summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-06-23 11:35:38 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-06-23 11:35:38 +0000
commit7c52c3f35cdbdff58443b994f2f33d13b4d81f57 (patch)
treee54a27979ea72ec41702bec2984c2eadac3b8862 /src
parent4ef45ba0404dac3773e83af995a5ec584b23d633 (diff)
downloadvyos-strongswan-7c52c3f35cdbdff58443b994f2f33d13b4d81f57.tar.gz
vyos-strongswan-7c52c3f35cdbdff58443b994f2f33d13b4d81f57.zip
Updated to new upstream version.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/Makefile.in31
-rw-r--r--src/_copyright/Makefile.am7
-rw-r--r--src/_copyright/Makefile.in31
-rw-r--r--src/_copyright/_copyright.83
-rw-r--r--src/_copyright/_copyright.c5
-rw-r--r--src/_updown/Makefile.am2
-rw-r--r--src/_updown/Makefile.in21
-rw-r--r--src/_updown/_updown.83
-rw-r--r--src/_updown/_updown.in21
-rw-r--r--src/_updown_espmark/Makefile.in19
-rw-r--r--src/_updown_espmark/_updown_espmark21
-rw-r--r--src/_updown_espmark/_updown_espmark.83
-rw-r--r--src/charon/Makefile.am30
-rw-r--r--src/charon/Makefile.in286
-rw-r--r--src/charon/bus/bus.c42
-rw-r--r--src/charon/bus/bus.h28
-rw-r--r--src/charon/bus/listeners/file_logger.c2
-rw-r--r--src/charon/bus/listeners/file_logger.h2
-rw-r--r--src/charon/bus/listeners/sys_logger.c2
-rw-r--r--src/charon/bus/listeners/sys_logger.h2
-rw-r--r--src/charon/config/attributes/attribute_handler.h58
-rw-r--r--src/charon/config/attributes/attribute_manager.c120
-rw-r--r--src/charon/config/attributes/attribute_manager.h74
-rw-r--r--src/charon/config/attributes/attribute_provider.h16
-rw-r--r--src/charon/config/auth_cfg.c768
-rw-r--r--src/charon/config/auth_cfg.h201
-rw-r--r--src/charon/config/backend.h18
-rw-r--r--src/charon/config/backend_manager.c314
-rw-r--r--src/charon/config/backend_manager.h32
-rw-r--r--src/charon/config/child_cfg.c2
-rw-r--r--src/charon/config/child_cfg.h2
-rw-r--r--src/charon/config/ike_cfg.c2
-rw-r--r--src/charon/config/ike_cfg.h2
-rw-r--r--src/charon/config/peer_cfg.c194
-rw-r--r--src/charon/config/peer_cfg.h78
-rw-r--r--src/charon/config/proposal.c251
-rw-r--r--src/charon/config/proposal.h23
-rw-r--r--src/charon/config/traffic_selector.c2
-rw-r--r--src/charon/config/traffic_selector.h2
-rw-r--r--src/charon/control/controller.c128
-rw-r--r--src/charon/control/controller.h34
-rw-r--r--src/charon/credentials/auth_info.c607
-rw-r--r--src/charon/credentials/auth_info.h198
-rw-r--r--src/charon/credentials/credential_manager.c176
-rw-r--r--src/charon/credentials/credential_manager.h18
-rw-r--r--src/charon/credentials/credential_set.h2
-rw-r--r--src/charon/credentials/sets/auth_cfg_wrapper.c (renamed from src/charon/credentials/sets/auth_info_wrapper.c)89
-rw-r--r--src/charon/credentials/sets/auth_cfg_wrapper.h (renamed from src/charon/credentials/sets/auth_info_wrapper.h)28
-rw-r--r--src/charon/credentials/sets/cert_cache.c2
-rw-r--r--src/charon/credentials/sets/cert_cache.h2
-rw-r--r--src/charon/credentials/sets/ocsp_response_wrapper.c2
-rw-r--r--src/charon/credentials/sets/ocsp_response_wrapper.h2
-rw-r--r--src/charon/daemon.c74
-rw-r--r--src/charon/daemon.h12
-rw-r--r--src/charon/encoding/generator.c444
-rw-r--r--src/charon/encoding/generator.h8
-rw-r--r--src/charon/encoding/message.c132
-rw-r--r--src/charon/encoding/message.h21
-rw-r--r--src/charon/encoding/parser.c479
-rw-r--r--src/charon/encoding/parser.h2
-rw-r--r--src/charon/encoding/payloads/auth_payload.c2
-rw-r--r--src/charon/encoding/payloads/auth_payload.h2
-rw-r--r--src/charon/encoding/payloads/cert_payload.c2
-rw-r--r--src/charon/encoding/payloads/cert_payload.h2
-rw-r--r--src/charon/encoding/payloads/certreq_payload.c2
-rw-r--r--src/charon/encoding/payloads/certreq_payload.h2
-rw-r--r--src/charon/encoding/payloads/configuration_attribute.c2
-rw-r--r--src/charon/encoding/payloads/configuration_attribute.h2
-rw-r--r--src/charon/encoding/payloads/cp_payload.c2
-rw-r--r--src/charon/encoding/payloads/cp_payload.h2
-rw-r--r--src/charon/encoding/payloads/delete_payload.c2
-rw-r--r--src/charon/encoding/payloads/delete_payload.h2
-rw-r--r--src/charon/encoding/payloads/eap_payload.c2
-rw-r--r--src/charon/encoding/payloads/eap_payload.h2
-rw-r--r--src/charon/encoding/payloads/encodings.c3
-rw-r--r--src/charon/encoding/payloads/encodings.h15
-rw-r--r--src/charon/encoding/payloads/encryption_payload.c2
-rw-r--r--src/charon/encoding/payloads/encryption_payload.h2
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.c2
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.h2
-rw-r--r--src/charon/encoding/payloads/id_payload.c2
-rw-r--r--src/charon/encoding/payloads/id_payload.h2
-rw-r--r--src/charon/encoding/payloads/ike_header.c2
-rw-r--r--src/charon/encoding/payloads/ike_header.h2
-rw-r--r--src/charon/encoding/payloads/ke_payload.c2
-rw-r--r--src/charon/encoding/payloads/ke_payload.h2
-rw-r--r--src/charon/encoding/payloads/nonce_payload.c2
-rw-r--r--src/charon/encoding/payloads/nonce_payload.h2
-rw-r--r--src/charon/encoding/payloads/notify_payload.c2
-rw-r--r--src/charon/encoding/payloads/notify_payload.h2
-rw-r--r--src/charon/encoding/payloads/payload.c2
-rw-r--r--src/charon/encoding/payloads/payload.h2
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.c2
-rw-r--r--src/charon/encoding/payloads/proposal_substructure.h2
-rw-r--r--src/charon/encoding/payloads/sa_payload.c2
-rw-r--r--src/charon/encoding/payloads/sa_payload.h2
-rw-r--r--src/charon/encoding/payloads/traffic_selector_substructure.c2
-rw-r--r--src/charon/encoding/payloads/traffic_selector_substructure.h2
-rw-r--r--src/charon/encoding/payloads/transform_attribute.c6
-rw-r--r--src/charon/encoding/payloads/transform_attribute.h2
-rw-r--r--src/charon/encoding/payloads/transform_substructure.c36
-rw-r--r--src/charon/encoding/payloads/transform_substructure.h2
-rw-r--r--src/charon/encoding/payloads/ts_payload.c2
-rw-r--r--src/charon/encoding/payloads/ts_payload.h2
-rw-r--r--src/charon/encoding/payloads/unknown_payload.c2
-rw-r--r--src/charon/encoding/payloads/unknown_payload.h2
-rw-r--r--src/charon/encoding/payloads/vendor_id_payload.c2
-rw-r--r--src/charon/encoding/payloads/vendor_id_payload.h2
-rw-r--r--src/charon/kernel/kernel_interface.c154
-rw-r--r--src/charon/kernel/kernel_interface.h12
-rw-r--r--src/charon/kernel/kernel_ipsec.c2
-rw-r--r--src/charon/kernel/kernel_ipsec.h17
-rw-r--r--src/charon/kernel/kernel_net.h2
-rw-r--r--src/charon/network/packet.c2
-rw-r--r--src/charon/network/packet.h2
-rw-r--r--src/charon/network/receiver.c100
-rw-r--r--src/charon/network/receiver.h2
-rw-r--r--src/charon/network/sender.c2
-rw-r--r--src/charon/network/sender.h2
-rw-r--r--src/charon/network/socket-raw.c4
-rw-r--r--src/charon/network/socket.c151
-rw-r--r--src/charon/network/socket.h2
-rw-r--r--src/charon/plugins/attr/Makefile.am9
-rw-r--r--src/charon/plugins/attr/Makefile.in507
-rw-r--r--src/charon/plugins/attr/attr_plugin.c63
-rw-r--r--src/charon/plugins/attr/attr_plugin.h (renamed from src/scepclient/rsakey.h)46
-rw-r--r--src/charon/plugins/attr/attr_provider.c154
-rw-r--r--src/charon/plugins/attr/attr_provider.h49
-rw-r--r--src/charon/plugins/eap_aka/Makefile.in17
-rw-r--r--src/charon/plugins/eap_aka/eap_aka.c6
-rw-r--r--src/charon/plugins/eap_aka/eap_aka.h2
-rw-r--r--src/charon/plugins/eap_aka/eap_aka_plugin.c2
-rw-r--r--src/charon/plugins/eap_aka/eap_aka_plugin.h2
-rw-r--r--src/charon/plugins/eap_gtc/Makefile.in17
-rw-r--r--src/charon/plugins/eap_gtc/eap_gtc.c4
-rw-r--r--src/charon/plugins/eap_gtc/eap_gtc.h2
-rw-r--r--src/charon/plugins/eap_gtc/eap_gtc_plugin.c2
-rw-r--r--src/charon/plugins/eap_gtc/eap_gtc_plugin.h2
-rw-r--r--src/charon/plugins/eap_identity/Makefile.in17
-rw-r--r--src/charon/plugins/eap_identity/eap_identity.c2
-rw-r--r--src/charon/plugins/eap_identity/eap_identity.h2
-rw-r--r--src/charon/plugins/eap_identity/eap_identity_plugin.c2
-rw-r--r--src/charon/plugins/eap_identity/eap_identity_plugin.h2
-rw-r--r--src/charon/plugins/eap_md5/Makefile.in17
-rw-r--r--src/charon/plugins/eap_md5/eap_md5.c4
-rw-r--r--src/charon/plugins/eap_md5/eap_md5.h2
-rw-r--r--src/charon/plugins/eap_md5/eap_md5_plugin.c2
-rw-r--r--src/charon/plugins/eap_md5/eap_md5_plugin.h2
-rw-r--r--src/charon/plugins/eap_mschapv2/Makefile.in17
-rw-r--r--src/charon/plugins/eap_mschapv2/eap_mschapv2.c98
-rw-r--r--src/charon/plugins/eap_mschapv2/eap_mschapv2.h2
-rw-r--r--src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.c2
-rw-r--r--src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.h2
-rw-r--r--src/charon/plugins/eap_radius/Makefile.in17
-rw-r--r--src/charon/plugins/eap_radius/eap_radius.c21
-rw-r--r--src/charon/plugins/eap_radius/eap_radius.h2
-rw-r--r--src/charon/plugins/eap_radius/eap_radius_plugin.c2
-rw-r--r--src/charon/plugins/eap_radius/eap_radius_plugin.h2
-rw-r--r--src/charon/plugins/eap_radius/radius_client.c2
-rw-r--r--src/charon/plugins/eap_radius/radius_client.h2
-rw-r--r--src/charon/plugins/eap_radius/radius_message.c2
-rw-r--r--src/charon/plugins/eap_radius/radius_message.h2
-rw-r--r--src/charon/plugins/eap_sim/Makefile.in17
-rw-r--r--src/charon/plugins/eap_sim/eap_sim.c6
-rw-r--r--src/charon/plugins/eap_sim/eap_sim_plugin.c2
-rw-r--r--src/charon/plugins/eap_sim/eap_sim_plugin.h2
-rw-r--r--src/charon/plugins/eap_sim_file/Makefile.in17
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_card.c8
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_card.h2
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_plugin.c2
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_plugin.h2
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_provider.c2
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_provider.h2
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c107
-rw-r--r--src/charon/plugins/eap_sim_file/eap_sim_file_triplets.h10
-rw-r--r--src/charon/plugins/kernel_klips/Makefile.in17
-rw-r--r--src/charon/plugins/kernel_klips/kernel_klips_ipsec.c11
-rw-r--r--src/charon/plugins/kernel_klips/kernel_klips_ipsec.h2
-rw-r--r--src/charon/plugins/kernel_klips/kernel_klips_plugin.c2
-rw-r--r--src/charon/plugins/kernel_klips/kernel_klips_plugin.h2
-rw-r--r--src/charon/plugins/kernel_netlink/Makefile.in17
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c53
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.h2
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_net.c30
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_net.h2
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_plugin.c2
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_plugin.h2
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_shared.c2
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_shared.h2
-rw-r--r--src/charon/plugins/kernel_pfkey/Makefile.in17
-rw-r--r--src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c209
-rw-r--r--src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h2
-rw-r--r--src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c2
-rw-r--r--src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.h2
-rw-r--r--src/charon/plugins/kernel_pfroute/Makefile.am10
-rw-r--r--src/charon/plugins/kernel_pfroute/Makefile.in510
-rw-r--r--src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c713
-rw-r--r--src/charon/plugins/kernel_pfroute/kernel_pfroute_net.h46
-rw-r--r--src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.c58
-rw-r--r--src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.h47
-rw-r--r--src/charon/plugins/load_tester/Makefile.in17
-rw-r--r--src/charon/plugins/load_tester/load_tester_config.c169
-rw-r--r--src/charon/plugins/load_tester/load_tester_config.h2
-rw-r--r--src/charon/plugins/load_tester/load_tester_creds.c2
-rw-r--r--src/charon/plugins/load_tester/load_tester_creds.h2
-rw-r--r--src/charon/plugins/load_tester/load_tester_diffie_hellman.c2
-rw-r--r--src/charon/plugins/load_tester/load_tester_diffie_hellman.h2
-rw-r--r--src/charon/plugins/load_tester/load_tester_ipsec.c9
-rw-r--r--src/charon/plugins/load_tester/load_tester_ipsec.h2
-rw-r--r--src/charon/plugins/load_tester/load_tester_listener.c2
-rw-r--r--src/charon/plugins/load_tester/load_tester_listener.h2
-rw-r--r--src/charon/plugins/load_tester/load_tester_plugin.c2
-rw-r--r--src/charon/plugins/load_tester/load_tester_plugin.h2
-rw-r--r--src/charon/plugins/medcli/Makefile.in17
-rw-r--r--src/charon/plugins/medcli/medcli_config.c46
-rw-r--r--src/charon/plugins/medcli/medcli_config.h2
-rw-r--r--src/charon/plugins/medcli/medcli_creds.c4
-rw-r--r--src/charon/plugins/medcli/medcli_creds.h2
-rw-r--r--src/charon/plugins/medcli/medcli_listener.c2
-rw-r--r--src/charon/plugins/medcli/medcli_listener.h2
-rw-r--r--src/charon/plugins/medcli/medcli_plugin.c2
-rw-r--r--src/charon/plugins/medcli/medcli_plugin.h2
-rw-r--r--src/charon/plugins/medsrv/Makefile.in17
-rw-r--r--src/charon/plugins/medsrv/medsrv_config.c14
-rw-r--r--src/charon/plugins/medsrv/medsrv_config.h2
-rw-r--r--src/charon/plugins/medsrv/medsrv_creds.c2
-rw-r--r--src/charon/plugins/medsrv/medsrv_creds.h2
-rw-r--r--src/charon/plugins/medsrv/medsrv_plugin.c2
-rw-r--r--src/charon/plugins/medsrv/medsrv_plugin.h2
-rw-r--r--src/charon/plugins/nm/Makefile.am5
-rw-r--r--src/charon/plugins/nm/Makefile.in25
-rw-r--r--src/charon/plugins/nm/nm_creds.c6
-rw-r--r--src/charon/plugins/nm/nm_creds.h3
-rw-r--r--src/charon/plugins/nm/nm_handler.c148
-rw-r--r--src/charon/plugins/nm/nm_handler.h62
-rw-r--r--src/charon/plugins/nm/nm_plugin.c24
-rw-r--r--src/charon/plugins/nm/nm_plugin.h2
-rw-r--r--src/charon/plugins/nm/nm_service.c97
-rw-r--r--src/charon/plugins/nm/nm_service.h8
-rw-r--r--src/charon/plugins/resolv_conf/Makefile.am13
-rw-r--r--src/charon/plugins/resolv_conf/Makefile.in513
-rw-r--r--src/charon/plugins/resolv_conf/resolv_conf_handler.c192
-rw-r--r--src/charon/plugins/resolv_conf/resolv_conf_handler.h49
-rw-r--r--src/charon/plugins/resolv_conf/resolv_conf_plugin.c64
-rw-r--r--src/charon/plugins/resolv_conf/resolv_conf_plugin.h47
-rw-r--r--src/charon/plugins/smp/Makefile.in17
-rw-r--r--src/charon/plugins/smp/smp.c13
-rw-r--r--src/charon/plugins/smp/smp.h2
-rw-r--r--src/charon/plugins/sql/Makefile.in17
-rw-r--r--src/charon/plugins/sql/pool.c10
-rw-r--r--src/charon/plugins/sql/sql_attribute.c7
-rw-r--r--src/charon/plugins/sql/sql_attribute.h2
-rw-r--r--src/charon/plugins/sql/sql_config.c20
-rw-r--r--src/charon/plugins/sql/sql_config.h2
-rw-r--r--src/charon/plugins/sql/sql_cred.c2
-rw-r--r--src/charon/plugins/sql/sql_cred.h2
-rw-r--r--src/charon/plugins/sql/sql_logger.c2
-rw-r--r--src/charon/plugins/sql/sql_logger.h2
-rw-r--r--src/charon/plugins/sql/sql_plugin.c2
-rw-r--r--src/charon/plugins/sql/sql_plugin.h2
-rw-r--r--src/charon/plugins/stroke/Makefile.am5
-rw-r--r--src/charon/plugins/stroke/Makefile.in23
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.c22
-rw-r--r--src/charon/plugins/stroke/stroke_attribute.h2
-rw-r--r--src/charon/plugins/stroke/stroke_ca.c8
-rw-r--r--src/charon/plugins/stroke/stroke_ca.h2
-rw-r--r--src/charon/plugins/stroke/stroke_config.c732
-rw-r--r--src/charon/plugins/stroke/stroke_config.h2
-rw-r--r--src/charon/plugins/stroke/stroke_control.c203
-rw-r--r--src/charon/plugins/stroke/stroke_control.h15
-rw-r--r--src/charon/plugins/stroke/stroke_cred.c81
-rw-r--r--src/charon/plugins/stroke/stroke_cred.h2
-rw-r--r--src/charon/plugins/stroke/stroke_list.c335
-rw-r--r--src/charon/plugins/stroke/stroke_list.h2
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.c2
-rw-r--r--src/charon/plugins/stroke/stroke_plugin.h2
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.c2
-rw-r--r--src/charon/plugins/stroke/stroke_shared_key.h2
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c48
-rw-r--r--src/charon/plugins/stroke/stroke_socket.h2
-rw-r--r--src/charon/plugins/uci/Makefile.in17
-rw-r--r--src/charon/plugins/uci/uci_config.c43
-rw-r--r--src/charon/plugins/uci/uci_config.h2
-rw-r--r--src/charon/plugins/uci/uci_control.c47
-rw-r--r--src/charon/plugins/uci/uci_control.h2
-rw-r--r--src/charon/plugins/uci/uci_creds.c10
-rw-r--r--src/charon/plugins/uci/uci_creds.h2
-rw-r--r--src/charon/plugins/uci/uci_parser.c2
-rw-r--r--src/charon/plugins/uci/uci_parser.h2
-rw-r--r--src/charon/plugins/uci/uci_plugin.c2
-rw-r--r--src/charon/plugins/uci/uci_plugin.h2
-rw-r--r--src/charon/plugins/unit_tester/Makefile.am4
-rw-r--r--src/charon/plugins/unit_tester/Makefile.in57
-rw-r--r--src/charon/plugins/unit_tester/tests.h9
-rw-r--r--src/charon/plugins/unit_tester/tests/test_aes.c467
-rw-r--r--src/charon/plugins/unit_tester/tests/test_auth_info.c29
-rw-r--r--src/charon/plugins/unit_tester/tests/test_fips_prf.c64
-rw-r--r--src/charon/plugins/unit_tester/tests/test_id.c69
-rw-r--r--src/charon/plugins/unit_tester/tests/test_med_db.c2
-rw-r--r--src/charon/plugins/unit_tester/tests/test_pool.c17
-rw-r--r--src/charon/plugins/unit_tester/tests/test_rng.c221
-rw-r--r--src/charon/plugins/unit_tester/tests/test_rsa_gen.c20
-rw-r--r--src/charon/plugins/unit_tester/unit_tester.c2
-rw-r--r--src/charon/plugins/unit_tester/unit_tester.h2
-rw-r--r--src/charon/plugins/updown/Makefile.in17
-rw-r--r--src/charon/plugins/updown/updown_listener.c6
-rw-r--r--src/charon/plugins/updown/updown_listener.h2
-rw-r--r--src/charon/plugins/updown/updown_plugin.c2
-rw-r--r--src/charon/plugins/updown/updown_plugin.h2
-rw-r--r--src/charon/processing/jobs/acquire_job.c31
-rw-r--r--src/charon/processing/jobs/acquire_job.h6
-rw-r--r--src/charon/processing/jobs/callback_job.c2
-rw-r--r--src/charon/processing/jobs/callback_job.h2
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.c2
-rw-r--r--src/charon/processing/jobs/delete_child_sa_job.h2
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.c2
-rw-r--r--src/charon/processing/jobs/delete_ike_sa_job.h2
-rw-r--r--src/charon/processing/jobs/initiate_mediation_job.c18
-rw-r--r--src/charon/processing/jobs/initiate_mediation_job.h2
-rw-r--r--src/charon/processing/jobs/job.h2
-rw-r--r--src/charon/processing/jobs/mediation_job.c10
-rw-r--r--src/charon/processing/jobs/mediation_job.h2
-rw-r--r--src/charon/processing/jobs/migrate_job.c2
-rw-r--r--src/charon/processing/jobs/migrate_job.h2
-rw-r--r--src/charon/processing/jobs/process_message_job.c2
-rw-r--r--src/charon/processing/jobs/process_message_job.h2
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.c2
-rw-r--r--src/charon/processing/jobs/rekey_child_sa_job.h2
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.c2
-rw-r--r--src/charon/processing/jobs/rekey_ike_sa_job.h2
-rw-r--r--src/charon/processing/jobs/retransmit_job.c2
-rw-r--r--src/charon/processing/jobs/retransmit_job.h2
-rw-r--r--src/charon/processing/jobs/roam_job.c2
-rw-r--r--src/charon/processing/jobs/roam_job.h2
-rw-r--r--src/charon/processing/jobs/send_dpd_job.c2
-rw-r--r--src/charon/processing/jobs/send_dpd_job.h2
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.c2
-rw-r--r--src/charon/processing/jobs/send_keepalive_job.h2
-rw-r--r--src/charon/processing/jobs/update_sa_job.c2
-rw-r--r--src/charon/processing/jobs/update_sa_job.h2
-rw-r--r--src/charon/processing/processor.c2
-rw-r--r--src/charon/processing/processor.h2
-rw-r--r--src/charon/processing/scheduler.c122
-rw-r--r--src/charon/processing/scheduler.h84
-rw-r--r--src/charon/sa/authenticators/authenticator.c49
-rw-r--r--src/charon/sa/authenticators/authenticator.h89
-rw-r--r--src/charon/sa/authenticators/eap/eap_manager.c22
-rw-r--r--src/charon/sa/authenticators/eap/eap_manager.h2
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.c35
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.h11
-rw-r--r--src/charon/sa/authenticators/eap/sim_manager.c2
-rw-r--r--src/charon/sa/authenticators/eap/sim_manager.h4
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.c786
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.h113
-rw-r--r--src/charon/sa/authenticators/psk_authenticator.c147
-rw-r--r--src/charon/sa/authenticators/psk_authenticator.h30
-rw-r--r--src/charon/sa/authenticators/pubkey_authenticator.c229
-rw-r--r--src/charon/sa/authenticators/pubkey_authenticator.h30
-rw-r--r--src/charon/sa/child_sa.c45
-rw-r--r--src/charon/sa/child_sa.h2
-rw-r--r--src/charon/sa/connect_manager.c24
-rw-r--r--src/charon/sa/connect_manager.h2
-rw-r--r--src/charon/sa/ike_sa.c559
-rw-r--r--src/charon/sa/ike_sa.h96
-rw-r--r--src/charon/sa/ike_sa_id.c2
-rw-r--r--src/charon/sa/ike_sa_id.h2
-rw-r--r--src/charon/sa/ike_sa_manager.c127
-rw-r--r--src/charon/sa/ike_sa_manager.h5
-rw-r--r--src/charon/sa/keymat.c17
-rw-r--r--src/charon/sa/keymat.h2
-rw-r--r--src/charon/sa/mediation_manager.c10
-rw-r--r--src/charon/sa/mediation_manager.h2
-rw-r--r--src/charon/sa/task_manager.c265
-rw-r--r--src/charon/sa/task_manager.h2
-rw-r--r--src/charon/sa/tasks/child_create.c132
-rw-r--r--src/charon/sa/tasks/child_create.h9
-rw-r--r--src/charon/sa/tasks/child_delete.c17
-rw-r--r--src/charon/sa/tasks/child_delete.h2
-rw-r--r--src/charon/sa/tasks/child_rekey.c26
-rw-r--r--src/charon/sa/tasks/child_rekey.h2
-rw-r--r--src/charon/sa/tasks/ike_auth.c1107
-rw-r--r--src/charon/sa/tasks/ike_auth.h2
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.c10
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.h2
-rw-r--r--src/charon/sa/tasks/ike_cert_post.c122
-rw-r--r--src/charon/sa/tasks/ike_cert_post.h2
-rw-r--r--src/charon/sa/tasks/ike_cert_pre.c302
-rw-r--r--src/charon/sa/tasks/ike_cert_pre.h2
-rw-r--r--src/charon/sa/tasks/ike_config.c310
-rw-r--r--src/charon/sa/tasks/ike_config.h2
-rw-r--r--src/charon/sa/tasks/ike_delete.c6
-rw-r--r--src/charon/sa/tasks/ike_delete.h2
-rw-r--r--src/charon/sa/tasks/ike_dpd.c2
-rw-r--r--src/charon/sa/tasks/ike_dpd.h2
-rw-r--r--src/charon/sa/tasks/ike_init.c43
-rw-r--r--src/charon/sa/tasks/ike_init.h2
-rw-r--r--src/charon/sa/tasks/ike_me.c16
-rw-r--r--src/charon/sa/tasks/ike_me.h2
-rw-r--r--src/charon/sa/tasks/ike_mobike.c20
-rw-r--r--src/charon/sa/tasks/ike_mobike.h2
-rw-r--r--src/charon/sa/tasks/ike_natd.c10
-rw-r--r--src/charon/sa/tasks/ike_natd.h2
-rw-r--r--src/charon/sa/tasks/ike_reauth.c6
-rw-r--r--src/charon/sa/tasks/ike_reauth.h2
-rw-r--r--src/charon/sa/tasks/ike_rekey.c45
-rw-r--r--src/charon/sa/tasks/ike_rekey.h2
-rw-r--r--src/charon/sa/tasks/task.c2
-rw-r--r--src/charon/sa/tasks/task.h2
-rw-r--r--src/charon/sa/trap_manager.c371
-rw-r--r--src/charon/sa/trap_manager.h81
-rw-r--r--src/dumm/Makefile.am17
-rw-r--r--src/dumm/Makefile.in69
-rw-r--r--src/dumm/bridge.h14
-rw-r--r--src/dumm/cowfs.c344
-rw-r--r--src/dumm/cowfs.h8
-rw-r--r--src/dumm/dumm.c83
-rw-r--r--src/dumm/dumm.h27
-rw-r--r--src/dumm/ext/dumm.c124
-rw-r--r--src/dumm/ext/extconf.rb21
-rw-r--r--src/dumm/ext/extconf.rb.in19
-rw-r--r--src/dumm/ext/lib/dumm.rb45
-rw-r--r--src/dumm/ext/lib/dumm/guest.rb26
-rw-r--r--src/dumm/guest.c9
-rw-r--r--src/dumm/guest.h30
-rw-r--r--src/dumm/iface.h16
-rw-r--r--src/dumm/mconsole.c7
-rw-r--r--src/dumm/mconsole.h10
-rw-r--r--src/include/Makefile.in15
-rw-r--r--src/ipsec/Makefile.am2
-rw-r--r--src/ipsec/Makefile.in21
-rw-r--r--src/ipsec/ipsec.81
-rwxr-xr-xsrc/ipsec/ipsec.in13
-rw-r--r--src/libcrypto/Makefile.am11
-rw-r--r--src/libcrypto/Makefile.in741
-rw-r--r--src/libcrypto/include/cbc_generic.h110
-rw-r--r--src/libcrypto/include/hmac_generic.h60
-rw-r--r--src/libcrypto/include/md32_common.h607
-rw-r--r--src/libcrypto/libaes/aes.c1415
-rw-r--r--src/libcrypto/libaes/aes.h97
-rw-r--r--src/libcrypto/libaes/aes_cbc.c13
-rw-r--r--src/libcrypto/libaes/aes_cbc.h4
-rw-r--r--src/libcrypto/libaes/aes_xcbc_mac.c67
-rw-r--r--src/libcrypto/libaes/aes_xcbc_mac.h12
-rw-r--r--src/libcrypto/libdes/cbc_enc.c135
-rw-r--r--src/libcrypto/libdes/des.h308
-rw-r--r--src/libcrypto/libdes/des_enc.c502
-rw-r--r--src/libcrypto/libdes/des_locl.h515
-rw-r--r--src/libcrypto/libdes/des_ver.h60
-rw-r--r--src/libcrypto/libdes/destest.c871
-rw-r--r--src/libcrypto/libdes/ecb_enc.c128
-rw-r--r--src/libcrypto/libdes/fcrypt.c152
-rw-r--r--src/libcrypto/libdes/podd.h75
-rw-r--r--src/libcrypto/libdes/set_key.c246
-rw-r--r--src/libcrypto/libdes/sk.h204
-rw-r--r--src/libcrypto/libdes/spr.h204
-rw-r--r--src/libcrypto/libserpent/serpent.c995
-rw-r--r--src/libcrypto/libserpent/serpent.h17
-rw-r--r--src/libcrypto/libserpent/serpent_cbc.c8
-rw-r--r--src/libcrypto/libserpent/serpent_cbc.h3
-rw-r--r--src/libcrypto/libsha2/hmac_sha2.c32
-rw-r--r--src/libcrypto/libsha2/hmac_sha2.h17
-rw-r--r--src/libcrypto/libsha2/sha2.c437
-rw-r--r--src/libcrypto/libsha2/sha2.h52
-rw-r--r--src/libcrypto/libtwofish/twofish.c861
-rw-r--r--src/libcrypto/libtwofish/twofish.h20
-rw-r--r--src/libcrypto/libtwofish/twofish_cbc.c8
-rw-r--r--src/libcrypto/libtwofish/twofish_cbc.h3
-rw-r--r--src/libfast/Makefile.in17
-rw-r--r--src/libfast/context.h2
-rw-r--r--src/libfast/controller.h2
-rw-r--r--src/libfast/dispatcher.c2
-rw-r--r--src/libfast/dispatcher.h2
-rw-r--r--src/libfast/filter.h2
-rw-r--r--src/libfast/request.c2
-rw-r--r--src/libfast/request.h2
-rw-r--r--src/libfast/session.c2
-rw-r--r--src/libfast/session.h2
-rw-r--r--src/libfreeswan/Makefile.am22
-rw-r--r--src/libfreeswan/Makefile.in62
-rw-r--r--src/libfreeswan/addrtoa.c2
-rw-r--r--src/libfreeswan/addrtot.c4
-rw-r--r--src/libfreeswan/addrtypeof.c4
-rw-r--r--src/libfreeswan/anyaddr.31
-rw-r--r--src/libfreeswan/anyaddr.c4
-rw-r--r--src/libfreeswan/atoaddr.31
-rw-r--r--src/libfreeswan/atoaddr.c2
-rw-r--r--src/libfreeswan/atoasr.31
-rw-r--r--src/libfreeswan/atoasr.c2
-rw-r--r--src/libfreeswan/atosa.31
-rw-r--r--src/libfreeswan/atosa.c2
-rw-r--r--src/libfreeswan/atosubnet.c2
-rw-r--r--src/libfreeswan/atoul.31
-rw-r--r--src/libfreeswan/atoul.c2
-rw-r--r--src/libfreeswan/copyright.c4
-rw-r--r--src/libfreeswan/datatot.c2
-rw-r--r--src/libfreeswan/freeswan.h78
-rw-r--r--src/libfreeswan/goodmask.31
-rw-r--r--src/libfreeswan/goodmask.c2
-rw-r--r--src/libfreeswan/initaddr.31
-rw-r--r--src/libfreeswan/initaddr.c4
-rw-r--r--src/libfreeswan/initsaid.c2
-rw-r--r--src/libfreeswan/initsubnet.31
-rw-r--r--src/libfreeswan/initsubnet.c2
-rw-r--r--src/libfreeswan/internal.h35
-rw-r--r--src/libfreeswan/ipcomp.h61
-rw-r--r--src/libfreeswan/ipsec_ah.h111
-rw-r--r--src/libfreeswan/ipsec_alg.h254
-rw-r--r--src/libfreeswan/ipsec_encap.h55
-rw-r--r--src/libfreeswan/ipsec_eroute.h82
-rw-r--r--src/libfreeswan/ipsec_errs.h32
-rw-r--r--src/libfreeswan/ipsec_esp.h80
-rw-r--r--src/libfreeswan/ipsec_kversion.h191
-rw-r--r--src/libfreeswan/ipsec_life.h90
-rw-r--r--src/libfreeswan/ipsec_md5h.h83
-rw-r--r--src/libfreeswan/ipsec_param.h172
-rw-r--r--src/libfreeswan/ipsec_policy.h233
-rw-r--r--src/libfreeswan/ipsec_proto.h111
-rw-r--r--src/libfreeswan/ipsec_radij.h63
-rw-r--r--src/libfreeswan/ipsec_rcv.h72
-rw-r--r--src/libfreeswan/ipsec_sa.h252
-rw-r--r--src/libfreeswan/ipsec_sha1.h32
-rw-r--r--src/libfreeswan/ipsec_stats.h38
-rw-r--r--src/libfreeswan/ipsec_tunnel.h128
-rw-r--r--src/libfreeswan/ipsec_xform.h84
-rw-r--r--src/libfreeswan/ipsec_xmit.h140
-rw-r--r--src/libfreeswan/keyblobtoid.31
-rw-r--r--src/libfreeswan/keyblobtoid.c2
-rw-r--r--src/libfreeswan/optionsfrom.3182
-rw-r--r--src/libfreeswan/optionsfrom.c301
-rw-r--r--src/libfreeswan/pfkey.h121
-rw-r--r--src/libfreeswan/pfkey_v2_build.c71
-rw-r--r--src/libfreeswan/pfkey_v2_debug.c28
-rw-r--r--src/libfreeswan/pfkey_v2_ext_bits.c36
-rw-r--r--src/libfreeswan/pfkey_v2_parse.c83
-rw-r--r--src/libfreeswan/pfkeyv2.h4
-rw-r--r--src/libfreeswan/portof.31
-rw-r--r--src/libfreeswan/portof.c4
-rw-r--r--src/libfreeswan/prng.31
-rw-r--r--src/libfreeswan/prng.c2
-rw-r--r--src/libfreeswan/radij.h201
-rw-r--r--src/libfreeswan/rangetoa.c2
-rw-r--r--src/libfreeswan/rangetosubnet.31
-rw-r--r--src/libfreeswan/rangetosubnet.c2
-rw-r--r--src/libfreeswan/sameaddr.31
-rw-r--r--src/libfreeswan/sameaddr.c2
-rw-r--r--src/libfreeswan/satoa.c2
-rw-r--r--src/libfreeswan/satot.c4
-rw-r--r--src/libfreeswan/subnetof.31
-rw-r--r--src/libfreeswan/subnetof.c2
-rw-r--r--src/libfreeswan/subnettoa.c2
-rw-r--r--src/libfreeswan/subnettot.c2
-rw-r--r--src/libfreeswan/subnettypeof.c2
-rw-r--r--src/libfreeswan/ttoaddr.31
-rw-r--r--src/libfreeswan/ttoaddr.c4
-rw-r--r--src/libfreeswan/ttodata.31
-rw-r--r--src/libfreeswan/ttodata.c2
-rw-r--r--src/libfreeswan/ttoprotoport.c4
-rw-r--r--src/libfreeswan/ttosa.31
-rw-r--r--src/libfreeswan/ttosa.c4
-rw-r--r--src/libfreeswan/ttosubnet.c4
-rw-r--r--src/libfreeswan/ttoul.31
-rw-r--r--src/libfreeswan/ttoul.c2
-rw-r--r--src/libfreeswan/ultoa.c2
-rw-r--r--src/libfreeswan/ultot.c2
-rw-r--r--src/libfreeswan/version.344
-rw-r--r--src/libfreeswan/version.c43
-rw-r--r--src/libstrongswan/Makefile.am57
-rw-r--r--src/libstrongswan/Makefile.in284
-rw-r--r--src/libstrongswan/asn1/asn1.h24
-rw-r--r--src/libstrongswan/asn1/asn1_parser.c4
-rw-r--r--src/libstrongswan/asn1/asn1_parser.h6
-rw-r--r--src/libstrongswan/asn1/oid.c562
-rw-r--r--src/libstrongswan/asn1/oid.h264
-rw-r--r--src/libstrongswan/asn1/oid.pl7
-rw-r--r--src/libstrongswan/asn1/oid.txt72
-rwxr-xr-xsrc/libstrongswan/asn1/pem.c49
-rwxr-xr-xsrc/libstrongswan/asn1/pem.h8
-rw-r--r--src/libstrongswan/chunk.c14
-rw-r--r--src/libstrongswan/chunk.h19
-rw-r--r--src/libstrongswan/credentials/builder.c2
-rw-r--r--src/libstrongswan/credentials/builder.h10
-rw-r--r--src/libstrongswan/credentials/certificates/ac.h2
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.c14
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.h12
-rw-r--r--src/libstrongswan/credentials/certificates/crl.c2
-rw-r--r--src/libstrongswan/credentials/certificates/crl.h2
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_request.h2
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_response.c2
-rw-r--r--src/libstrongswan/credentials/certificates/ocsp_response.h2
-rw-r--r--src/libstrongswan/credentials/certificates/x509.c2
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h2
-rw-r--r--src/libstrongswan/credentials/credential_factory.c4
-rw-r--r--src/libstrongswan/credentials/credential_factory.h3
-rw-r--r--src/libstrongswan/credentials/keys/private_key.c2
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h10
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c45
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h66
-rw-r--r--src/libstrongswan/credentials/keys/shared_key.c2
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c147
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.h74
-rw-r--r--src/libstrongswan/crypto/crypto_factory.c178
-rw-r--r--src/libstrongswan/crypto/crypto_factory.h15
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c629
-rw-r--r--src/libstrongswan/crypto/crypto_tester.h205
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c28
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h2
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c8
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h18
-rw-r--r--src/libstrongswan/crypto/pkcs9.c2
-rw-r--r--src/libstrongswan/crypto/pkcs9.h2
-rw-r--r--src/libstrongswan/crypto/prf_plus.c2
-rw-r--r--src/libstrongswan/crypto/prf_plus.h2
-rw-r--r--src/libstrongswan/crypto/prfs/prf.c11
-rw-r--r--src/libstrongswan/crypto/prfs/prf.h20
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.c270
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.h (renamed from src/libfreeswan/ipsec_ipe4.h)35
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.txt118
-rw-r--r--src/libstrongswan/crypto/rngs/rng.c6
-rw-r--r--src/libstrongswan/crypto/rngs/rng.h10
-rw-r--r--src/libstrongswan/crypto/signers/signer.c21
-rw-r--r--src/libstrongswan/crypto/signers/signer.h35
-rw-r--r--src/libstrongswan/crypto/transform.c29
-rw-r--r--src/libstrongswan/crypto/transform.h47
-rw-r--r--src/libstrongswan/database/database_factory.c2
-rw-r--r--src/libstrongswan/debug.c2
-rw-r--r--src/libstrongswan/debug.h2
-rw-r--r--src/libstrongswan/enum.c2
-rw-r--r--src/libstrongswan/enum.h2
-rw-r--r--src/libstrongswan/fetcher/fetcher.h12
-rw-r--r--src/libstrongswan/fetcher/fetcher_manager.c6
-rw-r--r--src/libstrongswan/fips/Makefile.in17
-rw-r--r--src/libstrongswan/fips/fips.c2
-rw-r--r--src/libstrongswan/fips/fips.h2
-rw-r--r--src/libstrongswan/fips/fips_canister_end.c2
-rw-r--r--src/libstrongswan/fips/fips_canister_start.c2
-rw-r--r--src/libstrongswan/fips/fips_signer.c2
-rw-r--r--src/libstrongswan/library.c8
-rw-r--r--src/libstrongswan/library.h4
-rw-r--r--src/libstrongswan/pgp/pgp.c93
-rw-r--r--src/libstrongswan/pgp/pgp.h115
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/aes/aes_crypter.c4
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.c2
-rw-r--r--src/libstrongswan/plugins/agent/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/agent/agent_plugin.c2
-rw-r--r--src/libstrongswan/plugins/agent/agent_private_key.c16
-rw-r--r--src/libstrongswan/plugins/blowfish/Makefile.am12
-rw-r--r--src/libstrongswan/plugins/blowfish/Makefile.in513
-rw-r--r--src/libstrongswan/plugins/blowfish/bf_enc.c (renamed from src/libcrypto/libblowfish/bf_enc.c)38
-rw-r--r--src/libstrongswan/plugins/blowfish/bf_locl.h (renamed from src/libcrypto/libblowfish/bf_locl.h)0
-rw-r--r--src/libstrongswan/plugins/blowfish/bf_pi.h (renamed from src/libcrypto/libblowfish/bf_pi.h)0
-rw-r--r--src/libstrongswan/plugins/blowfish/bf_skey.c (renamed from src/libcrypto/libblowfish/bf_skey.c)0
-rw-r--r--src/libstrongswan/plugins/blowfish/blowfish.h (renamed from src/libcrypto/libblowfish/blowfish.h)0
-rw-r--r--src/libstrongswan/plugins/blowfish/blowfish_crypter.c (renamed from src/libcrypto/libdes/fcrypt_b.c)217
-rw-r--r--src/libstrongswan/plugins/blowfish/blowfish_crypter.h50
-rw-r--r--src/libstrongswan/plugins/blowfish/blowfish_plugin.c59
-rw-r--r--src/libstrongswan/plugins/blowfish/blowfish_plugin.h48
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.c66
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.c2
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.c4
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.c2
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c2
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c2
-rw-r--r--src/libstrongswan/plugins/gcrypt/Makefile.am17
-rw-r--r--src/libstrongswan/plugins/gcrypt/Makefile.in522
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c252
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h49
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_dh.c564
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_dh.h48
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c151
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_hasher.h47
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c212
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_plugin.h47
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rng.c103
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rng.h47
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c734
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.h47
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c512
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.h47
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c6
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.c2
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c341
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c350
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h2
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.c2
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.c4
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_prf.c2
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_signer.c6
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_fetcher.c2
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.c2
-rw-r--r--src/libstrongswan/plugins/md4/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/md4/md4_hasher.c2
-rw-r--r--src/libstrongswan/plugins/md4/md4_plugin.c2
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.c2
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.c2
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.c2
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.c2
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c10
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c101
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c51
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c167
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c127
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.h2
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_aes_crypter.c2
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.c4
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_rng.c4
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_rng.h2
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c2
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c2
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c2
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.h2
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.c2
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.c4
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_public_key.h2
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.c4
-rw-r--r--src/libstrongswan/plugins/random/random_rng.c4
-rw-r--r--src/libstrongswan/plugins/random/random_rng.h2
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.c2
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.c2
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_prf.c2
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.c2
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.c2
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_database.c2
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.c2
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.am33
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in710
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors.h159
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/3des_cbc.c43
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/aes_cbc.c113
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/aes_xcbc.c129
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/blowfish.c46
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/camellia_cbc.c91
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/cast.c28
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/des.c65
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/fips_prf.c30
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/idea.c44
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/md2.c63
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/md4.c63
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/md5.c63
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/md5_hmac.c112
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/null.c (renamed from src/pluto/rnd.h)24
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/rc5.c44
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/rng.c236
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/serpent_cbc.c91
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c51
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/sha1_hmac.c146
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/sha2.c136
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/sha2_hmac.c353
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/twofish_cbc.c56
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c142
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors_plugin.h47
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/x509/ietf_attr_list.h2
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c33
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.h2
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c122
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.h2
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c34
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c3
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c38
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.c2
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in17
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.c2
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.c2
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_prf.c2
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_signer.c2
-rw-r--r--src/libstrongswan/printf_hook.c20
-rw-r--r--src/libstrongswan/printf_hook.h7
-rw-r--r--src/libstrongswan/settings.c19
-rw-r--r--src/libstrongswan/settings.h4
-rw-r--r--src/libstrongswan/utils.c19
-rw-r--r--src/libstrongswan/utils.h33
-rw-r--r--src/libstrongswan/utils/backtrace.c4
-rw-r--r--src/libstrongswan/utils/enumerator.c4
-rw-r--r--src/libstrongswan/utils/enumerator.h4
-rw-r--r--src/libstrongswan/utils/hashtable.c2
-rw-r--r--src/libstrongswan/utils/hashtable.h2
-rw-r--r--src/libstrongswan/utils/host.c51
-rw-r--r--src/libstrongswan/utils/identification.c396
-rw-r--r--src/libstrongswan/utils/identification.h89
-rw-r--r--src/libstrongswan/utils/iterator.h2
-rw-r--r--src/libstrongswan/utils/leak_detective.c7
-rw-r--r--src/libstrongswan/utils/lexparser.c2
-rw-r--r--src/libstrongswan/utils/lexparser.h2
-rw-r--r--src/libstrongswan/utils/linked_list.c2
-rw-r--r--src/libstrongswan/utils/linked_list.h3
-rw-r--r--src/libstrongswan/utils/mutex.c10
-rw-r--r--src/libstrongswan/utils/mutex.h2
-rw-r--r--src/libstrongswan/utils/optionsfrom.c2
-rw-r--r--src/libstrongswan/utils/optionsfrom.h2
-rw-r--r--src/manager/Makefile.in17
-rw-r--r--src/manager/controller/auth_controller.c2
-rw-r--r--src/manager/controller/auth_controller.h2
-rw-r--r--src/manager/controller/config_controller.c2
-rw-r--r--src/manager/controller/config_controller.h2
-rw-r--r--src/manager/controller/control_controller.c2
-rw-r--r--src/manager/controller/control_controller.h2
-rw-r--r--src/manager/controller/gateway_controller.c2
-rw-r--r--src/manager/controller/gateway_controller.h2
-rw-r--r--src/manager/controller/ikesa_controller.c2
-rw-r--r--src/manager/controller/ikesa_controller.h2
-rw-r--r--src/manager/gateway.c2
-rw-r--r--src/manager/gateway.h2
-rw-r--r--src/manager/main.c2
-rw-r--r--src/manager/manager.c2
-rw-r--r--src/manager/manager.h2
-rw-r--r--src/manager/storage.c2
-rw-r--r--src/manager/storage.h2
-rw-r--r--src/manager/xml.c4
-rw-r--r--src/manager/xml.h2
-rw-r--r--src/medsrv/Makefile.in17
-rwxr-xr-xsrc/medsrv/controller/peer_controller.c4
-rwxr-xr-xsrc/medsrv/controller/peer_controller.h2
-rwxr-xr-xsrc/medsrv/controller/user_controller.c2
-rwxr-xr-xsrc/medsrv/controller/user_controller.h2
-rwxr-xr-xsrc/medsrv/filter/auth_filter.c2
-rwxr-xr-xsrc/medsrv/filter/auth_filter.h2
-rw-r--r--src/medsrv/main.c2
-rw-r--r--src/medsrv/user.c2
-rw-r--r--src/medsrv/user.h2
-rw-r--r--src/openac/Makefile.in21
-rwxr-xr-xsrc/openac/openac.c25
-rw-r--r--src/pluto/Makefile.am52
-rw-r--r--src/pluto/Makefile.in239
-rw-r--r--src/pluto/TODO129
-rw-r--r--src/pluto/ac.c1575
-rw-r--r--src/pluto/ac.h56
-rw-r--r--src/pluto/adns.c726
-rw-r--r--src/pluto/adns.h56
-rw-r--r--src/pluto/alg/ike_alg_aes.c68
-rw-r--r--src/pluto/alg/ike_alg_blowfish.c52
-rw-r--r--src/pluto/alg/ike_alg_serpent.c70
-rw-r--r--src/pluto/alg/ike_alg_sha2.c634
-rw-r--r--src/pluto/alg/ike_alg_twofish.c85
-rw-r--r--src/pluto/alg/ike_alginit.c7
-rw-r--r--src/pluto/alg_info.c1539
-rw-r--r--src/pluto/alg_info.h69
-rw-r--r--src/pluto/asn1.c806
-rw-r--r--src/pluto/asn1.h141
-rw-r--r--src/pluto/ca.c923
-rw-r--r--src/pluto/ca.h42
-rw-r--r--src/pluto/certs.c374
-rw-r--r--src/pluto/certs.h63
-rw-r--r--src/pluto/connections.c6574
-rw-r--r--src/pluto/connections.h270
-rw-r--r--src/pluto/constants.c1071
-rw-r--r--src/pluto/constants.h1013
-rw-r--r--src/pluto/cookie.c68
-rw-r--r--src/pluto/cookie.h8
-rw-r--r--src/pluto/crl.c1197
-rw-r--r--src/pluto/crl.h34
-rw-r--r--src/pluto/crypto.c997
-rw-r--r--src/pluto/crypto.h91
-rw-r--r--src/pluto/db_ops.c541
-rw-r--r--src/pluto/db_ops.h36
-rw-r--r--src/pluto/defs.c346
-rw-r--r--src/pluto/defs.h97
-rw-r--r--src/pluto/demux.c3950
-rw-r--r--src/pluto/demux.h64
-rw-r--r--src/pluto/dnskey.c2609
-rw-r--r--src/pluto/dnskey.h70
-rw-r--r--src/pluto/dsa.c476
-rw-r--r--src/pluto/dsa.h32
-rw-r--r--src/pluto/elgamal.c613
-rw-r--r--src/pluto/elgamal.h35
-rw-r--r--src/pluto/fetch.c1293
-rw-r--r--src/pluto/fetch.h28
-rw-r--r--src/pluto/foodgroups.c606
-rw-r--r--src/pluto/foodgroups.h4
-rw-r--r--src/pluto/gcryptfix.c283
-rw-r--r--src/pluto/gcryptfix.h111
-rw-r--r--src/pluto/id.c672
-rw-r--r--src/pluto/id.h34
-rw-r--r--src/pluto/ike_alg.c775
-rw-r--r--src/pluto/ike_alg.h86
-rw-r--r--src/pluto/ipsec_doi.c8810
-rw-r--r--src/pluto/ipsec_doi.h80
-rw-r--r--src/pluto/kameipsec.h46
-rw-r--r--src/pluto/kernel.c4621
-rw-r--r--src/pluto/kernel.h204
-rw-r--r--src/pluto/kernel_alg.c1163
-rw-r--r--src/pluto/kernel_alg.h2
-rw-r--r--src/pluto/kernel_netlink.c1748
-rw-r--r--src/pluto/kernel_netlink.h2
-rw-r--r--src/pluto/kernel_noklips.c60
-rw-r--r--src/pluto/kernel_noklips.h2
-rw-r--r--src/pluto/kernel_pfkey.c1212
-rw-r--r--src/pluto/kernel_pfkey.h2
-rw-r--r--src/pluto/keys.c2249
-rw-r--r--src/pluto/keys.h79
-rw-r--r--src/pluto/lex.c268
-rw-r--r--src/pluto/lex.h20
-rw-r--r--src/pluto/log.c1115
-rw-r--r--src/pluto/log.h104
-rw-r--r--src/pluto/md2.c237
-rw-r--r--src/pluto/md2.h72
-rw-r--r--src/pluto/md5.c385
-rw-r--r--src/pluto/md5.h75
-rw-r--r--src/pluto/modecfg.c1773
-rw-r--r--src/pluto/modecfg.h2
-rw-r--r--src/pluto/mp_defs.c70
-rw-r--r--src/pluto/mp_defs.h36
-rw-r--r--src/pluto/nat_traversal.c1279
-rw-r--r--src/pluto/nat_traversal.h62
-rw-r--r--src/pluto/ocsp.c2396
-rw-r--r--src/pluto/ocsp.h64
-rw-r--r--src/pluto/packet.c1286
-rw-r--r--src/pluto/packet.h312
-rw-r--r--src/pluto/pem.c485
-rw-r--r--src/pluto/pem.h10
-rw-r--r--src/pluto/pgp.c647
-rw-r--r--src/pluto/pgpcert.c496
-rw-r--r--src/pluto/pgpcert.h (renamed from src/pluto/pgp.h)42
-rw-r--r--src/pluto/pkcs1.c676
-rw-r--r--src/pluto/pkcs1.h88
-rw-r--r--src/pluto/pkcs7.c1341
-rw-r--r--src/pluto/pkcs7.h32
-rw-r--r--src/pluto/plutomain.c1125
-rw-r--r--src/pluto/primegen.c593
-rw-r--r--src/pluto/rcv_whack.c1013
-rw-r--r--src/pluto/rcv_whack.h2
-rw-r--r--src/pluto/rnd.c250
-rw-r--r--src/pluto/server.c1434
-rw-r--r--src/pluto/server.h28
-rw-r--r--src/pluto/sha1.c193
-rw-r--r--src/pluto/sha1.h16
-rw-r--r--src/pluto/smallprime.c122
-rw-r--r--src/pluto/smartcard.c2746
-rw-r--r--src/pluto/smartcard.h56
-rw-r--r--src/pluto/spdb.c3779
-rw-r--r--src/pluto/spdb.h84
-rw-r--r--src/pluto/state.c1358
-rw-r--r--src/pluto/state.h276
-rw-r--r--src/pluto/timer.c875
-rw-r--r--src/pluto/timer.h16
-rw-r--r--src/pluto/vendor.c795
-rw-r--r--src/pluto/vendor.h254
-rw-r--r--src/pluto/virtual.c411
-rw-r--r--src/pluto/virtual.h6
-rw-r--r--src/pluto/x509.c3375
-rw-r--r--src/pluto/x509.h137
-rw-r--r--src/pluto/xauth.c74
-rw-r--r--src/pluto/xauth.h18
-rw-r--r--src/scepclient/Makefile.am55
-rw-r--r--src/scepclient/Makefile.in90
-rw-r--r--src/scepclient/loglite.c406
-rw-r--r--src/scepclient/pkcs10.c234
-rw-r--r--src/scepclient/pkcs10.h27
-rw-r--r--src/scepclient/rsakey.c349
-rw-r--r--src/scepclient/scep.c884
-rw-r--r--src/scepclient/scep.h46
-rw-r--r--src/scepclient/scepclient.88
-rw-r--r--src/scepclient/scepclient.c1753
-rw-r--r--src/starter/Makefile.am37
-rw-r--r--src/starter/Makefile.in57
-rw-r--r--src/starter/args.c985
-rw-r--r--src/starter/args.h8
-rw-r--r--src/starter/cmp.c90
-rw-r--r--src/starter/cmp.h2
-rw-r--r--src/starter/confread.c62
-rw-r--r--src/starter/confread.h324
-rw-r--r--src/starter/exec.c28
-rw-r--r--src/starter/exec.h2
-rw-r--r--src/starter/files.h12
-rw-r--r--src/starter/interfaces.c198
-rw-r--r--src/starter/interfaces.h14
-rw-r--r--src/starter/invokecharon.c317
-rw-r--r--src/starter/invokecharon.h4
-rw-r--r--src/starter/invokepluto.c466
-rw-r--r--src/starter/invokepluto.h4
-rw-r--r--src/starter/ipsec.conf.594
-rw-r--r--src/starter/keywords.c349
-rw-r--r--src/starter/keywords.h322
-rw-r--r--src/starter/keywords.txt12
-rw-r--r--src/starter/klips.c80
-rw-r--r--src/starter/klips.h2
-rw-r--r--src/starter/loglite.c294
-rw-r--r--src/starter/netkey.c84
-rw-r--r--src/starter/netkey.h2
-rw-r--r--src/starter/parser.h24
-rw-r--r--src/starter/parser.l216
-rw-r--r--src/starter/parser.y339
-rw-r--r--src/starter/starter.c1116
-rw-r--r--src/starter/starterstroke.c33
-rw-r--r--src/starter/starterstroke.h2
-rw-r--r--src/starter/starterwhack.c582
-rw-r--r--src/starter/starterwhack.h2
-rw-r--r--src/starter/y.tab.c323
-rw-r--r--src/starter/y.tab.h2
-rw-r--r--src/stroke/Makefile.am5
-rw-r--r--src/stroke/Makefile.in32
-rw-r--r--src/stroke/stroke.c14
-rw-r--r--src/stroke/stroke_keywords.c130
-rw-r--r--src/stroke/stroke_keywords.h3
-rw-r--r--src/stroke/stroke_keywords.txt3
-rw-r--r--src/stroke/stroke_msg.h11
-rw-r--r--src/strongswan.conf18
-rw-r--r--src/whack/Makefile.am11
-rw-r--r--src/whack/Makefile.in32
-rw-r--r--src/whack/whack.c3394
-rw-r--r--src/whack/whack.h478
1031 files changed, 68882 insertions, 76650 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 913099c23..09eb13fe3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,15 +1,15 @@
SUBDIRS = . include
-if USE_FILE_CONFIG
- SUBDIRS += libfreeswan starter ipsec _copyright
-endif
-
if USE_LIBSTRONGSWAN
SUBDIRS += libstrongswan
endif
+if USE_FILE_CONFIG
+ SUBDIRS += libfreeswan starter ipsec _copyright
+endif
+
if USE_PLUTO
- SUBDIRS += libcrypto pluto whack
+ SUBDIRS += pluto whack
endif
if USE_CHARON
@@ -25,7 +25,7 @@ if USE_UPDOWN
endif
if USE_TOOLS
- SUBDIRS += libcrypto openac scepclient
+ SUBDIRS += openac scepclient
endif
if USE_DUMM
diff --git a/src/Makefile.in b/src/Makefile.in
index 7dab32d21..26046e6a1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -31,13 +31,13 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@USE_FILE_CONFIG_TRUE@am__append_1 = libfreeswan starter ipsec _copyright
-@USE_LIBSTRONGSWAN_TRUE@am__append_2 = libstrongswan
-@USE_PLUTO_TRUE@am__append_3 = libcrypto pluto whack
+@USE_LIBSTRONGSWAN_TRUE@am__append_1 = libstrongswan
+@USE_FILE_CONFIG_TRUE@am__append_2 = libfreeswan starter ipsec _copyright
+@USE_PLUTO_TRUE@am__append_3 = pluto whack
@USE_CHARON_TRUE@am__append_4 = charon
@USE_STROKE_TRUE@am__append_5 = stroke
@USE_UPDOWN_TRUE@am__append_6 = _updown _updown_espmark
-@USE_TOOLS_TRUE@am__append_7 = libcrypto openac scepclient
+@USE_TOOLS_TRUE@am__append_7 = openac scepclient
@USE_DUMM_TRUE@am__append_8 = dumm
@USE_FAST_TRUE@am__append_9 = libfast
@USE_MANAGER_TRUE@am__append_10 = manager
@@ -63,9 +63,9 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = . include libfreeswan starter ipsec _copyright \
- libstrongswan libcrypto pluto whack charon stroke _updown \
- _updown_espmark openac scepclient dumm libfast manager medsrv
+DIST_SUBDIRS = . include libstrongswan libfreeswan starter ipsec \
+ _copyright pluto whack charon stroke _updown _updown_espmark \
+ openac scepclient dumm libfast manager medsrv
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -82,6 +82,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -104,6 +105,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -115,6 +119,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -128,6 +133,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -188,6 +195,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -199,6 +207,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -215,8 +224,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/_copyright/Makefile.am b/src/_copyright/Makefile.am
index 00d5fb2ff..33c4ffc23 100644
--- a/src/_copyright/Makefile.am
+++ b/src/_copyright/Makefile.am
@@ -2,5 +2,8 @@ ipsec_PROGRAMS = _copyright
_copyright_SOURCES = _copyright.c
dist_man8_MANS = _copyright.8
-INCLUDES = -I$(top_srcdir)/src/libfreeswan
-_copyright_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
+INCLUDES = \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/libstrongswan
+
+_copyright_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la
diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in
index c86e56bce..9f178fdfa 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -48,7 +48,8 @@ PROGRAMS = $(ipsec_PROGRAMS)
am__copyright_OBJECTS = _copyright.$(OBJEXT)
_copyright_OBJECTS = $(am__copyright_OBJECTS)
_copyright_DEPENDENCIES = \
- $(top_builddir)/src/libfreeswan/libfreeswan.a
+ $(top_builddir)/src/libfreeswan/libfreeswan.a \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -84,6 +85,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -106,6 +108,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -117,6 +122,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -130,6 +136,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -190,6 +198,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -201,14 +210,18 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
_copyright_SOURCES = _copyright.c
dist_man8_MANS = _copyright.8
-INCLUDES = -I$(top_srcdir)/src/libfreeswan
-_copyright_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
+INCLUDES = \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/libstrongswan
+
+_copyright_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la
all: all-am
.SUFFIXES:
@@ -217,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -319,8 +332,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -359,7 +372,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/_copyright/_copyright.8 b/src/_copyright/_copyright.8
index a0358750a..99386254b 100644
--- a/src/_copyright/_copyright.8
+++ b/src/_copyright/_copyright.8
@@ -1,7 +1,4 @@
.TH _COPYRIGHT 8 "25 Apr 2002"
-.\"
-.\" RCSID $Id: _copyright.8 3266 2007-10-08 19:57:37Z andreas $
-.\"
.SH NAME
ipsec _copyright \- prints FreeSWAN copyright
.SH DESCRIPTION
diff --git a/src/_copyright/_copyright.c b/src/_copyright/_copyright.c
index ff4294f81..5abefd4f1 100644
--- a/src/_copyright/_copyright.c
+++ b/src/_copyright/_copyright.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: _copyright.c 3266 2007-10-08 19:57:37Z andreas $
*/
#include <sys/types.h>
@@ -39,7 +37,6 @@ main(int argc, char *argv[])
int opt;
extern int optind;
int errflg = 0;
- const char *version = ipsec_version_code();
const char **notice = ipsec_copyright_notice();
const char **co;
@@ -50,7 +47,7 @@ main(int argc, char *argv[])
exit(0);
break;
case 'v': /* version */
- printf("%s %s\n", me, version);
+ printf("%s strongSwan "VERSION"\n", me);
exit(0);
break;
case '?':
diff --git a/src/_updown/Makefile.am b/src/_updown/Makefile.am
index 9fd592797..5fc04ab88 100644
--- a/src/_updown/Makefile.am
+++ b/src/_updown/Makefile.am
@@ -8,5 +8,5 @@ _updown : _updown.in
-e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:\@IPSEC_ROUTING_TABLE\@:$(IPSEC_ROUTING_TABLE):" \
-e "s:\@IPSEC_ROUTING_TABLE_PRIO\@:$(IPSEC_ROUTING_TABLE_PRIO):" \
- $< > $@
+ $(srcdir)/$@.in > $@
chmod +x $@
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index 059c56383..3db887ef0 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -65,6 +65,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -87,6 +88,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -98,6 +102,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -111,6 +116,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -171,6 +178,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -182,6 +190,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -197,8 +206,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -258,8 +267,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -434,7 +443,7 @@ _updown : _updown.in
-e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:\@IPSEC_ROUTING_TABLE\@:$(IPSEC_ROUTING_TABLE):" \
-e "s:\@IPSEC_ROUTING_TABLE_PRIO\@:$(IPSEC_ROUTING_TABLE_PRIO):" \
- $< > $@
+ $(srcdir)/$@.in > $@
chmod +x $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/_updown/_updown.8 b/src/_updown/_updown.8
index 0f7b17ba5..8c88e5fb8 100644
--- a/src/_updown/_updown.8
+++ b/src/_updown/_updown.8
@@ -1,7 +1,4 @@
.TH _UPDOWN 8 "27 Apr 2006"
-.\"
-.\" RCSID $Id: _updown.8 3268 2007-10-08 19:59:18Z andreas $
-.\"
.SH NAME
ipsec _updown \- route and firewall manipulation script
.SH SYNOPSIS
diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in
index d71317e60..838842d06 100644
--- a/src/_updown/_updown.in
+++ b/src/_updown/_updown.in
@@ -15,8 +15,6 @@
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
-#
-# RCSID $Id: _updown.in 4187 2008-07-18 10:04:40Z andreas $
# CAUTION: Installing a new version of strongSwan will install a new
# copy of this script, wiping out any custom changes you make. If
@@ -35,7 +33,7 @@
# 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­
+# for security gateway to security gateway communica-
# tions is IPv6, then a suffix of -v6 is added to the
# verb.
#
@@ -95,7 +93,7 @@
# is the CA which issued the cert of our peer.
#
# PLUTO_PEER_CLIENT
-# is the IP address / count of the peer's client sub­
+# 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).
@@ -207,15 +205,12 @@ doroute() {
if [ -z "$PLUTO_MY_SOURCEIP" ]
then
- if [ -f /etc/sysconfig/defaultsource ]
- then
- . /etc/sysconfig/defaultsource
- fi
-
- if [ -f /etc/conf.d/defaultsource ]
- then
- . /etc/conf.d/defaultsource
- fi
+ for dir in /etc/sysconfig /etc/conf.d; do
+ if [ -f "$dir/defaultsource" ]
+ then
+ . "$dir/defaultsource"
+ fi
+ done
if [ -n "$DEFAULTSOURCE" ]
then
diff --git a/src/_updown_espmark/Makefile.in b/src/_updown_espmark/Makefile.in
index 7838e94ac..2852b7e67 100644
--- a/src/_updown_espmark/Makefile.in
+++ b/src/_updown_espmark/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -65,6 +65,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -87,6 +88,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -98,6 +102,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -111,6 +116,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -171,6 +178,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -182,6 +190,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -195,8 +204,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -256,8 +265,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
diff --git a/src/_updown_espmark/_updown_espmark b/src/_updown_espmark/_updown_espmark
index fbaf30132..74de0722d 100644
--- a/src/_updown_espmark/_updown_espmark
+++ b/src/_updown_espmark/_updown_espmark
@@ -15,8 +15,6 @@
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
-#
-# RCSID $Id: _updown_espmark 4187 2008-07-18 10:04:40Z andreas $
@@ -38,7 +36,7 @@
# 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­
+# for security gateway to security gateway communica-
# tions is IPv6, then a suffix of -v6 is added to the
# verb.
#
@@ -95,7 +93,7 @@
# is the CA which issued the cert of our peer.
#
# PLUTO_PEER_CLIENT
-# is the IP address / count of the peer's client sub­
+# 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).
@@ -201,15 +199,12 @@ doroute() {
if [ -z "$PLUTO_MY_SOURCEIP" ]
then
- if [ -f /etc/sysconfig/defaultsource ]
- then
- . /etc/sysconfig/defaultsource
- fi
-
- if [ -f /etc/conf.d/defaultsource ]
- then
- . /etc/conf.d/defaultsource
- fi
+ for dir in /etc/sysconfig /etc/conf.d; do
+ if [ -f "$dir/defaultsource" ]
+ then
+ . "$dir/defaultsource"
+ fi
+ done
if [ -n "$DEFAULTSOURCE" ]
then
diff --git a/src/_updown_espmark/_updown_espmark.8 b/src/_updown_espmark/_updown_espmark.8
index 07db3b548..34383cb8e 100644
--- a/src/_updown_espmark/_updown_espmark.8
+++ b/src/_updown_espmark/_updown_espmark.8
@@ -1,7 +1,4 @@
.TH _UPDOWN_ESPMARK 8 "7 Apr 2005"
-.\"
-.\" RCSID $Id: _updown_espmark.8 3268 2007-10-08 19:59:18Z andreas $
-.\"
.SH NAME
ipsec _updown_espmark \- manages routes and firewall rules
.SH SYNOPSIS
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am
index 9da2b238a..3b5b9c068 100644
--- a/src/charon/Makefile.am
+++ b/src/charon/Makefile.am
@@ -9,8 +9,10 @@ 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 \
+config/auth_cfg.c config/auth_cfg.h \
config/traffic_selector.c config/traffic_selector.h \
config/attributes/attribute_provider.h \
+config/attributes/attribute_handler.h \
config/attributes/attribute_manager.c config/attributes/attribute_manager.h \
control/controller.c control/controller.h \
daemon.c daemon.h \
@@ -76,6 +78,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \
sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h \
sa/keymat.c sa/keymat.h \
+sa/trap_manager.c sa/trap_manager.h \
sa/tasks/child_create.c sa/tasks/child_create.h \
sa/tasks/child_delete.c sa/tasks/child_delete.h \
sa/tasks/child_rekey.c sa/tasks/child_rekey.h \
@@ -93,8 +96,7 @@ sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
sa/tasks/task.c sa/tasks/task.h \
credentials/credential_manager.c credentials/credential_manager.h \
-credentials/auth_info.c credentials/auth_info.h \
-credentials/sets/auth_info_wrapper.c credentials/sets/auth_info_wrapper.h \
+credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
credentials/credential_set.h
@@ -104,9 +106,8 @@ AM_CFLAGS = -rdynamic \
-DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
- -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
- -DRESOLV_CONF=\"${resolv_conf}\"
-charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\"
+charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm $(DLLIB)
# compile options
#################
@@ -131,10 +132,6 @@ if USE_INTEGRITY_TEST
AM_CFLAGS += -DINTEGRITY_TEST
endif
-if USE_SELF_TEST
- AM_CFLAGS += -DSELF_TEST
-endif
-
if USE_CAPABILITIES
charon_LDADD += -lcap
endif
@@ -156,6 +153,11 @@ if USE_KERNEL_PFKEY
PLUGINS += kernel-pfkey
endif
+if USE_KERNEL_PFROUTE
+ SUBDIRS += plugins/kernel_pfroute
+ PLUGINS += kernel-pfroute
+endif
+
if USE_KERNEL_KLIPS
SUBDIRS += plugins/kernel_klips
PLUGINS += kernel-klips
@@ -186,6 +188,11 @@ if USE_UPDOWN
PLUGINS += updown
endif
+if USE_ATTR
+ SUBDIRS += plugins/attr
+ PLUGINS += attr
+endif
+
if USE_EAP_IDENTITY
SUBDIRS += plugins/eap_identity
PLUGINS += eapidentity
@@ -241,6 +248,11 @@ if USE_NM
PLUGINS += nm
endif
+if USE_RESOLV_CONF
+ SUBDIRS += plugins/resolv_conf
+ PLUGINS += resolv-conf
+endif
+
if USE_UCI
SUBDIRS += plugins/uci
PLUGINS += uci
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index f74577c8c..77884d50e 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -48,50 +48,55 @@ ipsec_PROGRAMS = charon$(EXEEXT)
@USE_ME_TRUE@ sa/tasks/ike_me.c sa/tasks/ike_me.h
@USE_INTEGRITY_TEST_TRUE@am__append_4 = -DINTEGRITY_TEST
-@USE_SELF_TEST_TRUE@am__append_5 = -DSELF_TEST
-@USE_CAPABILITIES_TRUE@am__append_6 = -lcap
-@USE_LOAD_TESTS_TRUE@am__append_7 = plugins/load_tester
-@USE_LOAD_TESTS_TRUE@am__append_8 = load-tester
-@USE_KERNEL_PFKEY_TRUE@am__append_9 = plugins/kernel_pfkey
-@USE_KERNEL_PFKEY_TRUE@am__append_10 = kernel-pfkey
-@USE_KERNEL_KLIPS_TRUE@am__append_11 = plugins/kernel_klips
-@USE_KERNEL_KLIPS_TRUE@am__append_12 = kernel-klips
-@USE_KERNEL_NETLINK_TRUE@am__append_13 = plugins/kernel_netlink
-@USE_KERNEL_NETLINK_TRUE@am__append_14 = kernel-netlink
-@USE_STROKE_TRUE@am__append_15 = plugins/stroke
-@USE_STROKE_TRUE@am__append_16 = stroke
-@USE_SMP_TRUE@am__append_17 = plugins/smp
-@USE_SMP_TRUE@am__append_18 = smp
-@USE_SQL_TRUE@am__append_19 = plugins/sql
-@USE_SQL_TRUE@am__append_20 = sql
-@USE_UPDOWN_TRUE@am__append_21 = plugins/updown
-@USE_UPDOWN_TRUE@am__append_22 = updown
-@USE_EAP_IDENTITY_TRUE@am__append_23 = plugins/eap_identity
-@USE_EAP_IDENTITY_TRUE@am__append_24 = eapidentity
-@USE_EAP_SIM_TRUE@am__append_25 = plugins/eap_sim
-@USE_EAP_SIM_TRUE@am__append_26 = eapsim
-@USE_EAP_SIM_FILE_TRUE@am__append_27 = plugins/eap_sim_file
-@USE_EAP_SIM_FILE_TRUE@am__append_28 = eapsim-file
-@USE_EAP_MD5_TRUE@am__append_29 = plugins/eap_md5
-@USE_EAP_MD5_TRUE@am__append_30 = eapmd5
-@USE_EAP_GTC_TRUE@am__append_31 = plugins/eap_gtc
-@USE_EAP_GTC_TRUE@am__append_32 = eapgtc
-@USE_EAP_AKA_TRUE@am__append_33 = plugins/eap_aka
-@USE_EAP_AKA_TRUE@am__append_34 = eapaka
-@USE_EAP_MSCHAPV2_TRUE@am__append_35 = plugins/eap_mschapv2
-@USE_EAP_MSCHAPV2_TRUE@am__append_36 = eapmschapv2
-@USE_EAP_RADIUS_TRUE@am__append_37 = plugins/eap_radius
-@USE_EAP_RADIUS_TRUE@am__append_38 = eapradius
-@USE_MEDSRV_TRUE@am__append_39 = plugins/medsrv
-@USE_MEDSRV_TRUE@am__append_40 = medsrv
-@USE_MEDCLI_TRUE@am__append_41 = plugins/medcli
-@USE_MEDCLI_TRUE@am__append_42 = medcli
-@USE_NM_TRUE@am__append_43 = plugins/nm
-@USE_NM_TRUE@am__append_44 = nm
-@USE_UCI_TRUE@am__append_45 = plugins/uci
-@USE_UCI_TRUE@am__append_46 = uci
-@USE_UNIT_TESTS_TRUE@am__append_47 = plugins/unit_tester
-@USE_UNIT_TESTS_TRUE@am__append_48 = unit-tester
+@USE_CAPABILITIES_TRUE@am__append_5 = -lcap
+@USE_LOAD_TESTS_TRUE@am__append_6 = plugins/load_tester
+@USE_LOAD_TESTS_TRUE@am__append_7 = load-tester
+@USE_KERNEL_PFKEY_TRUE@am__append_8 = plugins/kernel_pfkey
+@USE_KERNEL_PFKEY_TRUE@am__append_9 = kernel-pfkey
+@USE_KERNEL_PFROUTE_TRUE@am__append_10 = plugins/kernel_pfroute
+@USE_KERNEL_PFROUTE_TRUE@am__append_11 = kernel-pfroute
+@USE_KERNEL_KLIPS_TRUE@am__append_12 = plugins/kernel_klips
+@USE_KERNEL_KLIPS_TRUE@am__append_13 = kernel-klips
+@USE_KERNEL_NETLINK_TRUE@am__append_14 = plugins/kernel_netlink
+@USE_KERNEL_NETLINK_TRUE@am__append_15 = kernel-netlink
+@USE_STROKE_TRUE@am__append_16 = plugins/stroke
+@USE_STROKE_TRUE@am__append_17 = stroke
+@USE_SMP_TRUE@am__append_18 = plugins/smp
+@USE_SMP_TRUE@am__append_19 = smp
+@USE_SQL_TRUE@am__append_20 = plugins/sql
+@USE_SQL_TRUE@am__append_21 = sql
+@USE_UPDOWN_TRUE@am__append_22 = plugins/updown
+@USE_UPDOWN_TRUE@am__append_23 = updown
+@USE_ATTR_TRUE@am__append_24 = plugins/attr
+@USE_ATTR_TRUE@am__append_25 = attr
+@USE_EAP_IDENTITY_TRUE@am__append_26 = plugins/eap_identity
+@USE_EAP_IDENTITY_TRUE@am__append_27 = eapidentity
+@USE_EAP_SIM_TRUE@am__append_28 = plugins/eap_sim
+@USE_EAP_SIM_TRUE@am__append_29 = eapsim
+@USE_EAP_SIM_FILE_TRUE@am__append_30 = plugins/eap_sim_file
+@USE_EAP_SIM_FILE_TRUE@am__append_31 = eapsim-file
+@USE_EAP_MD5_TRUE@am__append_32 = plugins/eap_md5
+@USE_EAP_MD5_TRUE@am__append_33 = eapmd5
+@USE_EAP_GTC_TRUE@am__append_34 = plugins/eap_gtc
+@USE_EAP_GTC_TRUE@am__append_35 = eapgtc
+@USE_EAP_AKA_TRUE@am__append_36 = plugins/eap_aka
+@USE_EAP_AKA_TRUE@am__append_37 = eapaka
+@USE_EAP_MSCHAPV2_TRUE@am__append_38 = plugins/eap_mschapv2
+@USE_EAP_MSCHAPV2_TRUE@am__append_39 = eapmschapv2
+@USE_EAP_RADIUS_TRUE@am__append_40 = plugins/eap_radius
+@USE_EAP_RADIUS_TRUE@am__append_41 = eapradius
+@USE_MEDSRV_TRUE@am__append_42 = plugins/medsrv
+@USE_MEDSRV_TRUE@am__append_43 = medsrv
+@USE_MEDCLI_TRUE@am__append_44 = plugins/medcli
+@USE_MEDCLI_TRUE@am__append_45 = medcli
+@USE_NM_TRUE@am__append_46 = plugins/nm
+@USE_NM_TRUE@am__append_47 = nm
+@USE_RESOLV_CONF_TRUE@am__append_48 = plugins/resolv_conf
+@USE_RESOLV_CONF_TRUE@am__append_49 = resolv-conf
+@USE_UCI_TRUE@am__append_50 = plugins/uci
+@USE_UCI_TRUE@am__append_51 = uci
+@USE_UNIT_TESTS_TRUE@am__append_52 = plugins/unit_tester
+@USE_UNIT_TESTS_TRUE@am__append_53 = unit-tester
subdir = src/charon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -110,8 +115,10 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.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 \
- config/traffic_selector.c config/traffic_selector.h \
+ config/auth_cfg.c config/auth_cfg.h config/traffic_selector.c \
+ config/traffic_selector.h \
config/attributes/attribute_provider.h \
+ config/attributes/attribute_handler.h \
config/attributes/attribute_manager.c \
config/attributes/attribute_manager.h control/controller.c \
control/controller.h daemon.c daemon.h encoding/generator.c \
@@ -199,10 +206,10 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \
- sa/tasks/child_create.c sa/tasks/child_create.h \
- sa/tasks/child_delete.c sa/tasks/child_delete.h \
- sa/tasks/child_rekey.c sa/tasks/child_rekey.h \
- sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
+ sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \
+ sa/tasks/child_create.h sa/tasks/child_delete.c \
+ sa/tasks/child_delete.h sa/tasks/child_rekey.c \
+ sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
sa/tasks/ike_config.c sa/tasks/ike_config.h \
@@ -214,9 +221,9 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
credentials/credential_manager.c \
- credentials/credential_manager.h credentials/auth_info.c \
- credentials/auth_info.h credentials/sets/auth_info_wrapper.c \
- credentials/sets/auth_info_wrapper.h \
+ credentials/credential_manager.h \
+ credentials/sets/auth_cfg_wrapper.c \
+ credentials/sets/auth_cfg_wrapper.h \
credentials/sets/ocsp_response_wrapper.c \
credentials/sets/ocsp_response_wrapper.h \
credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
@@ -238,15 +245,15 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
sys_logger.$(OBJEXT) backend_manager.$(OBJEXT) \
child_cfg.$(OBJEXT) ike_cfg.$(OBJEXT) peer_cfg.$(OBJEXT) \
- proposal.$(OBJEXT) traffic_selector.$(OBJEXT) \
- attribute_manager.$(OBJEXT) controller.$(OBJEXT) \
- daemon.$(OBJEXT) generator.$(OBJEXT) message.$(OBJEXT) \
- parser.$(OBJEXT) auth_payload.$(OBJEXT) cert_payload.$(OBJEXT) \
- certreq_payload.$(OBJEXT) configuration_attribute.$(OBJEXT) \
- cp_payload.$(OBJEXT) delete_payload.$(OBJEXT) \
- eap_payload.$(OBJEXT) encodings.$(OBJEXT) \
- encryption_payload.$(OBJEXT) id_payload.$(OBJEXT) \
- ike_header.$(OBJEXT) ke_payload.$(OBJEXT) \
+ proposal.$(OBJEXT) auth_cfg.$(OBJEXT) \
+ traffic_selector.$(OBJEXT) attribute_manager.$(OBJEXT) \
+ controller.$(OBJEXT) daemon.$(OBJEXT) generator.$(OBJEXT) \
+ message.$(OBJEXT) parser.$(OBJEXT) auth_payload.$(OBJEXT) \
+ cert_payload.$(OBJEXT) certreq_payload.$(OBJEXT) \
+ configuration_attribute.$(OBJEXT) cp_payload.$(OBJEXT) \
+ delete_payload.$(OBJEXT) eap_payload.$(OBJEXT) \
+ encodings.$(OBJEXT) encryption_payload.$(OBJEXT) \
+ id_payload.$(OBJEXT) ike_header.$(OBJEXT) ke_payload.$(OBJEXT) \
nonce_payload.$(OBJEXT) notify_payload.$(OBJEXT) \
payload.$(OBJEXT) proposal_substructure.$(OBJEXT) \
sa_payload.$(OBJEXT) traffic_selector_substructure.$(OBJEXT) \
@@ -267,22 +274,22 @@ am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
psk_authenticator.$(OBJEXT) pubkey_authenticator.$(OBJEXT) \
child_sa.$(OBJEXT) ike_sa.$(OBJEXT) ike_sa_id.$(OBJEXT) \
ike_sa_manager.$(OBJEXT) task_manager.$(OBJEXT) \
- keymat.$(OBJEXT) child_create.$(OBJEXT) child_delete.$(OBJEXT) \
- child_rekey.$(OBJEXT) ike_auth.$(OBJEXT) \
- ike_cert_pre.$(OBJEXT) ike_cert_post.$(OBJEXT) \
- ike_config.$(OBJEXT) ike_delete.$(OBJEXT) ike_dpd.$(OBJEXT) \
- ike_init.$(OBJEXT) ike_natd.$(OBJEXT) ike_mobike.$(OBJEXT) \
- ike_rekey.$(OBJEXT) ike_reauth.$(OBJEXT) \
- ike_auth_lifetime.$(OBJEXT) task.$(OBJEXT) \
- credential_manager.$(OBJEXT) auth_info.$(OBJEXT) \
- auth_info_wrapper.$(OBJEXT) ocsp_response_wrapper.$(OBJEXT) \
+ keymat.$(OBJEXT) trap_manager.$(OBJEXT) child_create.$(OBJEXT) \
+ child_delete.$(OBJEXT) child_rekey.$(OBJEXT) \
+ ike_auth.$(OBJEXT) ike_cert_pre.$(OBJEXT) \
+ ike_cert_post.$(OBJEXT) ike_config.$(OBJEXT) \
+ ike_delete.$(OBJEXT) ike_dpd.$(OBJEXT) ike_init.$(OBJEXT) \
+ ike_natd.$(OBJEXT) ike_mobike.$(OBJEXT) ike_rekey.$(OBJEXT) \
+ ike_reauth.$(OBJEXT) ike_auth_lifetime.$(OBJEXT) \
+ task.$(OBJEXT) credential_manager.$(OBJEXT) \
+ auth_cfg_wrapper.$(OBJEXT) ocsp_response_wrapper.$(OBJEXT) \
cert_cache.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3)
charon_OBJECTS = $(am_charon_OBJECTS)
am__DEPENDENCIES_1 =
charon_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -309,12 +316,13 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = . plugins/load_tester plugins/kernel_pfkey \
- plugins/kernel_klips plugins/kernel_netlink plugins/stroke \
- plugins/smp plugins/sql plugins/updown plugins/eap_identity \
+ plugins/kernel_pfroute plugins/kernel_klips \
+ plugins/kernel_netlink plugins/stroke plugins/smp plugins/sql \
+ plugins/updown plugins/attr plugins/eap_identity \
plugins/eap_sim plugins/eap_sim_file plugins/eap_md5 \
plugins/eap_gtc plugins/eap_aka plugins/eap_mschapv2 \
plugins/eap_radius plugins/medsrv plugins/medcli plugins/nm \
- plugins/uci plugins/unit_tester
+ plugins/resolv_conf plugins/uci plugins/unit_tester
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -331,6 +339,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -353,6 +362,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -364,6 +376,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -377,6 +390,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -437,6 +452,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -448,6 +464,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -458,9 +475,10 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.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 config/traffic_selector.c \
- config/traffic_selector.h \
+ config/proposal.h config/auth_cfg.c config/auth_cfg.h \
+ config/traffic_selector.c config/traffic_selector.h \
config/attributes/attribute_provider.h \
+ config/attributes/attribute_handler.h \
config/attributes/attribute_manager.c \
config/attributes/attribute_manager.h control/controller.c \
control/controller.h daemon.c daemon.h encoding/generator.c \
@@ -548,10 +566,10 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \
- sa/tasks/child_create.c sa/tasks/child_create.h \
- sa/tasks/child_delete.c sa/tasks/child_delete.h \
- sa/tasks/child_rekey.c sa/tasks/child_rekey.h \
- sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
+ sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \
+ sa/tasks/child_create.h sa/tasks/child_delete.c \
+ sa/tasks/child_delete.h sa/tasks/child_rekey.c \
+ sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
sa/tasks/ike_config.c sa/tasks/ike_config.h \
@@ -563,9 +581,9 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
credentials/credential_manager.c \
- credentials/credential_manager.h credentials/auth_info.c \
- credentials/auth_info.h credentials/sets/auth_info_wrapper.c \
- credentials/sets/auth_info_wrapper.h \
+ credentials/credential_manager.h \
+ credentials/sets/auth_cfg_wrapper.c \
+ credentials/sets/auth_cfg_wrapper.h \
credentials/sets/ocsp_response_wrapper.c \
credentials/sets/ocsp_response_wrapper.h \
credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
@@ -575,29 +593,30 @@ INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/c
AM_CFLAGS = -rdynamic -DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
-DIPSEC_PLUGINDIR=\"${plugindir}\" \
- -DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
- -DRESOLV_CONF=\"${resolv_conf}\" $(am__append_4) \
- $(am__append_5) -DPLUGINS=\""${PLUGINS}\""
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" $(am__append_4) \
+ -DPLUGINS=\""${PLUGINS}\""
charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lpthread -lm -ldl $(am__append_6)
+ -lpthread -lm $(DLLIB) $(am__append_5)
# build optional plugins
########################
-SUBDIRS = . $(am__append_7) $(am__append_9) $(am__append_11) \
- $(am__append_13) $(am__append_15) $(am__append_17) \
- $(am__append_19) $(am__append_21) $(am__append_23) \
- $(am__append_25) $(am__append_27) $(am__append_29) \
- $(am__append_31) $(am__append_33) $(am__append_35) \
- $(am__append_37) $(am__append_39) $(am__append_41) \
- $(am__append_43) $(am__append_45) $(am__append_47)
-PLUGINS = ${libstrongswan_plugins} $(am__append_8) $(am__append_10) \
+SUBDIRS = . $(am__append_6) $(am__append_8) $(am__append_10) \
$(am__append_12) $(am__append_14) $(am__append_16) \
$(am__append_18) $(am__append_20) $(am__append_22) \
$(am__append_24) $(am__append_26) $(am__append_28) \
$(am__append_30) $(am__append_32) $(am__append_34) \
$(am__append_36) $(am__append_38) $(am__append_40) \
$(am__append_42) $(am__append_44) $(am__append_46) \
- $(am__append_48)
+ $(am__append_48) $(am__append_50) $(am__append_52)
+PLUGINS = ${libstrongswan_plugins} $(am__append_7) $(am__append_9) \
+ $(am__append_11) $(am__append_13) $(am__append_15) \
+ $(am__append_17) $(am__append_19) $(am__append_21) \
+ $(am__append_23) $(am__append_25) $(am__append_27) \
+ $(am__append_29) $(am__append_31) $(am__append_33) \
+ $(am__append_35) $(am__append_37) $(am__append_39) \
+ $(am__append_41) $(am__append_43) $(am__append_45) \
+ $(am__append_47) $(am__append_49) $(am__append_51) \
+ $(am__append_53)
all: all-recursive
.SUFFIXES:
@@ -606,8 +625,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -671,8 +690,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acquire_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attribute_manager.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_info.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_info_wrapper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_cfg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_cfg_wrapper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authenticator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_manager.Po@am__quote@
@@ -765,6 +784,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/traffic_selector_substructure.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_attribute.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_substructure.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trap_manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update_sa_job.Po@am__quote@
@@ -903,6 +923,20 @@ proposal.obj: config/proposal.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o proposal.obj `if test -f 'config/proposal.c'; then $(CYGPATH_W) 'config/proposal.c'; else $(CYGPATH_W) '$(srcdir)/config/proposal.c'; fi`
+auth_cfg.o: config/auth_cfg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_cfg.o -MD -MP -MF $(DEPDIR)/auth_cfg.Tpo -c -o auth_cfg.o `test -f 'config/auth_cfg.c' || echo '$(srcdir)/'`config/auth_cfg.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_cfg.Tpo $(DEPDIR)/auth_cfg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/auth_cfg.c' object='auth_cfg.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_cfg.o `test -f 'config/auth_cfg.c' || echo '$(srcdir)/'`config/auth_cfg.c
+
+auth_cfg.obj: config/auth_cfg.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_cfg.obj -MD -MP -MF $(DEPDIR)/auth_cfg.Tpo -c -o auth_cfg.obj `if test -f 'config/auth_cfg.c'; then $(CYGPATH_W) 'config/auth_cfg.c'; else $(CYGPATH_W) '$(srcdir)/config/auth_cfg.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_cfg.Tpo $(DEPDIR)/auth_cfg.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/auth_cfg.c' object='auth_cfg.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_cfg.obj `if test -f 'config/auth_cfg.c'; then $(CYGPATH_W) 'config/auth_cfg.c'; else $(CYGPATH_W) '$(srcdir)/config/auth_cfg.c'; fi`
+
traffic_selector.o: config/traffic_selector.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT traffic_selector.o -MD -MP -MF $(DEPDIR)/traffic_selector.Tpo -c -o traffic_selector.o `test -f 'config/traffic_selector.c' || echo '$(srcdir)/'`config/traffic_selector.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/traffic_selector.Tpo $(DEPDIR)/traffic_selector.Po
@@ -1771,6 +1805,20 @@ keymat.obj: sa/keymat.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o keymat.obj `if test -f 'sa/keymat.c'; then $(CYGPATH_W) 'sa/keymat.c'; else $(CYGPATH_W) '$(srcdir)/sa/keymat.c'; fi`
+trap_manager.o: sa/trap_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trap_manager.o -MD -MP -MF $(DEPDIR)/trap_manager.Tpo -c -o trap_manager.o `test -f 'sa/trap_manager.c' || echo '$(srcdir)/'`sa/trap_manager.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/trap_manager.Tpo $(DEPDIR)/trap_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/trap_manager.c' object='trap_manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trap_manager.o `test -f 'sa/trap_manager.c' || echo '$(srcdir)/'`sa/trap_manager.c
+
+trap_manager.obj: sa/trap_manager.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT trap_manager.obj -MD -MP -MF $(DEPDIR)/trap_manager.Tpo -c -o trap_manager.obj `if test -f 'sa/trap_manager.c'; then $(CYGPATH_W) 'sa/trap_manager.c'; else $(CYGPATH_W) '$(srcdir)/sa/trap_manager.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/trap_manager.Tpo $(DEPDIR)/trap_manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/trap_manager.c' object='trap_manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o trap_manager.obj `if test -f 'sa/trap_manager.c'; then $(CYGPATH_W) 'sa/trap_manager.c'; else $(CYGPATH_W) '$(srcdir)/sa/trap_manager.c'; fi`
+
child_create.o: sa/tasks/child_create.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT child_create.o -MD -MP -MF $(DEPDIR)/child_create.Tpo -c -o child_create.o `test -f 'sa/tasks/child_create.c' || echo '$(srcdir)/'`sa/tasks/child_create.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/child_create.Tpo $(DEPDIR)/child_create.Po
@@ -2009,33 +2057,19 @@ credential_manager.obj: credentials/credential_manager.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o credential_manager.obj `if test -f 'credentials/credential_manager.c'; then $(CYGPATH_W) 'credentials/credential_manager.c'; else $(CYGPATH_W) '$(srcdir)/credentials/credential_manager.c'; fi`
-auth_info.o: credentials/auth_info.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info.o -MD -MP -MF $(DEPDIR)/auth_info.Tpo -c -o auth_info.o `test -f 'credentials/auth_info.c' || echo '$(srcdir)/'`credentials/auth_info.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info.Tpo $(DEPDIR)/auth_info.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/auth_info.c' object='auth_info.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info.o `test -f 'credentials/auth_info.c' || echo '$(srcdir)/'`credentials/auth_info.c
-
-auth_info.obj: credentials/auth_info.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info.obj -MD -MP -MF $(DEPDIR)/auth_info.Tpo -c -o auth_info.obj `if test -f 'credentials/auth_info.c'; then $(CYGPATH_W) 'credentials/auth_info.c'; else $(CYGPATH_W) '$(srcdir)/credentials/auth_info.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info.Tpo $(DEPDIR)/auth_info.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/auth_info.c' object='auth_info.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info.obj `if test -f 'credentials/auth_info.c'; then $(CYGPATH_W) 'credentials/auth_info.c'; else $(CYGPATH_W) '$(srcdir)/credentials/auth_info.c'; fi`
-
-auth_info_wrapper.o: credentials/sets/auth_info_wrapper.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info_wrapper.o -MD -MP -MF $(DEPDIR)/auth_info_wrapper.Tpo -c -o auth_info_wrapper.o `test -f 'credentials/sets/auth_info_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_info_wrapper.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info_wrapper.Tpo $(DEPDIR)/auth_info_wrapper.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_info_wrapper.c' object='auth_info_wrapper.o' libtool=no @AMDEPBACKSLASH@
+auth_cfg_wrapper.o: credentials/sets/auth_cfg_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_cfg_wrapper.o -MD -MP -MF $(DEPDIR)/auth_cfg_wrapper.Tpo -c -o auth_cfg_wrapper.o `test -f 'credentials/sets/auth_cfg_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_cfg_wrapper.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_cfg_wrapper.Tpo $(DEPDIR)/auth_cfg_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_cfg_wrapper.c' object='auth_cfg_wrapper.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info_wrapper.o `test -f 'credentials/sets/auth_info_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_info_wrapper.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_cfg_wrapper.o `test -f 'credentials/sets/auth_cfg_wrapper.c' || echo '$(srcdir)/'`credentials/sets/auth_cfg_wrapper.c
-auth_info_wrapper.obj: credentials/sets/auth_info_wrapper.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_info_wrapper.obj -MD -MP -MF $(DEPDIR)/auth_info_wrapper.Tpo -c -o auth_info_wrapper.obj `if test -f 'credentials/sets/auth_info_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_info_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_info_wrapper.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_info_wrapper.Tpo $(DEPDIR)/auth_info_wrapper.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_info_wrapper.c' object='auth_info_wrapper.obj' libtool=no @AMDEPBACKSLASH@
+auth_cfg_wrapper.obj: credentials/sets/auth_cfg_wrapper.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT auth_cfg_wrapper.obj -MD -MP -MF $(DEPDIR)/auth_cfg_wrapper.Tpo -c -o auth_cfg_wrapper.obj `if test -f 'credentials/sets/auth_cfg_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_cfg_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_cfg_wrapper.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/auth_cfg_wrapper.Tpo $(DEPDIR)/auth_cfg_wrapper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='credentials/sets/auth_cfg_wrapper.c' object='auth_cfg_wrapper.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_info_wrapper.obj `if test -f 'credentials/sets/auth_info_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_info_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_info_wrapper.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_cfg_wrapper.obj `if test -f 'credentials/sets/auth_cfg_wrapper.c'; then $(CYGPATH_W) 'credentials/sets/auth_cfg_wrapper.c'; else $(CYGPATH_W) '$(srcdir)/credentials/sets/auth_cfg_wrapper.c'; fi`
ocsp_response_wrapper.o: credentials/sets/ocsp_response_wrapper.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ocsp_response_wrapper.o -MD -MP -MF $(DEPDIR)/ocsp_response_wrapper.Tpo -c -o ocsp_response_wrapper.o `test -f 'credentials/sets/ocsp_response_wrapper.c' || echo '$(srcdir)/'`credentials/sets/ocsp_response_wrapper.c
@@ -2258,7 +2292,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index 504947465..bb7014b0b 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: bus.c 4622 2008-11-11 10:52:37Z martin $
*/
#include "bus.h"
@@ -521,6 +519,45 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa,
}
/**
+ * Implementation of bus_t.authorize
+ */
+static bool authorize(private_bus_t *this, linked_list_t *auth, bool final)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ entry_t *entry;
+ bool keep, success = TRUE;
+
+ ike_sa = pthread_getspecific(this->thread_sa);
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->listeners->create_enumerator(this->listeners);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->calling || !entry->listener->authorize)
+ {
+ continue;
+ }
+ entry->calling++;
+ keep = entry->listener->authorize(entry->listener, ike_sa,
+ auth, final, &success);
+ entry->calling--;
+ if (!keep)
+ {
+ unregister_listener(this, entry, enumerator);
+ break;
+ }
+ if (!success)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return success;
+}
+
+/**
* Implementation of bus_t.destroy.
*/
static void destroy(private_bus_t *this)
@@ -548,6 +585,7 @@ bus_t *bus_create()
this->public.message = (void(*)(bus_t*, message_t *message, bool incoming))message;
this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
+ this->public.authorize = (bool(*)(bus_t*, linked_list_t *auth, bool final))authorize;
this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create();
diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h
index fe7d1e53d..5faea088f 100644
--- a/src/charon/bus/bus.h
+++ b/src/charon/bus/bus.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: bus.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -210,6 +208,23 @@ struct listener_t {
*/
bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
+
+ /**
+ * Hook called to invoke additional authorization rules.
+ *
+ * An authorization hook gets invoked several times: After each
+ * authentication round, the hook gets invoked with with final = FALSE.
+ * After authentication is complete and the peer configuration is selected,
+ * it is invoked again, but with final = TRUE.
+ *
+ * @param ike_sa IKE_SA to authorize
+ * @param auth list of auth_cfg_t, done in peers authentication rounds
+ * @param final TRUE if this is the final hook invocation
+ * @param success set to TRUE to complete IKE_SA, FALSE abort
+ * @return TRUE to stay registered, FALSE to unregister
+ */
+ bool (*authorize)(listener_t *this, ike_sa_t *ike_sa, linked_list_t *auth,
+ bool final, bool *success);
};
/**
@@ -317,6 +332,15 @@ struct bus_t {
void (*message)(bus_t *this, message_t *message, bool incoming);
/**
+ * IKE_SA authorization hook.
+ *
+ * @param auth list of auth_cfg_t, containing peers authentication info
+ * @param final TRUE if this is the final invocation
+ * @return TRUE to establish IKE_SA, FALSE to send AUTH_FAILED
+ */
+ bool (*authorize)(bus_t *this, linked_list_t *auth, bool final);
+
+ /**
* IKE_SA keymat hook.
*
* @param ike_sa IKE_SA this keymat belongs to
diff --git a/src/charon/bus/listeners/file_logger.c b/src/charon/bus/listeners/file_logger.c
index 4259630ec..c3213f5f8 100644
--- a/src/charon/bus/listeners/file_logger.c
+++ b/src/charon/bus/listeners/file_logger.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: file_logger.c 4622 2008-11-11 10:52:37Z martin $
*/
#include <stdio.h>
diff --git a/src/charon/bus/listeners/file_logger.h b/src/charon/bus/listeners/file_logger.h
index 5cd37adc0..7282224a5 100644
--- a/src/charon/bus/listeners/file_logger.h
+++ b/src/charon/bus/listeners/file_logger.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: file_logger.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/bus/listeners/sys_logger.c b/src/charon/bus/listeners/sys_logger.c
index 37dbce926..5bcf28f24 100644
--- a/src/charon/bus/listeners/sys_logger.c
+++ b/src/charon/bus/listeners/sys_logger.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sys_logger.c 4434 2008-10-14 08:52:13Z martin $
*/
#include <stdio.h>
diff --git a/src/charon/bus/listeners/sys_logger.h b/src/charon/bus/listeners/sys_logger.h
index 50301924e..6eda096a9 100644
--- a/src/charon/bus/listeners/sys_logger.h
+++ b/src/charon/bus/listeners/sys_logger.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sys_logger.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/config/attributes/attribute_handler.h b/src/charon/config/attributes/attribute_handler.h
new file mode 100644
index 000000000..de1c4414d
--- /dev/null
+++ b/src/charon/config/attributes/attribute_handler.h
@@ -0,0 +1,58 @@
+/*
+ * 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 <sa/ike_sa.h>
+#include <encoding/payloads/configuration_attribute.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 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
+ * IKE_SA gets closed. Depending on the implementation, this is required
+ * to remove the attribute.
+ */
+ void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data);
+};
+
+#endif /* ATTRIBUTE_HANDLER_ @}*/
diff --git a/src/charon/config/attributes/attribute_manager.c b/src/charon/config/attributes/attribute_manager.c
index a069c954a..83e431c43 100644
--- a/src/charon/config/attributes/attribute_manager.c
+++ b/src/charon/config/attributes/attribute_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "attribute_manager.h"
@@ -39,6 +37,11 @@ struct private_attribute_manager_t {
linked_list_t *providers;
/**
+ * list of registered handlers
+ */
+ linked_list_t *handlers;
+
+ /**
* rwlock provider list
*/
rwlock_t *lock;
@@ -49,7 +52,7 @@ struct private_attribute_manager_t {
*/
static host_t* acquire_address(private_attribute_manager_t *this,
char *pool, identification_t *id,
- auth_info_t *auth, host_t *requested)
+ host_t *requested)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -59,7 +62,7 @@ static host_t* acquire_address(private_attribute_manager_t *this,
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &current))
{
- host = current->acquire_address(current, pool, id, auth, requested);
+ host = current->acquire_address(current, pool, id, requested);
if (host)
{
break;
@@ -105,6 +108,29 @@ static void release_address(private_attribute_manager_t *this,
}
/**
+ * inner enumerator constructor for attributes
+ */
+static enumerator_t *attrib_enum_create(attribute_provider_t *provider,
+ identification_t *id)
+{
+ return provider->create_attribute_enumerator(provider, id);
+}
+
+/**
+ * Implementation of attribute_manager_t.create_attribute_enumerator
+ */
+static enumerator_t* create_attribute_enumerator(
+ private_attribute_manager_t *this, identification_t *id)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_cleaner(
+ enumerator_create_nested(
+ this->providers->create_enumerator(this->providers),
+ (void*)attrib_enum_create, id, NULL),
+ (void*)this->lock->unlock, this->lock);
+}
+
+/**
* Implementation of attribute_manager_t.add_provider.
*/
static void add_provider(private_attribute_manager_t *this,
@@ -127,11 +153,89 @@ static void remove_provider(private_attribute_manager_t *this,
}
/**
+ * Implementation of attribute_manager_t.handle
+ */
+static attribute_handler_t* handle(private_attribute_manager_t *this,
+ ike_sa_t *ike_sa, configuration_attribute_type_t type,
+ chunk_t data)
+{
+ enumerator_t *enumerator;
+ attribute_handler_t *current, *handled = NULL;
+
+ this->lock->read_lock(this->lock);
+ 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;
+}
+
+/**
+ * Implementation of attribute_manager_t.release
+ */
+static void release(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);
+}
+
+/**
+ * Implementation of attribute_manager_t.add_handler
+ */
+static void add_handler(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);
+}
+
+/**
+ * Implementation of attribute_manager_t.remove_handler
+ */
+static void remove_handler(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);
+}
+
+/**
* Implementation of attribute_manager_t.destroy
*/
static void destroy(private_attribute_manager_t *this)
{
this->providers->destroy(this->providers);
+ this->handlers->destroy(this->handlers);
this->lock->destroy(this->lock);
free(this);
}
@@ -143,13 +247,19 @@ attribute_manager_t *attribute_manager_create()
{
private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t);
- this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,auth_info_t*,host_t*))acquire_address;
+ this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
+ this->public.create_attribute_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t *id))create_attribute_enumerator;
this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
+ this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))handle;
+ this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t *handler, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data))release;
+ this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))add_handler;
+ this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t *handler))remove_handler;
this->public.destroy = (void(*)(attribute_manager_t*))destroy;
this->providers = linked_list_create();
+ this->handlers = linked_list_create();
this->lock = rwlock_create(RWLOCK_DEFAULT);
return &this->public;
diff --git a/src/charon/config/attributes/attribute_manager.h b/src/charon/config/attributes/attribute_manager.h
index aef6e7b6e..ceea06581 100644
--- a/src/charon/config/attributes/attribute_manager.h
+++ b/src/charon/config/attributes/attribute_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -24,26 +22,31 @@
#define ATTRIBUTE_MANAGER_H_
#include <config/attributes/attribute_provider.h>
+#include <config/attributes/attribute_handler.h>
typedef struct attribute_manager_t attribute_manager_t;
/**
- * Provide configuration attributes to include in CFG Payloads.
+ * 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 pool pool name to acquire address from
- * @param id peer identity to get address for
- * @param auth authorization infos of peer
+ * @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,
char *pool, identification_t *id,
- auth_info_t *auth, host_t *requested);
+ host_t *requested);
/**
* Release a previously acquired address.
@@ -56,6 +59,15 @@ struct attribute_manager_t {
char *pool, host_t *address, identification_t *id);
/**
+ * Create an enumerator over attributes to hand out to a peer.
+ *
+ * @param id peer identity to hand out attributes to
+ * @return enumerator (configuration_attribute_type_t, chunk_t)
+ */
+ enumerator_t* (*create_attribute_enumerator)(attribute_manager_t *this,
+ identification_t *id);
+
+ /**
* Register an attribute provider to the manager.
*
* @param provider attribute provider to register
@@ -69,10 +81,50 @@ struct attribute_manager_t {
*/
void (*remove_provider)(attribute_manager_t *this,
attribute_provider_t *provider);
+
+ /**
+ * Handle a configuration attribute by passing them to the handlers.
+ *
+ * @param ike_sa IKE_SA where attribute was received
+ * @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,
+ configuration_attribute_type_t type, chunk_t data);
+
/**
- * Destroy a attribute_manager instance.
- */
- void (*destroy)(attribute_manager_t *this);
+ * Release an attribute previously handle()d by a handler.
+ *
+ * @param handler handler returned by handle() for this attribute
+ * @param ike_sa IKE_SA owning the attribute
+ * @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);
+
+ /**
+ * 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);
};
/**
diff --git a/src/charon/config/attributes/attribute_provider.h b/src/charon/config/attributes/attribute_provider.h
index 5d563e86b..0f1057af4 100644
--- a/src/charon/config/attributes/attribute_provider.h
+++ b/src/charon/config/attributes/attribute_provider.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -25,7 +23,7 @@
#include <library.h>
#include <utils/host.h>
-#include <credentials/auth_info.h>
+#include <utils/identification.h>
typedef struct attribute_provider_t attribute_provider_t;
@@ -39,13 +37,12 @@ struct attribute_provider_t {
*
* @param pool name of the pool to acquire address from
* @param id peer ID
- * @param auth authorization infos
* @param requested IP in configuration request
* @return allocated address, NULL to serve none
*/
host_t* (*acquire_address)(attribute_provider_t *this,
char *pool, identification_t *id,
- auth_info_t *auth, host_t *requested);
+ host_t *requested);
/**
* Release a previously acquired address.
*
@@ -56,6 +53,15 @@ struct attribute_provider_t {
*/
bool (*release_address)(attribute_provider_t *this,
char *pool, host_t *address, identification_t *id);
+
+ /**
+ * Create an enumerator over attributes to hand out to a peer.
+ *
+ * @param id peer ID
+ * @return enumerator (configuration_attribute_type_t, chunk_t)
+ */
+ enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
+ identification_t *id);
};
#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
diff --git a/src/charon/config/auth_cfg.c b/src/charon/config/auth_cfg.c
new file mode 100644
index 000000000..e4501bc93
--- /dev/null
+++ b/src/charon/config/auth_cfg.c
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "auth_cfg.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+#include <credentials/certificates/certificate.h>
+
+ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
+ "RULE_IDENTITY",
+ "RULE_AUTH_CLASS",
+ "RULE_EAP_IDENTITY",
+ "RULE_EAP_TYPE",
+ "RULE_EAP_VENDOR",
+ "RULE_CA_CERT",
+ "RULE_IM_CERT",
+ "RULE_SUBJECT_CERT",
+ "RULE_CRL_VALIDATION",
+ "RULE_OCSP_VALIDATION",
+ "RULE_AC_GROUP",
+ "HELPER_IM_CERT",
+ "HELPER_SUBJECT_CERT",
+ "HELPER_IM_HASH_URL",
+ "HELPER_SUBJECT_HASH_URL",
+);
+
+typedef struct private_auth_cfg_t private_auth_cfg_t;
+
+/**
+ * private data of item_set
+ */
+struct private_auth_cfg_t {
+
+ /**
+ * public functions
+ */
+ auth_cfg_t public;
+
+ /**
+ * list of entry_t
+ */
+ linked_list_t *entries;
+};
+
+typedef struct entry_t entry_t;
+
+struct entry_t {
+ /** rule type */
+ auth_rule_t type;
+ /** associated value */
+ void *value;
+};
+
+/**
+ * enumerator for auth_cfg_t.create_enumerator()
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** inner enumerator from linked_list_t */
+ enumerator_t *inner;
+ /** current entry */
+ entry_t *current;
+} entry_enumerator_t;
+
+/**
+ * enumerate function for item_enumerator_t
+ */
+static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
+{
+ entry_t *entry;
+
+ if (this->inner->enumerate(this->inner, &entry))
+ {
+ this->current = entry;
+ *type = entry->type;
+ *value = entry->value;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * destroy function for item_enumerator_t
+ */
+static void entry_enumerator_destroy(entry_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of auth_cfg_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_auth_cfg_t *this)
+{
+ entry_enumerator_t *enumerator;
+
+ enumerator = malloc_thing(entry_enumerator_t);
+ enumerator->inner = this->entries->create_enumerator(this->entries);
+ enumerator->public.enumerate = (void*)enumerate;
+ enumerator->public.destroy = (void*)entry_enumerator_destroy;
+ enumerator->current = NULL;
+ return &enumerator->public;
+}
+
+/**
+ * Destroy the value associated with an entry
+ */
+static void destroy_entry_value(entry_t *entry)
+{
+ switch (entry->type)
+ {
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ {
+ identification_t *id = (identification_t*)entry->value;
+ id->destroy(id);
+ break;
+ }
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ {
+ certificate_t *cert = (certificate_t*)entry->value;
+ cert->destroy(cert);
+ break;
+ }
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ {
+ free(entry->value);
+ break;
+ }
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ break;
+ }
+}
+
+/**
+ * Implementation of auth_cfg_t.replace.
+ */
+static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
+ auth_rule_t type, ...)
+{
+ if (enumerator->current)
+ {
+ va_list args;
+
+ va_start(args, type);
+
+ destroy_entry_value(enumerator->current);
+ enumerator->current->type = type;
+ switch (type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ /* integer type */
+ enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
+ break;
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ /* pointer type */
+ enumerator->current->value = va_arg(args, void*);
+ break;
+ }
+ va_end(args);
+ }
+}
+
+/**
+ * Implementation of auth_cfg_t.get.
+ */
+static void* get(private_auth_cfg_t *this, auth_rule_t type)
+{
+ enumerator_t *enumerator;
+ void *current_value, *best_value = NULL;
+ auth_rule_t current_type;
+ bool found = FALSE;
+
+ enumerator = create_enumerator(this);
+ while (enumerator->enumerate(enumerator, &current_type, &current_value))
+ {
+ if (type == current_type)
+ {
+ if (type == AUTH_RULE_CRL_VALIDATION ||
+ type == AUTH_RULE_OCSP_VALIDATION)
+ { /* for CRL/OCSP validation, always get() the highest value */
+ if (!found || current_value > best_value)
+ {
+ best_value = current_value;
+ }
+ found = TRUE;
+ continue;
+ }
+ best_value = current_value;
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (found)
+ {
+ return best_value;
+ }
+ switch (type)
+ {
+ /* use some sane defaults if we don't find an entry */
+ case AUTH_RULE_AUTH_CLASS:
+ return (void*)AUTH_CLASS_ANY;
+ case AUTH_RULE_EAP_TYPE:
+ return (void*)EAP_NAK;
+ case AUTH_RULE_EAP_VENDOR:
+ return (void*)0;
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ return (void*)VALIDATION_FAILED;
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of auth_cfg_t.add.
+ */
+static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
+{
+ entry_t *entry = malloc_thing(entry_t);
+ va_list args;
+
+ va_start(args, type);
+ entry->type = type;
+ switch (type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ /* integer type */
+ entry->value = (void*)(uintptr_t)va_arg(args, u_int);
+ break;
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ /* pointer type */
+ entry->value = va_arg(args, void*);
+ break;
+ }
+ va_end(args);
+ this->entries->insert_last(this->entries, entry);
+}
+
+/**
+ * Implementation of auth_cfg_t.complies.
+ */
+static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
+ bool log_error)
+{
+ enumerator_t *e1, *e2;
+ bool success = TRUE;
+ auth_rule_t t1, t2;
+ void *value;
+
+ e1 = constraints->create_enumerator(constraints);
+ while (e1->enumerate(e1, &t1, &value))
+ {
+ switch (t1)
+ {
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ {
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)value;
+
+ success = FALSE;
+ e2 = create_enumerator(this);
+ while (e2->enumerate(e2, &t2, &c2))
+ {
+ if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
+ c1->equals(c1, c2))
+ {
+ success = TRUE;
+ }
+ }
+ e2->destroy(e2);
+ if (!success && log_error)
+ {
+ DBG1(DBG_CFG, "constraint check failed: peer not "
+ "authenticated by CA '%Y'.", c1->get_subject(c1));
+ }
+ break;
+ }
+ case AUTH_RULE_SUBJECT_CERT:
+ {
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)value;
+ c2 = get(this, AUTH_RULE_SUBJECT_CERT);
+ if (!c2 || !c1->equals(c1, c2))
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint check failed: peer not "
+ "authenticated with peer cert '%Y'.",
+ c1->get_subject(c1));
+ }
+ }
+ break;
+ }
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ {
+ cert_validation_t validated, required;
+
+ required = (uintptr_t)value;
+ validated = (uintptr_t)get(this, t1);
+ switch (required)
+ {
+ case VALIDATION_FAILED:
+ /* no constraint */
+ break;
+ case VALIDATION_SKIPPED:
+ if (validated == VALIDATION_SKIPPED)
+ {
+ break;
+ }
+ /* FALL */
+ case VALIDATION_GOOD:
+ if (validated == VALIDATION_GOOD)
+ {
+ break;
+ }
+ /* FALL */
+ default:
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint check failed: %N is %N, "
+ "but requires at least %N", auth_rule_names,
+ t1, cert_validation_names, validated,
+ cert_validation_names, required);
+ }
+ break;
+ }
+ break;
+ }
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ {
+ identification_t *id1, *id2;
+
+ id1 = (identification_t*)value;
+ id2 = get(this, t1);
+ if (!id2 || !id2->matches(id2, id1))
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
+ " required ", t1 == AUTH_RULE_IDENTITY ? "" :
+ "EAP ", id1);
+ }
+ }
+ break;
+ }
+ case AUTH_RULE_AUTH_CLASS:
+ {
+ if ((uintptr_t)value != AUTH_CLASS_ANY &&
+ (uintptr_t)value != (uintptr_t)get(this, t1))
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint requires %N authentication, "
+ "but %N was used", auth_class_names, (uintptr_t)value,
+ auth_class_names, (uintptr_t)get(this, t1));
+ }
+ }
+ break;
+ }
+ case AUTH_RULE_EAP_TYPE:
+ {
+ if ((uintptr_t)value != (uintptr_t)get(this, t1))
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint requires %N, "
+ "but %N was used", eap_type_names, (uintptr_t)value,
+ eap_type_names, (uintptr_t)get(this, t1));
+ }
+ }
+ break;
+ }
+ case AUTH_RULE_EAP_VENDOR:
+ {
+ if ((uintptr_t)value != (uintptr_t)get(this, t1))
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
+ "but %d was used", (uintptr_t)value,
+ (uintptr_t)get(this, t1));
+ }
+ }
+ break;
+ }
+ case AUTH_RULE_AC_GROUP:
+ {
+ success = FALSE;
+ if (log_error)
+ {
+ DBG1(DBG_CFG, "constraint check %N not implemented!",
+ auth_rule_names, t1);
+ }
+ break;
+ }
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ /* skip helpers */
+ continue;
+ }
+ if (!success)
+ {
+ break;
+ }
+ }
+ e1->destroy(e1);
+ return success;
+}
+
+/**
+ * Implementation of auth_cfg_t.merge.
+ */
+static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
+{
+ if (!other)
+ { /* nothing to merge */
+ return;
+ }
+ if (copy)
+ {
+ enumerator_t *enumerator;
+ auth_rule_t type;
+ void *value;
+
+ enumerator = create_enumerator(other);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ switch (type)
+ {
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ {
+ certificate_t *cert = (certificate_t*)value;
+
+ add(this, type, cert->get_ref(cert));
+ break;
+ }
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ {
+ add(this, type, (uintptr_t)value);
+ break;
+ }
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ {
+ identification_t *id = (identification_t*)value;
+
+ add(this, type, id->clone(id));
+ break;
+ }
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ {
+ add(this, type, strdup((char*)value));
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ entry_t *entry;
+
+ while (other->entries->remove_first(other->entries,
+ (void**)&entry) == SUCCESS)
+ {
+ this->entries->insert_last(this->entries, entry);
+ }
+ }
+}
+
+/**
+ * Implementation of auth_cfg_t.equals.
+ */
+static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
+{
+ enumerator_t *e1, *e2;
+ entry_t *i1, *i2;
+ bool equal = TRUE, found;
+
+ if (this->entries->get_count(this->entries) !=
+ other->entries->get_count(other->entries))
+ {
+ return FALSE;
+ }
+ e1 = this->entries->create_enumerator(this->entries);
+ while (e1->enumerate(e1, &i1))
+ {
+ found = FALSE;
+ e2 = other->entries->create_enumerator(other->entries);
+ while (e2->enumerate(e2, &i2))
+ {
+ if (i1->type == i2->type)
+ {
+ switch (i1->type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ {
+ if (i1->value == i2->value)
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ {
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)i1->value;
+ c2 = (certificate_t*)i2->value;
+
+ if (c1->equals(c1, c2))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ {
+ identification_t *id1, *id2;
+
+ id1 = (identification_t*)i1->value;
+ id2 = (identification_t*)i2->value;
+
+ if (id1->equals(id1, id2))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ {
+ if (streq(i1->value, i2->value))
+ {
+ found = TRUE;
+ break;
+ }
+ continue;
+ }
+ }
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (!found)
+ {
+ equal = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ return equal;
+}
+
+/**
+ * Implementation of auth_cfg_t.purge
+ */
+static void purge(private_auth_cfg_t *this, bool keep_ca)
+{
+ entry_t *entry;
+ linked_list_t *cas;
+
+ cas = linked_list_create();
+ while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
+ {
+ if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
+ {
+ cas->insert_first(cas, entry);
+ }
+ else
+ {
+ destroy_entry_value(entry);
+ free(entry);
+ }
+ }
+ while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
+ {
+ this->entries->insert_first(this->entries, entry);
+ }
+ cas->destroy(cas);
+}
+
+/**
+ * Implementation of auth_cfg_t.clone
+ */
+static auth_cfg_t* clone_(private_auth_cfg_t *this)
+{
+ enumerator_t *enumerator;
+ auth_cfg_t *clone;
+ entry_t *entry;
+
+ clone = auth_cfg_create();
+ enumerator = this->entries->create_enumerator(this->entries);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ switch (entry->type)
+ {
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AC_GROUP:
+ {
+ identification_t *id = (identification_t*)entry->value;
+ clone->add(clone, entry->type, id->clone(id));
+ break;
+ }
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ {
+ certificate_t *cert = (certificate_t*)entry->value;
+ clone->add(clone, entry->type, cert->get_ref(cert));
+ break;
+ }
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ {
+ clone->add(clone, entry->type, strdup(entry->value));
+ break;
+ }
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ clone->add(clone, entry->type, (uintptr_t)entry->value);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return clone;
+}
+
+/**
+ * Implementation of auth_cfg_t.destroy
+ */
+static void destroy(private_auth_cfg_t *this)
+{
+ purge(this, FALSE);
+ this->entries->destroy(this->entries);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+auth_cfg_t *auth_cfg_create()
+{
+ private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
+
+ this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
+ this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
+ this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
+ this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
+ this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
+ this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
+ this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
+ this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
+ this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
+ this->public.destroy = (void(*)(auth_cfg_t*))destroy;
+
+ this->entries = linked_list_create();
+
+ return &this->public;
+}
+
diff --git a/src/charon/config/auth_cfg.h b/src/charon/config/auth_cfg.h
new file mode 100644
index 000000000..c6bc1959b
--- /dev/null
+++ b/src/charon/config/auth_cfg.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup auth_cfg auth_cfg
+ * @{ @ingroup config
+ */
+
+#ifndef AUTH_CFG_H_
+#define AUTH_CFG_H_
+
+#include <utils/enumerator.h>
+
+typedef struct auth_cfg_t auth_cfg_t;
+typedef enum auth_rule_t auth_rule_t;
+
+/**
+ * Authentication config to use during authentication process.
+ *
+ * Each authentication config contains a set of rules. These rule-sets are used
+ * in two ways:
+ * - For configs specifying local authentication behavior, the rules define
+ * which authentication method in which way.
+ * - For configs specifying remote peer authentication, the rules define
+ * constraints the peer has to fullfill.
+ *
+ * Additionally to the rules, there is a set of helper items. These are used
+ * to transport credentials during the authentication process.
+ */
+enum auth_rule_t {
+
+ /** identity to use for IKEv2 authentication exchange, identification_t* */
+ AUTH_RULE_IDENTITY,
+ /** authentication class, auth_class_t */
+ AUTH_RULE_AUTH_CLASS,
+ /** EAP identity to use within EAP-Identity exchange, identification_t* */
+ AUTH_RULE_EAP_IDENTITY,
+ /** EAP type to propose for peer authentication, eap_type_t */
+ AUTH_RULE_EAP_TYPE,
+ /** EAP vendor for vendor specific type, u_int32_t */
+ AUTH_RULE_EAP_VENDOR,
+ /** certificate authority, certificate_t* */
+ AUTH_RULE_CA_CERT,
+ /** intermediate certificate in trustchain, certificate_t* */
+ AUTH_RULE_IM_CERT,
+ /** subject certificate, certificate_t* */
+ AUTH_RULE_SUBJECT_CERT,
+ /** result of a CRL validation, cert_validation_t */
+ AUTH_RULE_CRL_VALIDATION,
+ /** result of a OCSP validation, cert_validation_t */
+ AUTH_RULE_OCSP_VALIDATION,
+ /** subject is in attribute certificate group, identification_t* */
+ AUTH_RULE_AC_GROUP,
+
+ /** intermediate certificate, certificate_t* */
+ AUTH_HELPER_IM_CERT,
+ /** subject certificate, certificate_t* */
+ AUTH_HELPER_SUBJECT_CERT,
+ /** Hash and URL of a intermediate certificate, char* */
+ AUTH_HELPER_IM_HASH_URL,
+ /** Hash and URL of a end-entity certificate, char* */
+ AUTH_HELPER_SUBJECT_HASH_URL,
+};
+
+/**
+ * enum name for auth_rule_t.
+ */
+extern enum_name_t *auth_rule_names;
+
+/**
+ * Authentication/Authorization round.
+ *
+ * RFC4739 defines multiple authentication rounds. This class defines such
+ * a round from a configuration perspective, either for the local or the remote
+ * peer. Local config are called "rulesets", as they define how we authenticate.
+ * Remote peer configs are called "constraits", they define what is needed to
+ * complete the authentication round successfully.
+ *
+ * @verbatim
+
+ [Repeat for each configuration]
+ +--------------------------------------------------+
+ | |
+ | |
+ | +----------+ IKE_AUTH +--------- + |
+ | | config | -----------> | | |
+ | | ruleset | | | |
+ | +----------+ [ <----------- ] | | |
+ | [ optional EAP ] | Peer | |
+ | +----------+ [ -----------> ] | | |
+ | | config | | | |
+ | | constr. | <----------- | | |
+ | +----------+ IKE_AUTH +--------- + |
+ | |
+ | |
+ +--------------------------------------------------+
+
+ @endverbatim
+ *
+ * Values for each items are either pointers (casted to void*) or short
+ * integers (use uintptr_t cast).
+ */
+struct auth_cfg_t {
+
+ /**
+ * Add an rule to the set.
+ *
+ * @param rule rule type
+ * @param ... associated value to rule
+ */
+ void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
+
+ /**
+ * Get an rule value.
+ *
+ * @param rule rule type
+ * @return bool if item has been found
+ */
+ void* (*get)(auth_cfg_t *this, auth_rule_t rule);
+
+ /**
+ * Create an enumerator over added rules.
+ *
+ * @return enumerator over (auth_rule_t, union{void*,uintpr_t})
+ */
+ enumerator_t* (*create_enumerator)(auth_cfg_t *this);
+
+ /**
+ * Replace an rule at enumerator position.
+ *
+ * @param pos enumerator position position
+ * @param rule rule type
+ * @param ... associated value to rule
+ */
+ void (*replace)(auth_cfg_t *this, enumerator_t *pos,
+ auth_rule_t rule, ...);
+
+ /**
+ * Check if a used config fulfills a set of configured constraints.
+ *
+ * @param constraints required authorization rules
+ * @param log_error wheter to log compliance errors
+ * @return TRUE if this complies with constraints
+ */
+ bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error);
+
+ /**
+ * Merge items from other into this.
+ *
+ * @param other items to read for merge
+ * @param copy TRUE to copy items, FALSE to move them
+ */
+ void (*merge)(auth_cfg_t *this, auth_cfg_t *other, bool copy);
+
+ /**
+ * Purge all rules in a config.
+ *
+ * @param keep_ca wheter to keep AUTH_RULE_CA_CERT entries
+ */
+ void (*purge)(auth_cfg_t *this, bool keep_ca);
+
+ /**
+ * Check two configs for equality.
+ *
+ * @param other other config to compaire against this
+ * @return TRUE if auth infos identical
+ */
+ bool (*equals)(auth_cfg_t *this, auth_cfg_t *other);
+
+ /**
+ * Clone a authentication config, including all rules.
+ *
+ * @return cloned configuration
+ */
+ auth_cfg_t* (*clone)(auth_cfg_t *this);
+
+ /**
+ * Destroy a config with all associated rules/values.
+ */
+ void (*destroy)(auth_cfg_t *this);
+};
+
+/**
+ * Create a authentication config.
+ */
+auth_cfg_t *auth_cfg_create();
+
+#endif /** AUTH_CFG_H_ @}*/
diff --git a/src/charon/config/backend.h b/src/charon/config/backend.h
index 3a22f61ac..458abc37f 100644
--- a/src/charon/config/backend.h
+++ b/src/charon/config/backend.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: backend.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -28,7 +26,6 @@ typedef struct backend_t backend_t;
#include <library.h>
#include <config/ike_cfg.h>
#include <config/peer_cfg.h>
-#include <credentials/auth_info.h>
#include <utils/linked_list.h>
/**
@@ -45,6 +42,10 @@ struct backend_t {
*
* Hosts may be NULL to get all.
*
+ * There is no requirement for the backend to filter the configurations
+ * using the supplied hosts; but it may do so if it increases lookup times
+ * (e.g. include hosts in SQL query).
+ *
* @param me address of local host
* @param other address of remote host
* @return enumerator over ike_cfg_t's
@@ -52,10 +53,17 @@ struct backend_t {
enumerator_t* (*create_ike_cfg_enumerator)(backend_t *this,
host_t *me, host_t *other);
/**
- * Create an enumerator over all Peer configs matching two IDs.
+ * Create an enumerator over all peer configs matching two identities.
*
* IDs may be NULL to get all.
*
+ * As configurations are looked up in the first authentication round (when
+ * multiple authentication), the backend implementation should compare
+ * the identities to the first auth_cfgs only.
+ * There is no requirement for the backend to filter the configurations
+ * using the supplied identities; but it may do so if it increases lookup
+ * times (e.g. include hosts in SQL query).
+ *
* @param me identity of ourself
* @param other identity of remote host
* @return enumerator over peer_cfg_t
@@ -64,7 +72,7 @@ struct backend_t {
identification_t *me,
identification_t *other);
/**
- * Get a peer_cfg identified by it's name, or a name of its child.
+ * Get a peer_cfg identified by it's name, or a name of its children.
*
* @param name name of peer/child cfg
* @return matching peer_config, or NULL if none found
diff --git a/src/charon/config/backend_manager.c b/src/charon/config/backend_manager.c
index a9fe974af..3a3a78466 100644
--- a/src/charon/config/backend_manager.c
+++ b/src/charon/config/backend_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: backend_manager.c 4758 2008-12-04 23:16:10Z andreas $
*/
#include "backend_manager.h"
@@ -68,15 +66,6 @@ typedef struct {
} ike_data_t;
/**
- * data to pass nested peer enumerator
- */
-typedef struct {
- private_backend_manager_t *this;
- identification_t *me;
- identification_t *other;
-} peer_data_t;
-
-/**
* inner enumerator constructor for IKE cfgs
*/
static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
@@ -85,59 +74,58 @@ static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
}
/**
- * inner enumerator constructor for Peer cfgs
- */
-static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
-{
- return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
-}
-/**
- * inner enumerator constructor for all Peer cfgs
- */
-static enumerator_t *peer_enum_create_all(backend_t *backend)
-{
- return backend->create_peer_cfg_enumerator(backend, NULL, NULL);
-}
-
-/**
* get a match of a candidate ike_cfg for two hosts
*/
-static ike_cfg_match_t get_match(ike_cfg_t *cand, host_t *me, host_t *other)
+static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
{
host_t *me_cand, *other_cand;
ike_cfg_match_t match = MATCH_NONE;
- me_cand = host_create_from_dns(cand->get_my_addr(cand),
- me->get_family(me), 0);
- if (!me_cand)
+ if (me)
{
- return MATCH_NONE;
- }
- if (me_cand->ip_equals(me_cand, me))
- {
- match += MATCH_ME;
+ me_cand = host_create_from_dns(cand->get_my_addr(cand),
+ me->get_family(me), 0);
+ if (!me_cand)
+ {
+ return MATCH_NONE;
+ }
+ if (me_cand->ip_equals(me_cand, me))
+ {
+ match += MATCH_ME;
+ }
+ else if (me_cand->is_anyaddr(me_cand))
+ {
+ match += MATCH_ANY;
+ }
+ me_cand->destroy(me_cand);
}
- else if (me_cand->is_anyaddr(me_cand))
+ else
{
match += MATCH_ANY;
}
- me_cand->destroy(me_cand);
- other_cand = host_create_from_dns(cand->get_other_addr(cand),
- other->get_family(other), 0);
- if (!other_cand)
+ if (other)
{
- return MATCH_NONE;
- }
- if (other_cand->ip_equals(other_cand, other))
- {
- match += MATCH_OTHER;
+ other_cand = host_create_from_dns(cand->get_other_addr(cand),
+ other->get_family(other), 0);
+ if (!other_cand)
+ {
+ return MATCH_NONE;
+ }
+ if (other_cand->ip_equals(other_cand, other))
+ {
+ match += MATCH_OTHER;
+ }
+ else if (other_cand->is_anyaddr(other_cand))
+ {
+ match += MATCH_ANY;
+ }
+ other_cand->destroy(other_cand);
}
- else if (other_cand->is_anyaddr(other_cand))
+ else
{
match += MATCH_ANY;
}
- other_cand->destroy(other_cand);
return match;
}
@@ -165,7 +153,7 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
(void*)ike_enum_create, data, (void*)free);
while (enumerator->enumerate(enumerator, (void**)&current))
{
- match = get_match(current, me, other);
+ match = get_ike_match(current, me, other);
if (match)
{
@@ -191,87 +179,198 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
return found;
}
+/**
+ * Get the best ID match in one of the configs auth_cfg
+ */
+static id_match_t get_peer_match(identification_t *id,
+ peer_cfg_t *cfg, bool local)
+{
+ enumerator_t *enumerator;
+ auth_cfg_t *auth;
+ identification_t *candidate;
+ id_match_t match = ID_MATCH_NONE;
+
+ if (!id)
+ {
+ return ID_MATCH_ANY;
+ }
+
+ /* compare first auth config only */
+ enumerator = cfg->create_auth_cfg_enumerator(cfg, local);
+ if (enumerator->enumerate(enumerator, &auth))
+ {
+ candidate = auth->get(auth, AUTH_RULE_IDENTITY);
+ if (candidate)
+ {
+ match = id->matches(id, candidate);
+ /* match vice-versa, as the proposed IDr might be ANY */
+ if (!match)
+ {
+ match = candidate->matches(candidate, id);
+ }
+ }
+ else
+ {
+ match = ID_MATCH_ANY;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return match;
+}
+
+/**
+ * data to pass nested peer enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ identification_t *me;
+ identification_t *other;
+} peer_data_t;
+
+/**
+ * list element to help sorting
+ */
+typedef struct {
+ id_match_t match_peer;
+ ike_cfg_match_t match_ike;
+ peer_cfg_t *cfg;
+} match_entry_t;
+
+/**
+ * inner enumerator constructor for peer cfgs
+ */
+static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
+{
+ return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
+}
+
+/**
+ * unlock/cleanup peer enumerator
+ */
+static void peer_enum_destroy(peer_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
+}
-static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this)
+/**
+ * convert enumerator value from match_entry to config
+ */
+static bool peer_enum_filter(linked_list_t *configs,
+ match_entry_t **in, peer_cfg_t **out)
{
- this->lock->read_lock(this->lock);
- return enumerator_create_nested(
- this->backends->create_enumerator(this->backends),
- (void*)peer_enum_create_all, this->lock,
- (void*)this->lock->unlock);
+ *out = (*in)->cfg;
+ return TRUE;
+}
+
+/**
+ * Clean up temporary config list
+ */
+static void peer_enum_filter_destroy(linked_list_t *configs)
+{
+ match_entry_t *entry;
+
+ while (configs->remove_last(configs, (void**)&entry) == SUCCESS)
+ {
+ entry->cfg->destroy(entry->cfg);
+ free(entry);
+ }
+ configs->destroy(configs);
}
/**
- * implements backend_manager_t.get_peer_cfg.
+ * Insert entry into match-sorted list, using helper
+ */
+static void insert_sorted(match_entry_t *entry, linked_list_t *list,
+ linked_list_t *helper)
+{
+ match_entry_t *current;
+
+ while (list->remove_first(list, (void**)&current) == SUCCESS)
+ {
+ helper->insert_last(helper, current);
+ }
+ while (helper->remove_first(helper, (void**)&current) == SUCCESS)
+ {
+ if (entry && (
+ (entry->match_ike > current->match_ike &&
+ entry->match_peer >= current->match_peer) ||
+ (entry->match_ike >= current->match_ike &&
+ entry->match_peer > current->match_peer)))
+ {
+ list->insert_last(list, entry);
+ entry = NULL;
+ }
+ list->insert_last(list, current);
+ }
+ if (entry)
+ {
+ list->insert_last(list, entry);
+ }
+}
+
+/**
+ * Implements backend_manager_t.create_peer_cfg_enumerator.
*/
-static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this, host_t *me,
- host_t *other, identification_t *my_id,
- identification_t *other_id, auth_info_t *auth)
+static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
+ host_t *me, host_t *other, identification_t *my_id,
+ identification_t *other_id)
{
- peer_cfg_t *current, *found = NULL;
enumerator_t *enumerator;
- id_match_t best_peer = ID_MATCH_NONE;
- ike_cfg_match_t best_ike = MATCH_NONE;
peer_data_t *data;
-
- DBG2(DBG_CFG, "looking for a peer config for %H[%D]...%H[%D]",
- me, my_id, other, other_id);
+ peer_cfg_t *cfg;
+ linked_list_t *configs, *helper;
data = malloc_thing(peer_data_t);
- data->this = this;
+ data->lock = this->lock;
data->me = my_id;
data->other = other_id;
+ /* create a sorted list with all matches */
this->lock->read_lock(this->lock);
enumerator = enumerator_create_nested(
- this->backends->create_enumerator(this->backends),
- (void*)peer_enum_create, data, (void*)free);
- while (enumerator->enumerate(enumerator, &current))
+ this->backends->create_enumerator(this->backends),
+ (void*)peer_enum_create, data, (void*)peer_enum_destroy);
+
+ if (!me && !other && !my_id && !other_id)
+ { /* shortcut if we are doing a "listall" */
+ return enumerator;
+ }
+
+ DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
+ me, my_id, other, other_id);
+
+ configs = linked_list_create();
+ /* only once allocated helper list for sorting */
+ helper = linked_list_create();
+ while (enumerator->enumerate(enumerator, &cfg))
{
- identification_t *my_cand, *other_cand;
- id_match_t m1, m2, match_peer;
+ id_match_t match_peer_me, match_peer_other;
ike_cfg_match_t match_ike;
+ match_entry_t *entry;
- my_cand = current->get_my_id(current);
- other_cand = current->get_other_id(current);
-
- /* own ID may have wildcards in both, config and request (missing IDr) */
- m1 = my_cand->matches(my_cand, my_id);
- if (!m1)
- {
- m1 = my_id->matches(my_id, my_cand);
- }
- m2 = other_id->matches(other_id, other_cand);
-
- match_peer = m1 + m2;
- match_ike = get_match(current->get_ike_cfg(current), me, other);
+ match_peer_me = get_peer_match(my_id, cfg, TRUE);
+ match_peer_other = get_peer_match(other_id, cfg, FALSE);
+ match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
- if (m1 && m2 && match_ike &&
- auth->complies(auth, current->get_auth(current)))
+ if (match_peer_me && match_peer_other && match_ike)
{
- DBG2(DBG_CFG, " candidate \"%s\": %D...%D with prio %d.%d",
- current->get_name(current), my_cand, other_cand,
- match_peer, match_ike);
- if ((match_peer > best_peer && match_ike >= best_ike) ||
- (match_peer >= best_peer && match_ike > best_ike))
- {
- DESTROY_IF(found);
- found = current;
- found->get_ref(found);
- best_peer = match_peer;
- best_ike = match_ike;
- }
+ DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d (me/other/ike)",
+ cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike);
+
+ entry = malloc_thing(match_entry_t);
+ entry->match_peer = match_peer_me + match_peer_other;
+ entry->match_ike = match_ike;
+ entry->cfg = cfg->get_ref(cfg);
+ insert_sorted(entry, configs, helper);
}
}
- if (found)
- {
- DBG1(DBG_CFG, "found matching peer config \"%s\": %D...%D with prio %d.%d",
- found->get_name(found), found->get_my_id(found),
- found->get_other_id(found), best_peer, best_ike);
- }
enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
- return found;
+ helper->destroy(helper);
+
+ return enumerator_create_filter(configs->create_enumerator(configs),
+ (void*)peer_enum_filter, configs,
+ (void*)peer_enum_filter_destroy);
}
/**
@@ -332,9 +431,8 @@ backend_manager_t *backend_manager_create()
private_backend_manager_t *this = malloc_thing(private_backend_manager_t);
this->public.get_ike_cfg = (ike_cfg_t* (*)(backend_manager_t*, host_t*, host_t*))get_ike_cfg;
- this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_t*,host_t*,host_t*,identification_t*,identification_t*,auth_info_t*))get_peer_cfg;
this->public.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_manager_t*,char*))get_peer_cfg_by_name;
- this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*))create_peer_cfg_enumerator;
+ this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*,host_t*,host_t*,identification_t*,identification_t*))create_peer_cfg_enumerator;
this->public.add_backend = (void(*)(backend_manager_t*, backend_t *backend))add_backend;
this->public.remove_backend = (void(*)(backend_manager_t*, backend_t *backend))remove_backend;
this->public.destroy = (void (*)(backend_manager_t*))destroy;
diff --git a/src/charon/config/backend_manager.h b/src/charon/config/backend_manager.h
index 657e5af94..0b7d7d0f8 100644
--- a/src/charon/config/backend_manager.h
+++ b/src/charon/config/backend_manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: backend_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -64,20 +62,6 @@ struct backend_manager_t {
host_t *my_host, host_t *other_host);
/**
- * Get a peer_config identified by two IDs and authorization info.
- *
- * @param me own address
- * @param other peer address
- * @param my_id own ID
- * @param other_id peer ID
- * @param auth_info authorization info
- * @return matching peer_config, or NULL if none found
- */
- peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this, host_t *me,
- host_t *other, identification_t *my_id,
- identification_t *other_id, auth_info_t *auth);
-
- /**
* Get a peer_config identified by it's name.
*
* @param name name of the peer_config
@@ -86,12 +70,20 @@ struct backend_manager_t {
peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name);
/**
- * Create an enumerator over all peer configs.
+ * Create an enumerator over all matching peer configs.
*
- * @return enumerator over peer configs
+ * Pass NULL as parameters to match any. The enumerator enumerates over
+ * peer_cfgs, ordered by priority (best match first).
+ *
+ * @param me local address
+ * @param other remote address
+ * @param my_id IDr in first authentication round
+ * @param other_id IDi in first authentication round
+ * @return enumerator over peer_cfg_t
*/
- enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this);
-
+ enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this,
+ host_t *me, host_t *other, identification_t *my_id,
+ identification_t *other_id);
/**
* Register a backend on the manager.
*
diff --git a/src/charon/config/child_cfg.c b/src/charon/config/child_cfg.c
index 737a38e89..43e41671a 100644
--- a/src/charon/config/child_cfg.c
+++ b/src/charon/config/child_cfg.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_cfg.c 4862 2009-02-11 16:41:37Z andreas $
*/
#include "child_cfg.h"
diff --git a/src/charon/config/child_cfg.h b/src/charon/config/child_cfg.h
index 6e3b0ba00..185fee3da 100644
--- a/src/charon/config/child_cfg.h
+++ b/src/charon/config/child_cfg.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_cfg.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/config/ike_cfg.c b/src/charon/config/ike_cfg.c
index 8beccdc29..e80ab577e 100644
--- a/src/charon/config/ike_cfg.c
+++ b/src/charon/config/ike_cfg.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cfg.c 4062 2008-06-12 11:42:19Z martin $
*/
#include "ike_cfg.h"
diff --git a/src/charon/config/ike_cfg.h b/src/charon/config/ike_cfg.h
index c2f1f2867..064906423 100644
--- a/src/charon/config/ike_cfg.h
+++ b/src/charon/config/ike_cfg.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cfg.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c
index 9cbca040d..da796d6a2 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007-2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: peer_cfg.c 4612 2008-11-11 06:37:37Z andreas $
*/
#include <string.h>
@@ -82,16 +80,6 @@ struct private_peer_cfg_t {
mutex_t *mutex;
/**
- * id to use to identify us
- */
- identification_t *my_id;
-
- /**
- * allowed id for other
- */
- identification_t *other_id;
-
- /**
* should we send a certificate
*/
cert_policy_t cert_policy;
@@ -147,10 +135,15 @@ struct private_peer_cfg_t {
char *pool;
/**
- * required authorization constraints
+ * local authentication configs (rulesets)
*/
- auth_info_t *auth;
-
+ linked_list_t *local_auth;
+
+ /**
+ * remote authentication configs (constraints)
+ */
+ linked_list_t *remote_auth;
+
#ifdef ME
/**
* Is this a mediation connection?
@@ -205,13 +198,39 @@ static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
}
/**
+ * child_cfg enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ enumerator_t *wrapped;
+ mutex_t *mutex;
+} child_cfg_enumerator_t;
+
+/**
* Implementation of peer_cfg_t.remove_child_cfg.
*/
-static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
+static void remove_child_cfg(private_peer_cfg_t *this,
+ child_cfg_enumerator_t *enumerator)
+{
+ this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
+}
+
+/**
+ * Implementation of child_cfg_enumerator_t.destroy
+ */
+static void child_cfg_enumerator_destroy(child_cfg_enumerator_t *this)
{
- this->mutex->lock(this->mutex);
- this->child_cfgs->remove_at(this->child_cfgs, enumerator);
this->mutex->unlock(this->mutex);
+ this->wrapped->destroy(this->wrapped);
+ free(this);
+}
+
+/**
+ * Implementation of child_cfg_enumerator_t.enumerate
+ */
+static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd)
+{
+ return this->wrapped->enumerate(this->wrapped, chd);
}
/**
@@ -219,12 +238,15 @@ static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
*/
static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
{
- enumerator_t *enumerator;
-
+ child_cfg_enumerator_t *enumerator = malloc_thing(child_cfg_enumerator_t);
+
+ enumerator->public.enumerate = (void*)child_cfg_enumerate;
+ enumerator->public.destroy = (void*)child_cfg_enumerator_destroy;
+ enumerator->mutex = this->mutex;
+ enumerator->wrapped = this->child_cfgs->create_enumerator(this->child_cfgs);
+
this->mutex->lock(this->mutex);
- enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
- return enumerator_create_cleaner(enumerator,
- (void*)this->mutex->unlock, this->mutex);
+ return &enumerator->public;
}
/**
@@ -287,22 +309,6 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
}
/**
- * Implementation of peer_cfg_t.get_my_id
- */
-static identification_t *get_my_id(private_peer_cfg_t *this)
-{
- return this->my_id;
-}
-
-/**
- * Implementation of peer_cfg_t.get_other_id
- */
-static identification_t *get_other_id(private_peer_cfg_t *this)
-{
- return this->other_id;
-}
-
-/**
* Implementation of peer_cfg_t.get_cert_policy.
*/
static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
@@ -397,13 +403,34 @@ static char* get_pool(private_peer_cfg_t *this)
{
return this->pool;
}
-
+
+/**
+ * Implementation of peer_cfg_t.add_auth_cfg
+ */
+static void add_auth_cfg(private_peer_cfg_t *this,
+ auth_cfg_t *cfg, bool local)
+{
+ if (local)
+ {
+ this->local_auth->insert_last(this->local_auth, cfg);
+ }
+ else
+ {
+ this->remote_auth->insert_last(this->remote_auth, cfg);
+ }
+}
+
/**
- * Implementation of peer_cfg_t.get_auth.
+ * Implementation of peer_cfg_t.create_auth_cfg_enumerator
*/
-static auth_info_t* get_auth(private_peer_cfg_t *this)
+static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
+ bool local)
{
- return this->auth;
+ if (local)
+ {
+ return this->local_auth->create_enumerator(this->local_auth);
+ }
+ return this->remote_auth->create_enumerator(this->remote_auth);
}
#ifdef ME
@@ -433,6 +460,60 @@ static identification_t* get_peer_id(private_peer_cfg_t *this)
#endif /* ME */
/**
+ * check auth configs for equality
+ */
+static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
+{
+ enumerator_t *e1, *e2;
+ auth_cfg_t *cfg1, *cfg2;
+ bool equal = TRUE;
+
+ if (this->local_auth->get_count(this->local_auth) !=
+ other->local_auth->get_count(other->local_auth))
+ {
+ return FALSE;
+ }
+ if (this->remote_auth->get_count(this->remote_auth) !=
+ other->remote_auth->get_count(other->remote_auth))
+ {
+ return FALSE;
+ }
+
+ e1 = this->local_auth->create_enumerator(this->local_auth);
+ e2 = other->local_auth->create_enumerator(other->local_auth);
+ while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
+ {
+ if (!cfg1->equals(cfg1, cfg2))
+ {
+ equal = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+
+ if (!equal)
+ {
+ return FALSE;
+ }
+
+ e1 = this->remote_auth->create_enumerator(this->remote_auth);
+ e2 = other->remote_auth->create_enumerator(other->remote_auth);
+ while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
+ {
+ if (!cfg1->equals(cfg1, cfg2))
+ {
+ equal = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+
+ return equal;
+}
+
+/**
* Implementation of peer_cfg_t.equals.
*/
static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
@@ -448,8 +529,6 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
return (
this->ike_version == other->ike_version &&
- this->my_id->equals(this->my_id, other->my_id) &&
- this->other_id->equals(this->other_id, other->other_id) &&
this->cert_policy == other->cert_policy &&
this->unique == other->unique &&
this->keyingtries == other->keyingtries &&
@@ -464,7 +543,7 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
(this->pool == other->pool ||
(this->pool && other->pool && streq(this->pool, other->pool))) &&
- this->auth->equals(this->auth, other->auth)
+ auth_cfg_equal(this, other)
#ifdef ME
&& this->mediation == other->mediation &&
this->mediated_by == other->mediated_by &&
@@ -492,11 +571,13 @@ static void destroy(private_peer_cfg_t *this)
if (ref_put(&this->refcount))
{
this->ike_cfg->destroy(this->ike_cfg);
- this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
- this->my_id->destroy(this->my_id);
- this->other_id->destroy(this->other_id);
+ this->child_cfgs->destroy_offset(this->child_cfgs,
+ offsetof(child_cfg_t, destroy));
DESTROY_IF(this->virtual_ip);
- this->auth->destroy(this->auth);
+ this->local_auth->destroy_offset(this->local_auth,
+ offsetof(auth_cfg_t, destroy));
+ this->remote_auth->destroy_offset(this->remote_auth,
+ offsetof(auth_cfg_t, destroy));
#ifdef ME
DESTROY_IF(this->mediated_by);
DESTROY_IF(this->peer_id);
@@ -512,7 +593,6 @@ static void destroy(private_peer_cfg_t *this)
* Described in header-file
*/
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
- identification_t *my_id, identification_t *other_id,
cert_policy_t cert_policy, unique_policy_t unique,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
@@ -531,8 +611,6 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
- this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
- this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
@@ -543,7 +621,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
- this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
+ this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg;
+ this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator;
this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
this->public.destroy = (void(*)(peer_cfg_t *))destroy;
@@ -559,8 +638,6 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->ike_cfg = ike_cfg;
this->child_cfgs = linked_list_create();
this->mutex = mutex_create(MUTEX_DEFAULT);
- this->my_id = my_id;
- this->other_id = other_id;
this->cert_policy = cert_policy;
this->unique = unique;
this->keyingtries = keyingtries;
@@ -580,7 +657,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->dpd = dpd;
this->virtual_ip = virtual_ip;
this->pool = pool ? strdup(pool) : NULL;
- this->auth = auth_info_create();
+ this->local_auth = linked_list_create();
+ this->remote_auth = linked_list_create();
this->refcount = 1;
#ifdef ME
this->mediation = mediation;
diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h
index 93bc7d495..3c095eff0 100644
--- a/src/charon/config/peer_cfg.h
+++ b/src/charon/config/peer_cfg.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007-2008 Tobias Brunner
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: peer_cfg.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -38,7 +36,7 @@ typedef struct peer_cfg_t peer_cfg_t;
#include <config/child_cfg.h>
#include <sa/authenticators/authenticator.h>
#include <sa/authenticators/eap/eap_method.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
/**
* Certificate sending policy. This is also used for certificate
@@ -87,27 +85,33 @@ extern enum_name_t *unique_policy_names;
* exactly one ike_cfg_t, which is use for initiation. Additionally, it contains
* multiple child_cfg_t defining which CHILD_SAs are allowed for this peer.
* @verbatim
-
- +-------------------+ +---------------+
- +---------------+ | peer_cfg | +---------------+ |
- | ike_cfg | +-------------------+ | child_cfg | |
- +---------------+ | - ids | +---------------+ |
- | - hosts | 1 1 | - cas | 1 n | - proposals | |
- | - proposals |<------| - auth info |-------->| - traffic sel | |
- | - ... | | - dpd config | | - ... |-+
- +---------------+ | - ... | +---------------+
- +-------------------+
- ^
- |
- +-------------------+
- | auth_info |
- +-------------------+
- | auth_items |
- +-------------------+
+ +-------------------+ +---------------+
+ +---------------+ | peer_cfg | +---------------+ |
+ | ike_cfg | +-------------------+ | child_cfg | |
+ +---------------+ | - ids | +---------------+ |
+ | - hosts | 1 1 | - cas | 1 n | - proposals | |
+ | - proposals |<-----| - auth info |----->| - traffic sel | |
+ | - ... | | - dpd config | | - ... |-+
+ +---------------+ | - ... | +---------------+
+ +-------------------+
+ | 1 0 |
+ | |
+ v n n V
+ +-------------------+ +-------------------+
+ +-------------------+ | +-------------------+ |
+ | auth_cfg | | | auth_cfg | |
+ +-------------------+ | +-------------------+ |
+ | - local rules |-+ | - remote constr. |-+
+ +-------------------+ +-------------------+
@endverbatim
- * The auth_info_t object associated to the peer_cfg holds additional
- * authorization constraints. A peer who wants to use a config needs to fullfil
- * the requirements defined in auth_info.
+ *
+ * Each peer_cfg has two lists of authentication config attached. Local
+ * authentication configs define how to authenticate ourself against the remote
+ * peer. Each config is enforced using the multiple authentication extension
+ * (RFC4739).
+ * The remote authentication configs are handled as constraints. The peer has
+ * to fullfill each of these rules (using multiple authentication, in any order)
+ * to gain access to the configuration.
*/
struct peer_cfg_t {
@@ -169,25 +173,20 @@ struct peer_cfg_t {
host_t *other_host);
/**
- * Get the authentication constraint items.
+ * Add an authentication config to the peer configuration.
*
- * @return auth_info object to manipulate requirements
- */
- auth_info_t* (*get_auth)(peer_cfg_t *this);
-
- /**
- * Get own ID.
- *
- * @return own id
+ * @param config config to add
+ * @param local TRUE for local rules, FALSE for remote constraints
*/
- identification_t* (*get_my_id)(peer_cfg_t *this);
+ void (*add_auth_cfg)(peer_cfg_t *this, auth_cfg_t *cfg, bool local);
/**
- * Get peers ID.
- *
- * @return other id
+ * Create an enumerator over registered authentication configs.
+ *
+ * @param local TRUE for local rules, FALSE for remote constraints
+ * @return enumerator over auth_cfg_t*
*/
- identification_t* (*get_other_id)(peer_cfg_t *this);
+ enumerator_t* (*create_auth_cfg_enumerator)(peer_cfg_t *this, bool local);
/**
* Should be sent a certificate for this connection?
@@ -331,8 +330,6 @@ struct peer_cfg_t {
* @param name name of the peer_cfg
* @param ike_version which IKE version we sould use for this peer
* @param ike_cfg IKE config to use when acting as initiator
- * @param my_id identification_t for ourselves
- * @param other_id identification_t for the remote guy
* @param cert_policy should we send a certificate payload?
* @param unique uniqueness of an IKE_SA
* @param keyingtries how many keying tries should be done before giving up
@@ -350,7 +347,6 @@ struct peer_cfg_t {
* @return peer_cfg_t object
*/
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
- identification_t *my_id, identification_t *other_id,
cert_policy_t cert_policy, unique_policy_t unique,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index 92ef34b75..e2dfcca4f 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: proposal.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <string.h>
@@ -24,10 +22,11 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <utils/lexparser.h>
+#include <crypto/transform.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
-
+#include <crypto/proposal/proposal_keywords.h>
ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP,
"PROTO_NONE",
@@ -36,16 +35,6 @@ ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP,
"ESP",
);
-ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, UNDEFINED_TRANSFORM_TYPE,
- "UNDEFINED_TRANSFORM_TYPE");
-ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, UNDEFINED_TRANSFORM_TYPE,
- "ENCRYPTION_ALGORITHM",
- "PSEUDO_RANDOM_FUNCTION",
- "INTEGRITY_ALGORITHM",
- "DIFFIE_HELLMAN_GROUP",
- "EXTENDED_SEQUENCE_NUMBERS");
-ENUM_END(transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
-
ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS,
"NO_EXT_SEQ",
"EXT_SEQ",
@@ -585,227 +574,57 @@ static void check_proposal(private_proposal_t *this)
/**
* add a algorithm identified by a string to the proposal.
- * TODO: we could use gperf here.
*/
static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
{
- if (strncmp(alg.ptr, "null", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_NULL, 0);
- }
- else if (strncmp(alg.ptr, "aes128", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128);
- }
- else if (strncmp(alg.ptr, "aes192", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192);
- }
- else if (strncmp(alg.ptr, "aes256", alg.len) == 0)
+ const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len);
+
+ if (token == NULL)
{
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
+ return FAILED;
}
- else if (strstr(alg.ptr, "ccm"))
- {
- u_int16_t key_size, icv_size;
- if (sscanf(alg.ptr, "aes%huccm%hu", &key_size, &icv_size) == 2)
- {
- if (key_size == 128 || key_size == 192 || key_size == 256)
- {
- switch (icv_size)
- {
- case 8: /* octets */
- case 64: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_CCM_ICV8, key_size);
- break;
- case 12: /* octets */
- case 96: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_CCM_ICV12, key_size);
- break;
- case 16: /* octets */
- case 128: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_CCM_ICV16, key_size);
- break;
- default:
- /* invalid ICV size */
- break;
- }
- }
- }
- }
- else if (strstr(alg.ptr, "gcm"))
- {
- u_int16_t key_size, icv_size;
+ add_algorithm(this, token->type, token->algorithm, token->keysize);
- if (sscanf(alg.ptr, "aes%hugcm%hu", &key_size, &icv_size) == 2)
- {
- if (key_size == 128 || key_size == 192 || key_size == 256)
- {
- switch (icv_size)
- {
- case 8: /* octets */
- case 64: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_GCM_ICV8, key_size);
- break;
- case 12: /* octets */
- case 96: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_GCM_ICV12, key_size);
- break;
- case 16: /* octets */
- case 128: /* bits */
- add_algorithm(this, ENCRYPTION_ALGORITHM,
- ENCR_AES_GCM_ICV16, key_size);
- break;
- default:
- /* invalid ICV size */
- break;
- }
- }
- }
- }
- else if (strncmp(alg.ptr, "3des", alg.len) == 0)
+ if (this->protocol == PROTO_IKE && token->type == INTEGRITY_ALGORITHM)
{
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
- }
- /* blowfish only uses some predefined key sizes yet */
- else if (strncmp(alg.ptr, "blowfish128", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128);
- }
- else if (strncmp(alg.ptr, "blowfish192", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192);
- }
- else if (strncmp(alg.ptr, "blowfish256", alg.len) == 0)
- {
- add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256);
- }
- else if (strncmp(alg.ptr, "sha", alg.len) == 0 ||
- strncmp(alg.ptr, "sha1", alg.len) == 0)
- {
- /* sha means we use SHA for both, PRF and AUTH */
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
- if (this->protocol == PROTO_IKE)
- {
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0);
- }
- }
- else if (strncmp(alg.ptr, "sha256", alg.len) == 0 ||
- strncmp(alg.ptr, "sha2_256", alg.len) == 0)
- {
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
- if (this->protocol == PROTO_IKE)
- {
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0);
- }
- }
- else if (strncmp(alg.ptr, "sha384", alg.len) == 0 ||
- strncmp(alg.ptr, "sha2_384", alg.len) == 0)
- {
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
- if (this->protocol == PROTO_IKE)
- {
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0);
- }
- }
- else if (strncmp(alg.ptr, "sha512", alg.len) == 0 ||
- strncmp(alg.ptr, "sha2_512", alg.len) == 0)
- {
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
- if (this->protocol == PROTO_IKE)
- {
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_512, 0);
- }
- }
- else if (strncmp(alg.ptr, "md5", alg.len) == 0)
- {
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
- if (this->protocol == PROTO_IKE)
+ pseudo_random_function_t prf;
+
+ switch (token->algorithm)
{
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
+ case AUTH_HMAC_SHA1_96:
+ prf = PRF_HMAC_SHA1;
+ break;
+ case AUTH_HMAC_SHA2_256_128:
+ prf = PRF_HMAC_SHA2_256;
+ break;
+ case AUTH_HMAC_SHA2_384_192:
+ prf = PRF_HMAC_SHA2_384;
+ break;
+ case AUTH_HMAC_SHA2_512_256:
+ prf = PRF_HMAC_SHA2_512;
+ break;
+ case AUTH_HMAC_MD5_96:
+ prf = PRF_HMAC_MD5;
+ break;
+ case AUTH_AES_XCBC_96:
+ prf = PRF_AES128_XCBC;
+ break;
+ default:
+ prf = PRF_UNDEFINED;
}
- }
- else if (strncmp(alg.ptr, "aesxcbc", alg.len) == 0)
- {
- add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
- if (this->protocol == PROTO_IKE)
+ if (prf != PRF_UNDEFINED)
{
- add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0);
+ add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
}
}
- else if (strncmp(alg.ptr, "modpnull", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0);
- }
- else if (strncmp(alg.ptr, "modp768", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp1024", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp1536", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp2048", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp3072", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp4096", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp6144", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0);
- }
- else if (strncmp(alg.ptr, "modp8192", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0);
- }
- else if (strncmp(alg.ptr, "ecp192", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0);
- }
- else if (strncmp(alg.ptr, "ecp224", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0);
- }
- else if (strncmp(alg.ptr, "ecp256", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0);
- }
- else if (strncmp(alg.ptr, "ecp384", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0);
- }
- else if (strncmp(alg.ptr, "ecp521", alg.len) == 0)
- {
- add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0);
- }
- else
- {
- return FAILED;
- }
return SUCCESS;
}
/**
* print all algorithms of a kind to buffer
*/
-static int print_alg(private_proposal_t *this, char **dst, int *len,
+static int print_alg(private_proposal_t *this, char **dst, size_t *len,
u_int kind, void *names, bool *first)
{
enumerator_t *enumerator;
@@ -826,7 +645,7 @@ static int print_alg(private_proposal_t *this, char **dst, int *len,
}
if (size)
{
- written += print_in_hook(*dst, *len, "-%d", size);
+ written += print_in_hook(*dst, *len, "_%u", size);
}
}
enumerator->destroy(enumerator);
diff --git a/src/charon/config/proposal.h b/src/charon/config/proposal.h
index 6096158e6..bc7a8c5e7 100644
--- a/src/charon/config/proposal.h
+++ b/src/charon/config/proposal.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: proposal.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -24,7 +22,6 @@
#define PROPOSAL_H_
typedef enum protocol_id_t protocol_id_t;
-typedef enum transform_type_t transform_type_t;
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
typedef struct proposal_t proposal_t;
@@ -32,6 +29,7 @@ typedef struct proposal_t proposal_t;
#include <utils/identification.h>
#include <utils/linked_list.h>
#include <utils/host.h>
+#include <crypto/transform.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <crypto/diffie_hellman.h>
@@ -52,25 +50,6 @@ enum protocol_id_t {
*/
extern enum_name_t *protocol_id_names;
-
-/**
- * Type of a transform, as in IKEv2 RFC 3.3.2.
- */
-enum transform_type_t {
- UNDEFINED_TRANSFORM_TYPE = 241,
- ENCRYPTION_ALGORITHM = 1,
- PSEUDO_RANDOM_FUNCTION = 2,
- INTEGRITY_ALGORITHM = 3,
- DIFFIE_HELLMAN_GROUP = 4,
- EXTENDED_SEQUENCE_NUMBERS = 5
-};
-
-/**
- * enum names for transform_type_t.
- */
-extern enum_name_t *transform_type_names;
-
-
/**
* Extended sequence numbers, as in IKEv2 RFC 3.3.2.
*/
diff --git a/src/charon/config/traffic_selector.c b/src/charon/config/traffic_selector.c
index b3bab900d..a8ea10008 100644
--- a/src/charon/config/traffic_selector.c
+++ b/src/charon/config/traffic_selector.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: traffic_selector.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <arpa/inet.h>
diff --git a/src/charon/config/traffic_selector.h b/src/charon/config/traffic_selector.h
index 2721f8993..a57da43a8 100644
--- a/src/charon/config/traffic_selector.h
+++ b/src/charon/config/traffic_selector.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: traffic_selector.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/control/controller.c b/src/charon/control/controller.c
index 989167a53..021cb4fdd 100644
--- a/src/charon/control/controller.c
+++ b/src/charon/control/controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: controller.c 4704 2008-11-26 14:32:55Z martin $
*/
#include "controller.h"
@@ -172,15 +170,12 @@ static bool listener_child_state(interface_listener_t *this, ike_sa_t *ike_sa,
{
switch (state)
{
- case CHILD_ROUTED:
case CHILD_INSTALLED:
this->status = SUCCESS;
return FALSE;
case CHILD_DESTROYING:
switch (child_sa->get_state(child_sa))
{
- case CHILD_ROUTED:
- /* has been unrouted */
case CHILD_DELETING:
/* proper delete */
this->status = SUCCESS;
@@ -235,7 +230,7 @@ static status_t initiate_execute(interface_job_t *job)
}
peer_cfg->destroy(peer_cfg);
- if (ike_sa->initiate(ike_sa, listener->child_cfg) == SUCCESS)
+ if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
return SUCCESS;
@@ -426,125 +421,6 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
}
/**
- * execute function for route
- */
-static status_t route_execute(interface_job_t *job)
-{
- interface_listener_t *listener = &job->listener;
- ike_sa_t *ike_sa = listener->ike_sa;
-
- charon->bus->set_sa(charon->bus, ike_sa);
- if (ike_sa->route(ike_sa, listener->child_cfg) != DESTROY_ME)
- {
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
- }
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return FAILED;
-}
-
-/**
- * Implementation of controller_t.route.
- */
-static status_t route(controller_t *this,
- peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param)
-{
- ike_sa_t *ike_sa;
- interface_job_t job = {
- .listener = {
- .public = {
- .log = (void*)listener_log,
- .ike_state_change = (void*)listener_ike_state,
- .child_state_change = (void*)listener_child_state,
- },
- .callback = callback,
- .param = param,
- .status = FAILED,
- .peer_cfg = peer_cfg,
- .child_cfg = child_cfg,
- },
- .public = {
- .execute = (void*)route_execute,
- .destroy = (void*)recheckin,
- },
- };
-
- ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
- peer_cfg);
- if (ike_sa->get_peer_cfg(ike_sa) == NULL)
- {
- ike_sa->set_peer_cfg(ike_sa, peer_cfg);
- }
- job.listener.ike_sa = ike_sa;
- if (callback == NULL)
- {
- return route_execute(&job);
- }
- charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job);
- return job.listener.status;
-}
-
-/**
- * execute function for unroute
- */
-static status_t unroute_execute(interface_job_t *job)
-{
- interface_listener_t *listener = &job->listener;
- ike_sa_t *ike_sa = listener->ike_sa;
-
- if (ike_sa->unroute(ike_sa, listener->id) != DESTROY_ME)
- {
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
- }
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
-}
-
-/**
- * Implementation of controller_t.unroute.
- */
-static status_t unroute(controller_t *this, u_int32_t reqid,
- controller_cb_t callback, void *param)
-{
- ike_sa_t *ike_sa;
- interface_job_t job = {
- .listener = {
- .public = {
- .log = (void*)listener_log,
- .ike_state_change = (void*)listener_ike_state,
- .child_state_change = (void*)listener_child_state,
- },
- .callback = callback,
- .param = param,
- .status = FAILED,
- .id = reqid,
- },
- .public = {
- .execute = (void*)unroute_execute,
- .destroy = (void*)recheckin,
- },
- };
-
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- reqid, TRUE);
- if (ike_sa == NULL)
- {
- DBG1(DBG_IKE, "unable to unroute, CHILD_SA with ID %d not found", reqid);
- return NOT_FOUND;
- }
- job.listener.ike_sa = ike_sa;
-
- if (callback == NULL)
- {
- return unroute_execute(&job);
- }
- charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job);
- return job.listener.status;
-}
-
-/**
* See header
*/
bool controller_cb_empty(void *param, debug_t group, level_t level,
@@ -572,8 +448,6 @@ controller_t *controller_create(void)
this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,controller_cb_t,void*))initiate;
this->public.terminate_ike = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void*))terminate_ike;
this->public.terminate_child = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void *param))terminate_child;
- this->public.route = (status_t(*)(controller_t*,peer_cfg_t*, child_cfg_t*,controller_cb_t,void*))route;
- this->public.unroute = (status_t(*)(controller_t*,u_int32_t,controller_cb_t,void*))unroute;
this->public.destroy = (void (*)(controller_t*))destroy;
return &this->public;
diff --git a/src/charon/control/controller.h b/src/charon/control/controller.h
index b2eaf480b..3c928d2ea 100644
--- a/src/charon/control/controller.h
+++ b/src/charon/control/controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -126,38 +124,6 @@ struct controller_t {
controller_cb_t callback, void *param);
/**
- * Route a CHILD_SA (install triggering policies).
- *
- * @param peer_cfg peer_cfg to use for IKE_SA setup, if triggered
- * @param child_cfg child_cfg to route
- * @param cb logging callback
- * @param param parameter to include in each call of cb
- * @return
- * - SUCCESS, if CHILD_SA routed
- * - FAILED, if routing failed
- * - NEED_MORE, if callback returned FALSE
- */
- status_t (*route)(controller_t *this,
- peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param);
-
- /**
- * Unroute a routed CHILD_SA (uninstall triggering policies).
- *
- * Only the route is removed, not the CHILD_SAs the route triggered.
- *
- * @param reqid reqid of the CHILD_SA to unroute
- * @param cb logging callback
- * @param param parameter to include in each call of cb
- * @return
- * - SUCCESS, if CHILD_SA terminated
- * - NOT_FOUND, if no such CHILD_SA routed
- * - NEED_MORE, if callback returned FALSE
- */
- status_t (*unroute)(controller_t *this, u_int32_t reqid,
- controller_cb_t callback, void *param);
-
- /**
* Destroy a controller_t instance.
*/
void (*destroy) (controller_t *this);
diff --git a/src/charon/credentials/auth_info.c b/src/charon/credentials/auth_info.c
deleted file mode 100644
index ed725b889..000000000
--- a/src/charon/credentials/auth_info.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- *
- * $Id: auth_info.c 4774 2008-12-09 14:34:15Z martin $
- */
-
-
-#include "auth_info.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <credentials/certificates/certificate.h>
-
-ENUM(auth_item_names, AUTHN_CA_CERT, AUTHZ_AC_GROUP,
- "AUTHN_AUTH_CLASS",
- "AUTHN_EAP_TYPE",
- "AUTHN_EAP_VENDOR",
- "AUTHN_EAP_IDENTITY",
- "AUTHN_CA_CERT",
- "AUTHN_CA_CERT_KEYID",
- "AUTHN_CA_CERT_NAME",
- "AUTHN_IM_CERT",
- "AUTHN_SUBJECT_CERT",
- "AUTHN_IM_HASH_URL",
- "AUTHN_SUBJECT_HASH_URL",
- "AUTHZ_PUBKEY",
- "AUTHZ_PSK",
- "AUTHZ_EAP",
- "AUTHZ_CA_CERT",
- "AUTHZ_CA_CERT_NAME",
- "AUTHZ_IM_CERT",
- "AUTHZ_SUBJECT_CERT",
- "AUTHZ_CRL_VALIDATION",
- "AUTHZ_OCSP_VALIDATION",
- "AUTHZ_AC_GROUP",
-);
-
-typedef struct private_auth_info_t private_auth_info_t;
-
-/**
- * private data of item_set
- */
-struct private_auth_info_t {
-
- /**
- * public functions
- */
- auth_info_t public;
-
- /**
- * list of item_t's
- */
- linked_list_t *items;
-};
-
-typedef struct item_t item_t;
-
-struct item_t {
- /** type of this item */
- auth_item_t type;
- /** associated privlege value, if any */
- void *value;
-};
-
-/**
- * enumerator for auth_info_wrapper_t.create_cert_enumerator()
- */
-typedef struct {
- /** implements enumerator_t */
- enumerator_t public;
- /** inner enumerator from linked_list_t */
- enumerator_t *inner;
- /** the current item */
- item_t *item;
-} item_enumerator_t;
-
-/**
- * enumerate function for item_enumerator_t
- */
-static bool enumerate(item_enumerator_t *this, auth_item_t *type, void **value)
-{
- if (this->inner->enumerate(this->inner, &this->item))
- {
- *type = this->item->type;
- *value = this->item->value;
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * destroy function for item_enumerator_t
- */
-static void item_enumerator_destroy(item_enumerator_t *this)
-{
- this->inner->destroy(this->inner);
- free(this);
-}
-
-/**
- * Implementation of auth_info_t.create_item_enumerator.
- */
-static enumerator_t* create_item_enumerator(private_auth_info_t *this)
-{
- item_enumerator_t *enumerator;
-
- enumerator = malloc_thing(item_enumerator_t);
- enumerator->item = NULL;
- enumerator->inner = this->items->create_enumerator(this->items);
- enumerator->public.enumerate = (void*)enumerate;
- enumerator->public.destroy = (void*)item_enumerator_destroy;
- return &enumerator->public;
-}
-
-static void destroy_item_value(item_t *item);
-
-/**
- * Implementation of auth_info_t.replace_item.
- */
-static void replace_item(item_enumerator_t *enumerator, auth_item_t type, void *value)
-{
- destroy_item_value(enumerator->item);
- enumerator->item->type = type;
- enumerator->item->value = value;
-}
-
-/**
- * Implementation of auth_info_t.get_item.
- */
-static bool get_item(private_auth_info_t *this, auth_item_t type, void** value)
-{
- enumerator_t *enumerator;
- void *current_value;
- auth_item_t current_type;
- bool found = FALSE;
-
- enumerator = create_item_enumerator(this);
- while (enumerator->enumerate(enumerator, &current_type, &current_value))
- {
- if (type == current_type)
- {
- *value = current_value;
- found = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
- return found;
-}
-
-/**
- * Implementation of auth_info_t.add_item.
- */
-static void add_item(private_auth_info_t *this, auth_item_t type, void *value)
-{
- item_t *item = malloc_thing(item_t);
-
- item->type = type;
- switch (type)
- {
- case AUTHZ_PUBKEY:
- {
- public_key_t *key = (public_key_t*)value;
-
- item->value = key->get_ref(key);
- break;
- }
- case AUTHZ_PSK:
- {
- shared_key_t *key = (shared_key_t*)value;
-
- item->value = key->get_ref(key);
- break;
- }
- case AUTHN_IM_HASH_URL:
- case AUTHN_SUBJECT_HASH_URL:
- {
- item->value = strdup(value);
- break;
- }
- case AUTHN_CA_CERT:
- case AUTHN_IM_CERT:
- case AUTHN_SUBJECT_CERT:
- case AUTHZ_CA_CERT:
- case AUTHZ_IM_CERT:
- case AUTHZ_SUBJECT_CERT:
- {
- certificate_t *cert = (certificate_t*)value;
-
- item->value = cert->get_ref(cert);
- break;
- }
- case AUTHZ_CRL_VALIDATION:
- case AUTHZ_OCSP_VALIDATION:
- {
- cert_validation_t *validation = malloc_thing(cert_validation_t);
-
- *validation = *(cert_validation_t*)value;
- item->value = validation;
- break;
- }
- case AUTHN_AUTH_CLASS:
- case AUTHN_EAP_TYPE:
- case AUTHN_EAP_VENDOR:
- case AUTHZ_EAP:
- {
- u_int *intval = malloc_thing(u_int);
-
- *intval = *(u_int*)value;
- item->value = intval;
- break;
- }
- case AUTHN_EAP_IDENTITY:
- case AUTHN_CA_CERT_KEYID:
- case AUTHN_CA_CERT_NAME:
- case AUTHZ_CA_CERT_NAME:
- case AUTHZ_AC_GROUP:
- {
- identification_t *id = (identification_t*)value;
-
- item->value = id->clone(id);
- break;
- }
- }
- this->items->insert_last(this->items, item);
-}
-
-
-/**
- * Implementation of auth_info_t.complies.
- */
-static bool complies(private_auth_info_t *this, auth_info_t *constraints)
-{
- enumerator_t *enumerator;
- bool success = TRUE;
- auth_item_t t1, t2;
- void *value;
-
- enumerator = constraints->create_item_enumerator(constraints);
- while (enumerator->enumerate(enumerator, &t1, &value))
- {
- switch (t1)
- {
- case AUTHN_AUTH_CLASS:
- case AUTHN_EAP_TYPE:
- case AUTHN_EAP_VENDOR:
- case AUTHN_EAP_IDENTITY:
- case AUTHN_CA_CERT_KEYID:
- case AUTHN_CA_CERT:
- case AUTHN_CA_CERT_NAME:
- case AUTHN_IM_CERT:
- case AUTHN_SUBJECT_CERT:
- case AUTHN_IM_HASH_URL:
- case AUTHN_SUBJECT_HASH_URL:
- { /* skip non-authorization tokens */
- continue;
- }
- case AUTHZ_CRL_VALIDATION:
- case AUTHZ_OCSP_VALIDATION:
- {
- cert_validation_t *valid;
-
- /* OCSP validation is also sufficient for CRL constraint, but
- * not vice-versa */
- if (!get_item(this, t1, (void**)&valid) &&
- t1 == AUTHZ_CRL_VALIDATION &&
- !get_item(this, AUTHZ_OCSP_VALIDATION, (void**)&valid))
- {
- DBG1(DBG_CFG, "constraint check failed: %N requires at "
- "least %N, but no check done", auth_item_names, t1,
- cert_validation_names, *(cert_validation_t*)value);
- success = FALSE;
- break;
- }
- switch (*(cert_validation_t*)value)
- {
- case VALIDATION_SKIPPED:
- if (*valid == VALIDATION_SKIPPED)
- {
- break;
- } /* FALL */
- case VALIDATION_GOOD:
- if (*valid == VALIDATION_GOOD)
- {
- break;
- } /* FALL */
- default:
- DBG1(DBG_CFG, "constraint check failed: %N is %N, but "
- "requires at least %N", auth_item_names, t1,
- cert_validation_names, *valid,
- cert_validation_names, *(cert_validation_t*)value);
- success = FALSE;
- break;
- }
- break;
- }
- case AUTHZ_CA_CERT:
- {
- enumerator_t *enumerator;
- certificate_t *c1, *c2;
-
- c1 = (certificate_t*)value;
-
- success = FALSE;
- enumerator = create_item_enumerator(this);
- while (enumerator->enumerate(enumerator, &t2, &c2))
- {
- if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
- c1->equals(c1, c2))
- {
- success = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- if (!success)
- {
- DBG1(DBG_CFG, "constraint check failed: peer not "
- "authenticated by CA '%D'.", c1->get_subject(c1));
- }
- break;
- }
- case AUTHZ_CA_CERT_NAME:
- {
- enumerator_t *enumerator;
- certificate_t *cert;
- identification_t *id;
-
- id = (identification_t*)value;
- success = FALSE;
- enumerator = create_item_enumerator(this);
- while (enumerator->enumerate(enumerator, &t2, &cert))
- {
- if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
- cert->has_subject(cert, id))
- {
- success = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- if (!success)
- {
- DBG1(DBG_CFG, "constraint check failed: peer not "
- "authenticated by CA '%D'.", id);
- }
- break;
- }
- case AUTHZ_PUBKEY:
- case AUTHZ_PSK:
- case AUTHZ_IM_CERT:
- case AUTHZ_SUBJECT_CERT:
- case AUTHZ_EAP:
- case AUTHZ_AC_GROUP:
- {
- DBG1(DBG_CFG, "constraint check %N not implemented!",
- auth_item_names, t1);
- success = FALSE;
- break;
- }
- }
- if (!success)
- {
- break;
- }
- }
- enumerator->destroy(enumerator);
- return success;
-}
-
-/**
- * Implementation of auth_info_t.merge.
- */
-static void merge(private_auth_info_t *this, private_auth_info_t *other)
-{
- item_t *item;
-
- while (other->items->remove_first(other->items, (void**)&item) == SUCCESS)
- {
- this->items->insert_last(this->items, item);
- }
-}
-
-/**
- * Implementation of auth_info_t.equals.
- */
-static bool equals(private_auth_info_t *this, private_auth_info_t *other)
-{
- enumerator_t *e1, *e2;
- item_t *i1, *i2;
- bool equal = TRUE, found;
-
- e1 = this->items->create_enumerator(this->items);
- while (e1->enumerate(e1, &i1))
- {
- found = FALSE;
- e2 = other->items->create_enumerator(other->items);
- while (e2->enumerate(e2, &i2))
- {
- if (i1->type == i2->type)
- {
- switch (i1->type)
- {
- case AUTHZ_CRL_VALIDATION:
- case AUTHZ_OCSP_VALIDATION:
- {
- cert_validation_t c1, c2;
-
- c1 = *(cert_validation_t*)i1->value;
- c2 = *(cert_validation_t*)i2->value;
-
- if (c1 == c2)
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTHN_IM_HASH_URL:
- case AUTHN_SUBJECT_HASH_URL:
- {
- if (streq(i1->value, i2->value))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTHN_CA_CERT:
- case AUTHN_IM_CERT:
- case AUTHN_SUBJECT_CERT:
- case AUTHZ_CA_CERT:
- case AUTHZ_IM_CERT:
- case AUTHZ_SUBJECT_CERT:
- {
- certificate_t *c1, *c2;
-
- c1 = (certificate_t*)i1->value;
- c2 = (certificate_t*)i2->value;
-
- if (c1->equals(c1, c2))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTHN_EAP_IDENTITY:
- case AUTHN_CA_CERT_KEYID:
- case AUTHN_CA_CERT_NAME:
- case AUTHZ_CA_CERT_NAME:
- {
- identification_t *c1, *c2;
-
- c1 = (identification_t*)i1->value;
- c2 = (identification_t*)i2->value;
-
- if (c1->equals(c1, c2))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTHN_AUTH_CLASS:
- case AUTHN_EAP_TYPE:
- case AUTHN_EAP_VENDOR:
- {
- if (*(u_int*)i1->value == *(u_int*)i2->value)
- {
- found = TRUE;
- break;
- }
- }
- case AUTHZ_PUBKEY:
- case AUTHZ_PSK:
- case AUTHZ_EAP:
- case AUTHZ_AC_GROUP:
- /* TODO: implement value comparison */
- break;
- }
- break;
- }
- }
- e2->destroy(e2);
- if (!found)
- {
- equal = FALSE;
- break;
- }
- }
- e1->destroy(e1);
- return equal;
-}
-
-/**
- * Destroy the value associated with an item
- */
-static void destroy_item_value(item_t *item)
-{
- switch (item->type)
- {
- case AUTHZ_PUBKEY:
- {
- public_key_t *key = (public_key_t*)item->value;
- key->destroy(key);
- break;
- }
- case AUTHZ_PSK:
- {
- shared_key_t *key = (shared_key_t*)item->value;
- key->destroy(key);
- break;
- }
- case AUTHN_CA_CERT:
- case AUTHN_IM_CERT:
- case AUTHN_SUBJECT_CERT:
- case AUTHZ_CA_CERT:
- case AUTHZ_IM_CERT:
- case AUTHZ_SUBJECT_CERT:
- {
- certificate_t *cert = (certificate_t*)item->value;
- cert->destroy(cert);
- break;
- }
- case AUTHN_AUTH_CLASS:
- case AUTHN_EAP_TYPE:
- case AUTHN_EAP_VENDOR:
- case AUTHN_IM_HASH_URL:
- case AUTHN_SUBJECT_HASH_URL:
- case AUTHZ_CRL_VALIDATION:
- case AUTHZ_OCSP_VALIDATION:
- case AUTHZ_EAP:
- {
- free(item->value);
- break;
- }
- case AUTHN_EAP_IDENTITY:
- case AUTHN_CA_CERT_KEYID:
- case AUTHN_CA_CERT_NAME:
- case AUTHZ_CA_CERT_NAME:
- case AUTHZ_AC_GROUP:
- {
- identification_t *id = (identification_t*)item->value;
- id->destroy(id);
- break;
- }
- }
-}
-
-/**
- * Implementation of auth_info_t.purge
- */
-static void purge(private_auth_info_t *this)
-{
- item_t *item;
-
- while (this->items->remove_last(this->items, (void**)&item) == SUCCESS)
- {
- destroy_item_value(item);
- free(item);
- }
-}
-
-/**
- * Implementation of auth_info_t.destroy
- */
-static void destroy(private_auth_info_t *this)
-{
- purge(this);
- this->items->destroy(this->items);
- free(this);
-}
-
-/*
- * see header file
- */
-auth_info_t *auth_info_create()
-{
- private_auth_info_t *this = malloc_thing(private_auth_info_t);
-
- this->public.add_item = (void(*)(auth_info_t*, auth_item_t type, void *value))add_item;
- this->public.get_item = (bool(*)(auth_info_t*, auth_item_t type, void **value))get_item;
- this->public.replace_item = (void(*)(enumerator_t*,auth_item_t,void*))replace_item;
- this->public.create_item_enumerator = (enumerator_t*(*)(auth_info_t*))create_item_enumerator;
- this->public.complies = (bool(*)(auth_info_t*, auth_info_t *))complies;
- this->public.merge = (void(*)(auth_info_t*, auth_info_t *other))merge;
- this->public.purge = (void(*)(auth_info_t*))purge;
- this->public.equals = (bool(*)(auth_info_t*, auth_info_t *other))equals;
- this->public.destroy = (void(*)(auth_info_t*))destroy;
-
- this->items = linked_list_create();
-
- return &this->public;
-}
-
diff --git a/src/charon/credentials/auth_info.h b/src/charon/credentials/auth_info.h
deleted file mode 100644
index f480a6e08..000000000
--- a/src/charon/credentials/auth_info.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-/**
- * @defgroup auth_info auth_info
- * @{ @ingroup ccredentials
- */
-
-#ifndef AUTH_INFO_H_
-#define AUTH_INFO_H_
-
-#include <utils/enumerator.h>
-
-typedef struct auth_info_t auth_info_t;
-typedef enum auth_item_t auth_item_t;
-
-/**
- * Authentication/Authorization process helper item.
- *
- * For the authentication process, further information may be needed. These
- * items are defined as auth_item_t and have a AUTHN prefix.
- * The authentication process returns important data for the authorization
- * process, these items are defined with a AUTHZ prefix.
- * Authentication uses AUTHN items and creates AUTHZ items during authentication,
- * authorization reads AUTHZ values to give out privileges.
- *
- * +---+ +---------------------+
- * | A | | A |
- * | u | | u +-----------+ |
- * | t | | t | Required | |
- * | h | | h | auth_info | |
- * | e | | o +-----------+ |
- * | n | | r | |
- * +-----------+ | t | | i | |
- * | Provided | | i | | z V |
- * | auth_info |--| c |-------------| a ----> match? ----|------->
- * +-----------+ | a | | t |
- * | t | | i |
- * | i | | o |
- * | o | | n |
- * | n | | |
- * +---+ +---------------------+
- */
-enum auth_item_t {
-
- /*
- * items provided to authentication process
- */
-
- /** authentication class to use, value is auth_class_t* */
- AUTHN_AUTH_CLASS,
- /** EAP method to request from peer, value is eap_type_t* */
- AUTHN_EAP_TYPE,
- /** EAP vendor to used in conjunction with EAP method, value is u_int32_t* */
- AUTHN_EAP_VENDOR,
- /** EAP identity to use within EAP-Identity exchange */
- AUTHN_EAP_IDENTITY,
- /** CA certificate to use for authentication, value is certificate_t* */
- AUTHN_CA_CERT,
- /** Keyid of a CA certificate to use, value is identification_t* */
- AUTHN_CA_CERT_KEYID,
- /** subject DN of a CA certificate to use, value is identification_t* */
- AUTHN_CA_CERT_NAME,
- /** intermediate certificate, value is certificate_t* */
- AUTHN_IM_CERT,
- /** certificate for trustchain verification, value is certificate_t* */
- AUTHN_SUBJECT_CERT,
- /** intermediate certificate supplied as hash and url */
- AUTHN_IM_HASH_URL,
- /** end-entity certificate supplied as hash and url */
- AUTHN_SUBJECT_HASH_URL,
-
- /*
- * item provided to authorization process
- */
-
- /** subject has been authenticated by public key, value is public_key_t* */
- AUTHZ_PUBKEY,
- /** subject has ben authenticated using preshared secrets, value is shared_key_t* */
- AUTHZ_PSK,
- /** subject has been authenticated using EAP, value is eap_type_t* */
- AUTHZ_EAP,
- /** certificate authority, value is certificate_t* */
- AUTHZ_CA_CERT,
- /** subject DN of a certificate authority, value is identification_t* */
- AUTHZ_CA_CERT_NAME,
- /** intermediate certificate in trustchain, value is certificate_t* */
- AUTHZ_IM_CERT,
- /** subject certificate, value is certificate_t* */
- AUTHZ_SUBJECT_CERT,
- /** result of a CRL validation, value is cert_validation_t */
- AUTHZ_CRL_VALIDATION,
- /** result of a OCSP validation, value is cert_validation_t */
- AUTHZ_OCSP_VALIDATION,
- /** subject is in attribute certificate group, value is identification_t* */
- AUTHZ_AC_GROUP,
-};
-
-
-/**
- * enum name for auth_item_t.
- */
-extern enum_name_t *auth_item_names;
-
-/**
- * The auth_info class contains auth_item_t's used for AA.
- *
- * A auth_info allows the separation of authentication and authorization.
- */
-struct auth_info_t {
-
- /**
- * Add an item to the set.
- *
- * @param type auth_info type
- * @param value associated value to auth_info type, if any
- */
- void (*add_item)(auth_info_t *this, auth_item_t type, void *value);
-
- /**
- * Get an item.
- *
- * @param type auth_info type to get
- * @param value pointer to a pointer receiving item
- * @return bool if item has been found
- */
- bool (*get_item)(auth_info_t *this, auth_item_t type, void **value);
-
- /**
- * Replace an item.
- *
- * @param type new auth_info type
- * @param value pointer to the new value
- */
- void (*replace_item)(enumerator_t *this, auth_item_t type, void *value);
-
- /**
- * Create an enumerator over all items.
- *
- * @return enumerator over (auth_item_t type, void *value)
- */
- enumerator_t* (*create_item_enumerator)(auth_info_t *this);
-
- /**
- * Check if this fulfills a set of required constraints.
- *
- * @param constraints required authorization infos
- * @return TRUE if this complies with constraints
- */
- bool (*complies)(auth_info_t *this, auth_info_t *constraints);
-
- /**
- * Merge items from other into this.
- *
- * Items do not get cloned, but moved from other to this.
- *
- * @param other items to read for merge
- */
- void (*merge)(auth_info_t *this, auth_info_t *other);
-
- /**
- * Purge all items in auth_info.
- */
- void (*purge)(auth_info_t *this);
-
- /**
- * Check two auth_infos for equality.
- *
- * @param other other item to compaire against this
- * @return TRUE if auth infos identical
- */
- bool (*equals)(auth_info_t *this, auth_info_t *other);
-
- /**
- * Destroy a auth_info instance with all associated values.
- */
- void (*destroy)(auth_info_t *this);
-};
-
-/**
- * Create a auth_info instance.
- */
-auth_info_t *auth_info_create();
-
-#endif /** AUTH_INFO_H_ @}*/
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c
index 2841086b2..776dbe599 100644
--- a/src/charon/credentials/credential_manager.c
+++ b/src/charon/credentials/credential_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: credential_manager.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <pthread.h>
@@ -23,7 +21,7 @@
#include <utils/mutex.h>
#include <utils/linked_list.h>
#include <credentials/sets/cert_cache.h>
-#include <credentials/sets/auth_info_wrapper.h>
+#include <credentials/sets/auth_cfg_wrapper.h>
#include <credentials/sets/ocsp_response_wrapper.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/crl.h>
@@ -530,7 +528,7 @@ static bool verify_ocsp(private_credential_manager_t *this,
{
if (this->cache->issued_by(this->cache, subject, issuer))
{
- DBG1(DBG_CFG, " ocsp response correctly signed by \"%D\"",
+ DBG1(DBG_CFG, " ocsp response correctly signed by \"%Y\"",
issuer->get_subject(issuer));
verified = TRUE;
break;
@@ -625,7 +623,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
*/
static cert_validation_t check_ocsp(private_credential_manager_t *this,
x509_t *subject, x509_t *issuer,
- auth_info_t *auth)
+ auth_cfg_t *auth)
{
enumerator_t *enumerator;
cert_validation_t valid = VALIDATION_SKIPPED;
@@ -706,7 +704,11 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
}
if (auth)
{
- auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
+ auth->add(auth, AUTH_RULE_OCSP_VALIDATION, valid);
+ if (valid == VALIDATION_GOOD)
+ { /* successful OCSP check fulfills also CRL constraint */
+ auth->add(auth, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+ }
}
DESTROY_IF(best);
return valid;
@@ -728,6 +730,7 @@ static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
}
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+ chunk_free(&chunk);
if (!crl)
{
DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
@@ -751,7 +754,7 @@ static bool verify_crl(private_credential_manager_t *this, certificate_t *crl)
{
if (this->cache->issued_by(this->cache, crl, issuer))
{
- DBG1(DBG_CFG, " crl correctly signed by \"%D\"",
+ DBG1(DBG_CFG, " crl correctly signed by \"%Y\"",
issuer->get_subject(issuer));
verified = TRUE;
break;
@@ -833,7 +836,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
*/
static cert_validation_t check_crl(private_credential_manager_t *this,
x509_t *subject, x509_t *issuer,
- auth_info_t *auth)
+ auth_cfg_t *auth)
{
cert_validation_t valid = VALIDATION_SKIPPED;
identification_t *keyid = NULL;
@@ -841,7 +844,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
certificate_t *current;
public_key_t *public;
enumerator_t *enumerator;
- char *uri;
+ char *uri = NULL;
/* derive the authorityKeyIdentifier from the issuer's public key */
current = &issuer->interface;
@@ -920,7 +923,16 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
}
if (auth)
{
- auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+ if (valid == VALIDATION_SKIPPED)
+ { /* if we skipped CRL validation, we use the result of OCSP for
+ * constraint checking */
+ auth->add(auth, AUTH_RULE_CRL_VALIDATION,
+ auth->get(auth, AUTH_RULE_OCSP_VALIDATION));
+ }
+ else
+ {
+ auth->add(auth, AUTH_RULE_CRL_VALIDATION, valid);
+ }
}
DESTROY_IF(best);
return valid;
@@ -931,7 +943,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
*/
static bool check_certificate(private_credential_manager_t *this,
certificate_t *subject, certificate_t *issuer,
- bool crl, bool ocsp, auth_info_t *auth)
+ bool crl, bool ocsp, auth_cfg_t *auth)
{
time_t not_before, not_after;
@@ -952,7 +964,7 @@ static bool check_certificate(private_credential_manager_t *this,
{
if (ocsp || crl)
{
- DBG1(DBG_CFG, "checking certificate status of \"%D\"",
+ DBG1(DBG_CFG, "checking certificate status of \"%Y\"",
subject->get_subject(subject));
}
if (ocsp)
@@ -963,7 +975,7 @@ static bool check_certificate(private_credential_manager_t *this,
DBG1(DBG_CFG, "certificate status is good");
return TRUE;
case VALIDATION_REVOKED:
- /* has already been logged */
+ /* has already been logged */
return FALSE;
case VALIDATION_SKIPPED:
DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
@@ -983,8 +995,8 @@ static bool check_certificate(private_credential_manager_t *this,
case VALIDATION_GOOD:
DBG1(DBG_CFG, "certificate status is good");
return TRUE;
- case VALIDATION_REVOKED:
- /* has already been logged */
+ case VALIDATION_REVOKED:
+ /* has already been logged */
return FALSE;
case VALIDATION_FAILED:
case VALIDATION_SKIPPED:
@@ -1050,14 +1062,14 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this,
* try to verify the trust chain of subject, return TRUE if trusted
*/
static bool verify_trust_chain(private_credential_manager_t *this,
- certificate_t *subject, auth_info_t *result,
+ certificate_t *subject, auth_cfg_t *result,
bool trusted, bool crl, bool ocsp)
{
certificate_t *current, *issuer;
- auth_info_t *auth;
+ auth_cfg_t *auth;
u_int level = 0;
- auth = auth_info_create();
+ auth = auth_cfg_create();
current = subject->get_ref(subject);
while (level++ < MAX_CA_LEVELS)
{
@@ -1067,16 +1079,16 @@ static bool verify_trust_chain(private_credential_manager_t *this,
/* accept only self-signed CAs as trust anchor */
if (this->cache->issued_by(this->cache, issuer, issuer))
{
- auth->add_item(auth, AUTHZ_CA_CERT, issuer);
- DBG1(DBG_CFG, " using trusted ca certificate \"%D\"",
+ auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
+ DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"",
issuer->get_subject(issuer));
trusted = TRUE;
}
else
{
- auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+ auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
DBG1(DBG_CFG, " using trusted intermediate ca certificate "
- "\"%D\"", issuer->get_subject(issuer));
+ "\"%Y\"", issuer->get_subject(issuer));
}
}
else
@@ -1086,18 +1098,18 @@ static bool verify_trust_chain(private_credential_manager_t *this,
{
if (current->equals(current, issuer))
{
- DBG1(DBG_CFG, " self-signed certificate \"%D\" is not trusted",
+ DBG1(DBG_CFG, " self-signed certificate \"%Y\" is not trusted",
current->get_subject(current));
issuer->destroy(issuer);
break;
}
- auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+ auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
DBG1(DBG_CFG, " using untrusted intermediate certificate "
- "\"%D\"", issuer->get_subject(issuer));
+ "\"%Y\"", issuer->get_subject(issuer));
}
else
{
- DBG1(DBG_CFG, "no issuer certificate found for \"%D\"",
+ DBG1(DBG_CFG, "no issuer certificate found for \"%Y\"",
current->get_subject(current));
break;
}
@@ -1123,7 +1135,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
}
if (trusted)
{
- result->merge(result, auth);
+ result->merge(result, auth, FALSE);
}
auth->destroy(auth);
return trusted;
@@ -1149,20 +1161,20 @@ typedef struct {
bool ocsp;
/** pretrusted certificate we have served at first invocation */
certificate_t *pretrusted;
- /** currently enumerating auth info */
- auth_info_t *auth;
+ /** currently enumerating auth config */
+ auth_cfg_t *auth;
} trusted_enumerator_t;
/**
* Implements trusted_enumerator_t.enumerate
*/
static bool trusted_enumerate(trusted_enumerator_t *this,
- certificate_t **cert, auth_info_t **auth)
+ certificate_t **cert, auth_cfg_t **auth)
{
certificate_t *current;
DESTROY_IF(this->auth);
- this->auth = auth_info_create();
+ this->auth = auth_cfg_create();
if (!this->candidates)
{
@@ -1181,8 +1193,9 @@ static bool trusted_enumerate(trusted_enumerator_t *this,
verify_trust_chain(this->this, this->pretrusted, this->auth,
TRUE, this->crl, this->ocsp))
{
- this->auth->add_item(this->auth, AUTHZ_CA_CERT, this->pretrusted);
- DBG1(DBG_CFG, " using trusted certificate \"%D\"",
+ this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT,
+ this->pretrusted->get_ref(this->pretrusted));
+ DBG1(DBG_CFG, " using trusted certificate \"%Y\"",
this->pretrusted->get_subject(this->pretrusted));
*cert = this->pretrusted;
if (auth)
@@ -1202,7 +1215,7 @@ static bool trusted_enumerate(trusted_enumerator_t *this,
continue;
}
- DBG1(DBG_CFG, " using certificate \"%D\"",
+ DBG1(DBG_CFG, " using certificate \"%Y\"",
current->get_subject(current));
if (verify_trust_chain(this->this, current, this->auth, FALSE,
this->crl, this->ocsp))
@@ -1264,15 +1277,15 @@ typedef struct {
private_credential_manager_t *this;
/** currently enumerating key */
public_key_t *current;
- /** credset wrapper around auth */
- auth_info_wrapper_t *wrapper;
+ /** credset wrapper around auth config */
+ auth_cfg_wrapper_t *wrapper;
} public_enumerator_t;
/**
* Implements public_enumerator_t.enumerate
*/
static bool public_enumerate(public_enumerator_t *this,
- public_key_t **key, auth_info_t **auth)
+ public_key_t **key, auth_cfg_t **auth)
{
certificate_t *cert;
@@ -1312,7 +1325,7 @@ static void public_destroy(public_enumerator_t *this)
* Implementation of credential_manager_t.create_public_enumerator.
*/
static enumerator_t* create_public_enumerator(private_credential_manager_t *this,
- key_type_t type, identification_t *id, auth_info_t *auth)
+ key_type_t type, identification_t *id, auth_cfg_t *auth)
{
public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
@@ -1324,7 +1337,7 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
enumerator->wrapper = NULL;
if (auth)
{
- enumerator->wrapper = auth_info_wrapper_create(auth);
+ enumerator->wrapper = auth_cfg_wrapper_create(auth);
add_local_set(this, &enumerator->wrapper->set);
}
this->lock->read_lock(this->lock);
@@ -1334,40 +1347,22 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
/**
* Check if a certificate's keyid is contained in the auth helper
*/
-static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
+static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
{
enumerator_t *enumerator;
identification_t *value;
- auth_item_t type;
+ auth_rule_t type;
bool found = FALSE;
- enumerator = auth->create_item_enumerator(auth);
+ enumerator = auth->create_enumerator(auth);
while (enumerator->enumerate(enumerator, &type, &value))
{
- if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
+ if (type == AUTH_RULE_CA_CERT &&
+ cert->equals(cert, (certificate_t*)value))
{
found = TRUE;
break;
}
- if (type == AUTHN_CA_CERT_KEYID)
- {
- public_key_t *public;
- identification_t *certid, *keyid;
-
- public = cert->get_public_key(cert);
- if (public)
- {
- keyid = (identification_t*)value;
- certid = public->get_id(public, keyid->get_type(keyid));
- if (certid && certid->equals(certid, keyid))
- {
- public->destroy(public);
- found = TRUE;
- break;
- }
- public->destroy(public);
- }
- }
}
enumerator->destroy(enumerator);
return found;
@@ -1376,19 +1371,21 @@ static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
/**
* build a trustchain from subject up to a trust anchor in trusted
*/
-static auth_info_t *build_trustchain(private_credential_manager_t *this,
- certificate_t *subject, auth_info_t *auth)
+static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
+ certificate_t *subject, auth_cfg_t *auth)
{
certificate_t *issuer, *current;
- auth_info_t *trustchain;
+ auth_cfg_t *trustchain;
u_int level = 0;
- trustchain = auth_info_create();
+ trustchain = auth_cfg_create();
- if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&current))
+ current = auth->get(auth, AUTH_RULE_CA_CERT);
+ if (!current)
{
/* no trust anchor specified, return this cert only */
- trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
+ trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT,
+ subject->get_ref(subject));
return trustchain;
}
current = subject->get_ref(subject);
@@ -1396,26 +1393,23 @@ static auth_info_t *build_trustchain(private_credential_manager_t *this,
{
if (auth_contains_cacert(auth, current))
{
- trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
- current->destroy(current);
+ trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
return trustchain;
}
if (subject == current)
{
- trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
+ trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT, current);
}
else
{
- trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
+ trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
}
issuer = get_issuer_cert(this, current, FALSE);
if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
{
DESTROY_IF(issuer);
- current->destroy(current);
break;
}
- current->destroy(current);
current = issuer;
level++;
}
@@ -1451,12 +1445,12 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
*/
static private_key_t *get_private(private_credential_manager_t *this,
key_type_t type, identification_t *id,
- auth_info_t *auth)
+ auth_cfg_t *auth)
{
enumerator_t *enumerator;
certificate_t *cert;
private_key_t *private = NULL;
- auth_info_t *trustchain;
+ auth_cfg_t *trustchain;
/* check if this is a lookup by key ID, and do it if so */
if (id)
@@ -1471,8 +1465,25 @@ static private_key_t *get_private(private_credential_manager_t *this,
break;
}
}
-
- /* try to build a trustchain for each certificate found */
+
+ /* if a specific certificate is preferred, check for a matching key */
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (cert)
+ {
+ private = get_private_by_cert(this, cert, type);
+ if (private)
+ {
+ trustchain = build_trustchain(this, cert, auth);
+ if (trustchain)
+ {
+ auth->merge(auth, trustchain, FALSE);
+ trustchain->destroy(trustchain);
+ }
+ return private;
+ }
+ }
+
+ /* try to build a trust chain for each certificate found */
enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
while (enumerator->enumerate(enumerator, &cert))
{
@@ -1482,7 +1493,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
trustchain = build_trustchain(this, cert, auth);
if (trustchain)
{
- auth->merge(auth, trustchain);
+ auth->merge(auth, trustchain, FALSE);
trustchain->destroy(trustchain);
break;
}
@@ -1491,6 +1502,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
}
}
enumerator->destroy(enumerator);
+
/* if no valid trustchain was found, fall back to the first usable cert */
if (!private)
{
@@ -1500,7 +1512,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
private = get_private_by_cert(this, cert, type);
if (private)
{
- auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
+ auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert));
break;
}
}
@@ -1566,8 +1578,8 @@ credential_manager_t *credential_manager_create()
this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, certificate_type_t type, identification_t *id))create_cdp_enumerator;
this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
- this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_private;
- this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_info_t *aut))create_public_enumerator;
+ this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_cfg_t*))get_private;
+ this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_cfg_t *aut))create_public_enumerator;
this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
this->public.cache_cert = (void(*)(credential_manager_t*, certificate_t *cert))cache_cert;
this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
diff --git a/src/charon/credentials/credential_manager.h b/src/charon/credentials/credential_manager.h
index ff2dc3645..0af54c0b1 100644
--- a/src/charon/credentials/credential_manager.h
+++ b/src/charon/credentials/credential_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Martin Willi
+ * Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: credential_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -25,7 +23,7 @@
#include <utils/identification.h>
#include <utils/enumerator.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
#include <credentials/credential_set.h>
#include <credentials/keys/private_key.h>
#include <credentials/keys/shared_key.h>
@@ -122,7 +120,6 @@ struct credential_manager_t {
* @param type kind of requested shared key
* @param me own identity
* @param other peers identity
- * @param auth auth_info helper
* @return shared_key_t, NULL if none found
*/
shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
@@ -138,11 +135,11 @@ struct credential_manager_t {
*
* @param type type of the key to get
* @param id identification the key belongs to
- * @param auth auth_info helper, including trusted CA certificates
+ * @param auth auth config, including trusted CA certificates
* @return private_key_t, NULL if none found
*/
private_key_t* (*get_private)(credential_manager_t *this, key_type_t type,
- identification_t *id, auth_info_t *auth);
+ identification_t *id, auth_cfg_t *auth);
/**
* Create an enumerator over trusted public keys.
@@ -150,9 +147,8 @@ struct credential_manager_t {
* This method gets a an enumerator over trusted public keys to verify a
* signature created by id. The auth parameter contains additional
* authentication infos, e.g. peer and intermediate certificates.
- * The resulting enumerator enumerates over public_key_t *, auth_info_t *,
- * where the auth info contains gained privileges for the authorization
- * process.
+ * The resulting enumerator enumerates over public_key_t *, auth_cfg_t *,
+ * where the auth config helper contains rules for constraint checks.
*
* @param type type of the key to get
* @param id owner of the key, signer of the signature
@@ -160,7 +156,7 @@ struct credential_manager_t {
* @return enumerator
*/
enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
- key_type_t type, identification_t *id, auth_info_t *auth);
+ key_type_t type, identification_t *id, auth_cfg_t *auth);
/**
* Cache a certificate by invoking cache_cert() on all registerd sets.
diff --git a/src/charon/credentials/credential_set.h b/src/charon/credentials/credential_set.h
index 14b2a8ebd..e9ad99bfd 100644
--- a/src/charon/credentials/credential_set.h
+++ b/src/charon/credentials/credential_set.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: credential_set.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/credentials/sets/auth_info_wrapper.c b/src/charon/credentials/sets/auth_cfg_wrapper.c
index 7ec75be15..b2cf5d960 100644
--- a/src/charon/credentials/sets/auth_info_wrapper.c
+++ b/src/charon/credentials/sets/auth_cfg_wrapper.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2008-2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,42 +12,40 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <daemon.h>
-#include "auth_info_wrapper.h"
+#include "auth_cfg_wrapper.h"
-typedef struct private_auth_info_wrapper_t private_auth_info_wrapper_t;
+typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t;
/**
- * private data of auth_info_wrapper
+ * private data of auth_cfg_wrapper
*/
-struct private_auth_info_wrapper_t {
+struct private_auth_cfg_wrapper_t {
/**
* public functions
*/
- auth_info_wrapper_t public;
+ auth_cfg_wrapper_t public;
/**
* wrapped auth info
*/
- auth_info_t *auth;
+ auth_cfg_t *auth;
};
/**
- * enumerator for auth_info_wrapper_t.create_cert_enumerator()
+ * enumerator for auth_cfg_wrapper_t.create_cert_enumerator()
*/
typedef struct {
/** implements enumerator_t */
enumerator_t public;
- /** inner enumerator from auth_info */
+ /** inner enumerator from auth_cfg */
enumerator_t *inner;
- /** wrapped auth info */
- auth_info_t *auth;
+ /** wrapped auth round */
+ auth_cfg_t *auth;
/** enumerated cert type */
certificate_type_t cert;
/** enumerated key type */
@@ -57,10 +55,11 @@ typedef struct {
} wrapper_enumerator_t;
/**
- * Tries to fetch a certificate that was supplied as "Hash and URL" (replaces the
- * item's type and value in place).
+ * Tries to fetch a certificate that was supplied as "Hash and URL"
+ * (replaces rule type and value in place).
*/
-static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void **value)
+static bool fetch_cert(wrapper_enumerator_t *enumerator,
+ auth_rule_t *rule, void **value)
{
char *url = (char*)*value;
if (!url)
@@ -77,29 +76,38 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
{
DBG1(DBG_CFG, " fetching certificate failed");
/* we set the item to NULL, so we can skip it */
- enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+ enumerator->auth->replace(enumerator->auth, enumerator->inner,
+ *rule, NULL);
return FALSE;
}
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, data, BUILD_END);
+ BUILD_BLOB_ASN1_DER, data, BUILD_END);
free(data.ptr);
if (!cert)
{
DBG1(DBG_CFG, " parsing fetched certificate failed");
/* we set the item to NULL, so we can skip it */
- enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+ enumerator->auth->replace(enumerator->auth, enumerator->inner,
+ *rule, NULL);
return FALSE;
}
- DBG1(DBG_CFG, " fetched certificate \"%D\"", cert->get_subject(cert));
+ DBG1(DBG_CFG, " fetched certificate \"%Y\"", cert->get_subject(cert));
charon->credentials->cache_cert(charon->credentials, cert);
- *type = (*type == AUTHN_IM_HASH_URL) ? AUTHN_IM_CERT : AUTHN_SUBJECT_CERT;
+ if (*rule == AUTH_HELPER_IM_HASH_URL)
+ {
+ *rule = AUTH_HELPER_IM_CERT;
+ }
+ else
+ {
+ *rule = AUTH_HELPER_SUBJECT_CERT;
+ }
*value = cert;
- enumerator->auth->replace_item(enumerator->inner, *type, cert);
-
+ enumerator->auth->replace(enumerator->auth, enumerator->inner,
+ *rule, cert->get_ref(cert));
return TRUE;
}
@@ -108,26 +116,25 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
*/
static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
{
- auth_item_t type;
+ auth_rule_t rule;
certificate_t *current;
public_key_t *public;
- while (this->inner->enumerate(this->inner, &type, &current))
+ while (this->inner->enumerate(this->inner, &rule, &current))
{
- if (type == AUTHN_IM_HASH_URL ||
- type == AUTHN_SUBJECT_HASH_URL)
- {
- if (!fetch_cert(this, &type, (void**)&current))
+ if (rule == AUTH_HELPER_IM_HASH_URL ||
+ rule == AUTH_HELPER_SUBJECT_HASH_URL)
+ { /* on-demand fetching of hash and url certificates */
+ if (!fetch_cert(this, &rule, (void**)&current))
{
continue;
}
}
- else if (type != AUTHN_SUBJECT_CERT &&
- type != AUTHN_IM_CERT)
- {
+ else if (rule != AUTH_HELPER_SUBJECT_CERT &&
+ rule != AUTH_HELPER_IM_CERT)
+ { /* handle only HELPER certificates */
continue;
}
-
if (this->cert != CERT_ANY && this->cert != current->get_type(current))
{ /* CERT type requested, but does not match */
continue;
@@ -164,9 +171,9 @@ static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
}
/**
- * implementation of auth_info_wrapper_t.set.create_cert_enumerator
+ * implementation of auth_cfg_wrapper_t.set.create_cert_enumerator
*/
-static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
+static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
certificate_type_t cert, key_type_t key,
identification_t *id, bool trusted)
{
@@ -181,16 +188,16 @@ static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
enumerator->cert = cert;
enumerator->key = key;
enumerator->id = id;
- enumerator->inner = this->auth->create_item_enumerator(this->auth);
+ enumerator->inner = this->auth->create_enumerator(this->auth);
enumerator->public.enumerate = (void*)enumerate;
enumerator->public.destroy = (void*)wrapper_enumerator_destroy;
return &enumerator->public;
}
/**
- * Implementation of auth_info_wrapper_t.destroy
+ * Implementation of auth_cfg_wrapper_t.destroy
*/
-static void destroy(private_auth_info_wrapper_t *this)
+static void destroy(private_auth_cfg_wrapper_t *this)
{
free(this);
}
@@ -198,16 +205,16 @@ static void destroy(private_auth_info_wrapper_t *this)
/*
* see header file
*/
-auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth)
+auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
{
- private_auth_info_wrapper_t *this = malloc_thing(private_auth_info_wrapper_t);
+ private_auth_cfg_wrapper_t *this = malloc_thing(private_auth_cfg_wrapper_t);
this->public.set.create_private_enumerator = (void*)return_null;
this->public.set.create_cert_enumerator = (void*)create_enumerator;
this->public.set.create_shared_enumerator = (void*)return_null;
this->public.set.create_cdp_enumerator = (void*)return_null;
this->public.set.cache_cert = (void*)nop;
- this->public.destroy = (void(*)(auth_info_wrapper_t*))destroy;
+ this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy;
this->auth = auth;
diff --git a/src/charon/credentials/sets/auth_info_wrapper.h b/src/charon/credentials/sets/auth_cfg_wrapper.h
index 9186715f0..dd5e0fff6 100644
--- a/src/charon/credentials/sets/auth_info_wrapper.h
+++ b/src/charon/credentials/sets/auth_cfg_wrapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,27 +11,25 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
- * @defgroup auth_info_wrapper auth_info_wrapper
+ * @defgroup auth_cfg_wrapper auth_cfg_wrapper
* @{ @ingroup sets
*/
-#ifndef AUTH_INFO_WRAPPER_H_
-#define AUTH_INFO_WRAPPER_H_
+#ifndef AUTH_CFG_WRAPPER_H_
+#define AUTH_CFG_WRAPPER_H_
+#include <config/auth_cfg.h>
#include <credentials/credential_set.h>
-#include <credentials/auth_info.h>
-typedef struct auth_info_wrapper_t auth_info_wrapper_t;
+typedef struct auth_cfg_wrapper_t auth_cfg_wrapper_t;
/**
- * A wrapper around auth_info_t to handle it like a credential set.
+ * A wrapper around auth_cfg_t to handle it as a credential set.
*/
-struct auth_info_wrapper_t {
+struct auth_cfg_wrapper_t {
/**
* implements credential_set_t
@@ -39,17 +37,17 @@ struct auth_info_wrapper_t {
credential_set_t set;
/**
- * Destroy a auth_info_wrapper instance.
+ * Destroy a auth_cfg_wrapper instance.
*/
- void (*destroy)(auth_info_wrapper_t *this);
+ void (*destroy)(auth_cfg_wrapper_t *this);
};
/**
- * Create a auth_info_wrapper instance.
+ * Create a auth_cfg_wrapper instance.
*
* @param auth the wrapped auth info
* @return wrapper around auth
*/
-auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth);
+auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth);
-#endif /** AUTH_INFO_WRAPPER_H_ @}*/
+#endif /** AUTH_CFG_WRAPPER_H_ @}*/
diff --git a/src/charon/credentials/sets/cert_cache.c b/src/charon/credentials/sets/cert_cache.c
index 83ba8263d..907f5072f 100644
--- a/src/charon/credentials/sets/cert_cache.c
+++ b/src/charon/credentials/sets/cert_cache.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "cert_cache.h"
diff --git a/src/charon/credentials/sets/cert_cache.h b/src/charon/credentials/sets/cert_cache.h
index 40e38e913..a2cae367c 100644
--- a/src/charon/credentials/sets/cert_cache.h
+++ b/src/charon/credentials/sets/cert_cache.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/credentials/sets/ocsp_response_wrapper.c b/src/charon/credentials/sets/ocsp_response_wrapper.c
index c4d3a5b0f..e9faec472 100644
--- a/src/charon/credentials/sets/ocsp_response_wrapper.c
+++ b/src/charon/credentials/sets/ocsp_response_wrapper.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "ocsp_response_wrapper.h"
diff --git a/src/charon/credentials/sets/ocsp_response_wrapper.h b/src/charon/credentials/sets/ocsp_response_wrapper.h
index 068035884..8f141f7a1 100644
--- a/src/charon/credentials/sets/ocsp_response_wrapper.h
+++ b/src/charon/credentials/sets/ocsp_response_wrapper.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index 6dcb39a89..c646ef9b4 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -17,7 +17,9 @@
*/
#include <stdio.h>
+#ifdef HAVE_PRCTL
#include <sys/prctl.h>
+#endif
#include <signal.h>
#include <pthread.h>
#include <sys/stat.h>
@@ -178,6 +180,7 @@ static void destroy(private_daemon_t *this)
#ifdef CAPABILITIES
cap_free(this->caps);
#endif /* CAPABILITIES */
+ DESTROY_IF(this->public.traps);
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.kernel_interface);
DESTROY_IF(this->public.scheduler);
@@ -240,8 +243,10 @@ static void kill_daemon(private_daemon_t *this, char *reason)
* drop daemon capabilities
*/
static void drop_capabilities(private_daemon_t *this)
-{
+{
+#ifdef HAVE_PRCTL
prctl(PR_SET_KEEPCAPS, 1);
+#endif
if (setgid(charon->gid) != 0)
{
@@ -314,6 +319,7 @@ static void print_plugins()
int len = 0;
enumerator_t *enumerator;
+ buf[0] = '\0';
enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
while (len < sizeof(buf) && enumerator->enumerate(enumerator, &plugin))
{
@@ -461,7 +467,7 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
initialize_loggers(this, !syslog, levels);
- DBG1(DBG_DMN, "starting charon (strongSwan Version %s)", VERSION);
+ DBG1(DBG_DMN, "Starting IKEv2 charon daemon (strongSwan "VERSION")");
/* load secrets, ca certificates and crls */
this->public.processor = processor_create();
@@ -474,6 +480,7 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
this->public.attributes = attribute_manager_create();
this->public.kernel_interface = kernel_interface_create();
this->public.socket = socket_create();
+ this->public.traps = trap_manager_create();
/* load plugins, further infrastructure may need it */
lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
@@ -481,9 +488,6 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
print_plugins();
- /* create the kernel interfaces */
- this->public.kernel_interface->create_interfaces(this->public.kernel_interface);
-
#ifdef INTEGRITY_TEST
DBG1(DBG_DMN, "integrity test of libstrongswan code");
if (fips_verify_hmac_signature(hmac_key, hmac_signature))
@@ -552,6 +556,7 @@ private_daemon_t *daemon_create(void)
/* NULL members for clean destruction */
this->public.socket = NULL;
this->public.ike_sa_manager = NULL;
+ this->public.traps = NULL;
this->public.credentials = NULL;
this->public.backends = NULL;
this->public.attributes = NULL;
@@ -604,6 +609,48 @@ private_daemon_t *daemon_create(void)
}
/**
+ * Check/create PID file, return TRUE if already running
+ */
+static bool check_pidfile()
+{
+ struct stat stb;
+ FILE *file;
+
+ if (stat(PID_FILE, &stb) == 0)
+ {
+ file = fopen(PID_FILE, "r");
+ if (file)
+ {
+ char buf[64];
+ pid_t pid = 0;
+
+ memset(buf, 0, sizeof(buf));
+ if (fread(buf, 1, sizeof(buf), file))
+ {
+ pid = atoi(buf);
+ }
+ fclose(file);
+ if (pid && kill(pid, 0) == 0)
+ { /* such a process is running */
+ return TRUE;
+ }
+ }
+ DBG1(DBG_DMN, "removing pidfile '"PID_FILE"', process not running");
+ unlink(PID_FILE);
+ }
+
+ /* create new pidfile */
+ file = fopen(PID_FILE, "w");
+ if (file)
+ {
+ fprintf(file, "%d\n", getpid());
+ ignore_result(fchown(fileno(file), charon->uid, charon->gid));
+ fclose(file);
+ }
+ return FALSE;
+}
+
+/**
* print command line usage and exit
*/
static void usage(const char *msg)
@@ -631,10 +678,7 @@ static void usage(const char *msg)
int main(int argc, char *argv[])
{
bool use_syslog = FALSE;
-
private_daemon_t *private_charon;
- FILE *pid_file;
- struct stat stb;
level_t levels[DBG_MAX];
int group;
@@ -715,21 +759,13 @@ int main(int argc, char *argv[])
destroy(private_charon);
exit(-1);
}
-
- /* check/setup PID file */
- if (stat(PID_FILE, &stb) == 0)
+
+ if (check_pidfile())
{
DBG1(DBG_DMN, "charon already running (\""PID_FILE"\" exists)");
destroy(private_charon);
exit(-1);
}
- pid_file = fopen(PID_FILE, "w");
- if (pid_file)
- {
- fprintf(pid_file, "%d\n", getpid());
- ignore_result(fchown(fileno(pid_file), charon->uid, charon->gid));
- fclose(pid_file);
- }
/* drop the capabilities we won't need */
drop_capabilities(private_charon);
diff --git a/src/charon/daemon.h b/src/charon/daemon.h
index d70a88010..023bae447 100644
--- a/src/charon/daemon.h
+++ b/src/charon/daemon.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: daemon.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -159,6 +157,7 @@ typedef struct daemon_t daemon_t;
#include <bus/listeners/file_logger.h>
#include <bus/listeners/sys_logger.h>
#include <sa/ike_sa_manager.h>
+#include <sa/trap_manager.h>
#include <config/backend_manager.h>
#include <config/attributes/attribute_manager.h>
#include <credentials/credential_manager.h>
@@ -205,13 +204,18 @@ struct daemon_t {
* A socket_t instance.
*/
socket_t *socket;
-
+
/**
* A ike_sa_manager_t instance.
*/
ike_sa_manager_t *ike_sa_manager;
/**
+ * Manager for triggering policies, called traps
+ */
+ trap_manager_t *traps;
+
+ /**
* Manager for the different configuration backends.
*/
backend_manager_t *backends;
diff --git a/src/charon/encoding/generator.c b/src/charon/encoding/generator.c
index dea4f0e21..406cfc688 100644
--- a/src/charon/encoding/generator.c
+++ b/src/charon/encoding/generator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: generator.c 4702 2008-11-26 10:42:54Z martin $
*/
#include <stdlib.h>
@@ -21,7 +19,6 @@
#include <arpa/inet.h>
#include <stdio.h>
-
#include "generator.h"
#include <library.h>
@@ -61,26 +58,26 @@ struct private_generator_t {
* Buffer used to generate the data into.
*/
u_int8_t *buffer;
-
+
/**
* Current write position in buffer (one byte aligned).
*/
u_int8_t *out_position;
-
+
/**
* Position of last byte in buffer.
*/
u_int8_t *roof_position;
-
+
/**
* Current bit writing to in current byte (between 0 and 7).
*/
- size_t current_bit;
-
+ u_int8_t current_bit;
+
/**
* Associated data struct to read informations from.
*/
- void * data_struct;
+ void *data_struct;
/*
* Last payload length position offset in the buffer.
@@ -115,7 +112,7 @@ struct private_generator_t {
/**
* Get size of current buffer in bytes.
*/
-static size_t get_current_buffer_size(private_generator_t *this)
+static int get_size(private_generator_t *this)
{
return this->roof_position - this->buffer;
}
@@ -123,7 +120,7 @@ static size_t get_current_buffer_size(private_generator_t *this)
/**
* Get free space of current buffer in bytes.
*/
-static size_t get_current_buffer_space(private_generator_t *this)
+static int get_space(private_generator_t *this)
{
return this->roof_position - this->out_position;
}
@@ -131,7 +128,7 @@ static size_t get_current_buffer_space(private_generator_t *this)
/**
* Get length of data in buffer (in bytes).
*/
-static size_t get_current_data_length(private_generator_t *this)
+static int get_length(private_generator_t *this)
{
return this->out_position - this->buffer;
}
@@ -139,7 +136,7 @@ static size_t get_current_data_length(private_generator_t *this)
/**
* Get current offset in buffer (in bytes).
*/
-static u_int32_t get_current_buffer_offset(private_generator_t *this)
+static u_int32_t get_offset(private_generator_t *this)
{
return this->out_position - this->buffer;
}
@@ -147,21 +144,20 @@ static u_int32_t get_current_buffer_offset(private_generator_t *this)
/**
* Makes sure enough space is available in buffer to store amount of bits.
*/
-static void make_space_available (private_generator_t *this, size_t bits)
+static void make_space_available(private_generator_t *this, int bits)
{
- while ((get_current_buffer_space(this) * 8 - this->current_bit) < bits)
+ while ((get_space(this) * 8 - this->current_bit) < bits)
{
- /* must increase buffer */
- size_t old_buffer_size = get_current_buffer_size(this);
- size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
- size_t out_position_offset = ((this->out_position) - (this->buffer));
-
- DBG2(DBG_ENC, "increased gen buffer from %d to %d byte",
+ int old_buffer_size, new_buffer_size, out_position_offset;
+
+ old_buffer_size = get_size(this);
+ new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
+ out_position_offset = this->out_position - this->buffer;
+
+ DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
old_buffer_size, new_buffer_size);
- /* Reallocate space for new buffer */
this->buffer = realloc(this->buffer,new_buffer_size);
-
this->out_position = (this->buffer + out_position_offset);
this->roof_position = (this->buffer + new_buffer_size);
}
@@ -170,11 +166,11 @@ static void make_space_available (private_generator_t *this, size_t bits)
/**
* Writes a specific amount of byte into the buffer.
*/
-static void write_bytes_to_buffer(private_generator_t *this, void * bytes,
- size_t number_of_bytes)
+static void write_bytes_to_buffer(private_generator_t *this, void *bytes,
+ int number_of_bytes)
{
int i;
- u_int8_t *read_position = (u_int8_t *) bytes;
+ u_int8_t *read_position = (u_int8_t *)bytes;
make_space_available(this, number_of_bytes * 8);
@@ -189,18 +185,19 @@ static void write_bytes_to_buffer(private_generator_t *this, void * bytes,
/**
* Writes a specific amount of byte into the buffer at a specific offset.
*/
-static void write_bytes_to_buffer_at_offset (private_generator_t *this,
- void *bytes, size_t number_of_bytes, u_int32_t offset)
+static void write_bytes_to_buffer_at_offset(private_generator_t *this,
+ void *bytes, int number_of_bytes, u_int32_t offset)
{
int i;
- u_int8_t *read_position = (u_int8_t *) bytes;
+ u_int8_t *read_position = (u_int8_t *)bytes;
u_int8_t *write_position;
- u_int32_t free_space_after_offset = get_current_buffer_size(this) - offset;
-
+ u_int32_t free_space_after_offset = get_size(this) - offset;
+
/* check first if enough space for new data is available */
if (number_of_bytes > free_space_after_offset)
{
- make_space_available(this, (number_of_bytes - free_space_after_offset) * 8);
+ make_space_available(this,
+ (number_of_bytes - free_space_after_offset) * 8);
}
write_position = this->buffer + offset;
@@ -214,98 +211,83 @@ static void write_bytes_to_buffer_at_offset (private_generator_t *this,
/**
* Generates a U_INT-Field type and writes it to buffer.
- *
- * @param this private_generator_t object
- * @param int_type type of U_INT field (U_INT_4, U_INT_8, etc.)
- * ATTRIBUTE_TYPE is also generated in this function
- * @param offset offset of value in data struct
- * @param generator_contexts generator_contexts_t object where the context is written or read from
*/
static void generate_u_int_type(private_generator_t *this,
encoding_type_t int_type,u_int32_t offset)
{
- size_t number_of_bits = 0;
-
- /* find out number of bits of each U_INT type to check for enough space
- in buffer */
+ int number_of_bits = 0;
+
+ /* find out number of bits of each U_INT type to check for enough space */
switch (int_type)
{
- case U_INT_4:
- number_of_bits = 4;
- break;
- case TS_TYPE:
- case U_INT_8:
- number_of_bits = 8;
- break;
- case U_INT_16:
- case CONFIGURATION_ATTRIBUTE_LENGTH:
- number_of_bits = 16;
- break;
- case U_INT_32:
- number_of_bits = 32;
- break;
- case U_INT_64:
- number_of_bits = 64;
- break;
- case ATTRIBUTE_TYPE:
- number_of_bits = 15;
- break;
- case IKE_SPI:
- number_of_bits = 64;
- break;
-
- default:
+ case U_INT_4:
+ number_of_bits = 4;
+ break;
+ case TS_TYPE:
+ case U_INT_8:
+ number_of_bits = 8;
+ break;
+ case U_INT_16:
+ case CONFIGURATION_ATTRIBUTE_LENGTH:
+ number_of_bits = 16;
+ break;
+ case U_INT_32:
+ number_of_bits = 32;
+ break;
+ case ATTRIBUTE_TYPE:
+ number_of_bits = 15;
+ break;
+ case IKE_SPI:
+ number_of_bits = 64;
+ break;
+ default:
DBG1(DBG_ENC, "U_INT Type %N is not supported",
encoding_type_names, int_type);
-
return;
}
- /* U_INT Types of multiple then 8 bits must be aligned */
- if (((number_of_bits % 8) == 0) && (this->current_bit != 0))
+ if ((number_of_bits % 8) == 0 && this->current_bit != 0)
{
DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
encoding_type_names, int_type);
- /* current bit has to be zero for values multiple of 8 bits */
return;
}
- /* make sure enough space is available in buffer */
make_space_available(this, number_of_bits);
- /* now handle each u int type differently */
switch (int_type)
{
case U_INT_4:
{
+ u_int8_t high, low;
+
if (this->current_bit == 0)
{
- /* highval of current byte in buffer has to be set to the new value*/
- u_int8_t high_val = *((u_int8_t *)(this->data_struct + offset)) << 4;
- /* lowval in buffer is not changed */
- u_int8_t low_val = *(this->out_position) & 0x0F;
- /* highval is set, low_val is not changed */
- *(this->out_position) = high_val | low_val;
+ /* high of current byte in buffer has to be set to the new value*/
+ high = *((u_int8_t *)(this->data_struct + offset)) << 4;
+ /* low in buffer is not changed */
+ low = *(this->out_position) & 0x0F;
+ /* high is set, low_val is not changed */
+ *(this->out_position) = high | low;
DBG3(DBG_ENC, " => %d", *(this->out_position));
/* write position is not changed, just bit position is moved */
this->current_bit = 4;
}
else if (this->current_bit == 4)
{
- /* highval in buffer is not changed */
- u_int high_val = *(this->out_position) & 0xF0;
- /* lowval of current byte in buffer has to be set to the new value*/
- u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
- *(this->out_position) = high_val | low_val;
+ /* high in buffer is not changed */
+ high = *(this->out_position) & 0xF0;
+ /* low of current byte in buffer has to be set to the new value*/
+ low = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
+ *(this->out_position) = high | low;
DBG3(DBG_ENC, " => %d", *(this->out_position));
this->out_position++;
this->current_bit = 0;
-
}
else
{
DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
/* 4 Bit integers must have a 4 bit alignment */
return;
- };
+ }
break;
}
case TS_TYPE:
@@ -316,31 +298,31 @@ static void generate_u_int_type(private_generator_t *this,
DBG3(DBG_ENC, " => %d", *(this->out_position));
this->out_position++;
break;
-
}
case ATTRIBUTE_TYPE:
{
- /* attribute type must not change first bit uf current byte ! */
+ u_int8_t attribute_format_flag;
+ u_int16_t val;
+
+ /* attribute type must not change first bit of current byte */
if (this->current_bit != 1)
{
DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
- /* first bit has to be set! */
return;
}
- /* get value of attribute format flag */
- u_int8_t attribute_format_flag = *(this->out_position) & 0x80;
+ attribute_format_flag = *(this->out_position) & 0x80;
/* get attribute type value as 16 bit integer*/
- u_int16_t int16_val = *((u_int16_t*)(this->data_struct + offset));
+ val = *((u_int16_t*)(this->data_struct + offset));
/* unset most significant bit */
- int16_val &= 0x7FFF;
+ val &= 0x7FFF;
if (attribute_format_flag)
{
- int16_val |= 0x8000;
+ val |= 0x8000;
}
- int16_val = htons(int16_val);
- DBG3(DBG_ENC, " => %d", int16_val);
- /* write bytes to buffer (set bit is overwritten)*/
- write_bytes_to_buffer(this, &int16_val, sizeof(u_int16_t));
+ val = htons(val);
+ DBG3(DBG_ENC, " => %d", val);
+ /* write bytes to buffer (set bit is overwritten) */
+ write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
this->current_bit = 0;
break;
@@ -348,37 +330,25 @@ static void generate_u_int_type(private_generator_t *this,
case U_INT_16:
case CONFIGURATION_ATTRIBUTE_LENGTH:
{
- u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset)));
- DBG3(DBG_ENC, " => %b", (void*)&int16_val, sizeof(int16_val));
- write_bytes_to_buffer(this, &int16_val, sizeof(u_int16_t));
+ u_int16_t val = htons(*((u_int16_t*)(this->data_struct + offset)));
+ DBG3(DBG_ENC, " => %b", &val, sizeof(u_int16_t));
+ write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
break;
}
case U_INT_32:
{
- u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset)));
- DBG3(DBG_ENC, " => %b", (void*)&int32_val, sizeof(int32_val));
- write_bytes_to_buffer(this, &int32_val, sizeof(u_int32_t));
+ u_int32_t val = htonl(*((u_int32_t*)(this->data_struct + offset)));
+ DBG3(DBG_ENC, " => %b", &val, sizeof(u_int32_t));
+ write_bytes_to_buffer(this, &val, sizeof(u_int32_t));
break;
}
- case U_INT_64:
- {
- /* 64 bit integers are written as two 32 bit integers */
- u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset)));
- u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1));
- DBG3(DBG_ENC, " => %b %b",
- (void*)&int32_val_low, sizeof(int32_val_low),
- (void*)&int32_val_high, sizeof(int32_val_high));
- /* TODO add support for big endian machines */
- write_bytes_to_buffer(this, &int32_val_high, sizeof(u_int32_t));
- write_bytes_to_buffer(this, &int32_val_low, sizeof(u_int32_t));
- break;
- }
-
case IKE_SPI:
{
- /* 64 bit are written as they come :-) */
- write_bytes_to_buffer(this, this->data_struct + offset, sizeof(u_int64_t));
- DBG3(DBG_ENC, " => %b", (void*)(this->data_struct + offset), sizeof(u_int64_t));
+ /* 64 bit are written as-is, no host order conversion */
+ write_bytes_to_buffer(this, this->data_struct + offset,
+ sizeof(u_int64_t));
+ DBG3(DBG_ENC, " => %b", this->data_struct + offset,
+ sizeof(u_int64_t));
break;
}
default:
@@ -396,18 +366,17 @@ static void generate_u_int_type(private_generator_t *this,
static void generate_reserved_field(private_generator_t *this, int bits)
{
/* only one bit or 8 bit fields are supported */
- if ((bits != 1) && (bits != 8))
+ if (bits != 1 && bits != 8)
{
DBG1(DBG_ENC, "reserved field of %d bits cannot be generated", bits);
return ;
}
- /* make sure enough space is available in buffer */
make_space_available(this, bits);
if (bits == 1)
- {
- /* one bit processing */
+ {
u_int8_t reserved_bit = ~(1 << (7 - this->current_bit));
+
*(this->out_position) = *(this->out_position) & reserved_bit;
if (this->current_bit == 0)
{
@@ -423,7 +392,6 @@ static void generate_reserved_field(private_generator_t *this, int bits)
}
else
{
- /* one byte processing*/
if (this->current_bit > 0)
{
DBG1(DBG_ENC, "reserved field cannot be written cause "
@@ -440,12 +408,9 @@ static void generate_reserved_field(private_generator_t *this, int bits)
*/
static void generate_flag(private_generator_t *this, u_int32_t offset)
{
- /* value of current flag */
u_int8_t flag_value;
- /* position of flag in current byte */
u_int8_t flag;
- /* if the value in the data_struct is TRUE, flag_value is set to 1, 0 otherwise */
flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
/* get flag position */
flag = (flag_value << (7 - this->current_bit));
@@ -457,12 +422,10 @@ static void generate_flag(private_generator_t *this, u_int32_t offset)
/* memory must be zero */
*(this->out_position) = 0x00;
}
-
- *(this->out_position) = *(this->out_position) | flag;
+ *(this->out_position) = *(this->out_position) | flag;
+ DBG3(DBG_ENC, " => %d", *this->out_position);
- DBG3(DBG_ENC, " => %d", *(this->out_position));
-
this->current_bit++;
if (this->current_bit >= 8)
{
@@ -476,42 +439,42 @@ static void generate_flag(private_generator_t *this, u_int32_t offset)
*/
static void generate_from_chunk(private_generator_t *this, u_int32_t offset)
{
+ chunk_t *value;
+
if (this->current_bit != 0)
{
DBG1(DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
return ;
}
- /* position in buffer */
- chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset);
-
- DBG3(DBG_ENC, " => %B", attribute_value);
+ value = (chunk_t *)(this->data_struct + offset);
+ DBG3(DBG_ENC, " => %B", value);
- /* use write_bytes_to_buffer function to do the job */
- write_bytes_to_buffer(this, attribute_value->ptr, attribute_value->len);
+ write_bytes_to_buffer(this, value->ptr, value->len);
}
/**
* Implementation of private_generator_t.write_to_chunk.
*/
-static void write_to_chunk (private_generator_t *this,chunk_t *data)
+static void write_to_chunk(private_generator_t *this,chunk_t *data)
{
- size_t data_length = get_current_data_length(this);
+ int data_length = get_length(this);
u_int32_t header_length_field = data_length;
/* write length into header length field */
if (this->header_length_position_offset > 0)
{
- u_int32_t int32_val = htonl(header_length_field);
- write_bytes_to_buffer_at_offset(this, &int32_val, sizeof(u_int32_t),
+ u_int32_t val = htonl(header_length_field);
+ write_bytes_to_buffer_at_offset(this, &val, sizeof(u_int32_t),
this->header_length_position_offset);
}
-
+
if (this->current_bit > 0)
- data_length++;
- data->ptr = malloc(data_length);
- memcpy(data->ptr,this->buffer,data_length);
- data->len = data_length;
+ {
+ data_length++;
+ }
+ *data = chunk_alloc(data_length);
+ memcpy(data->ptr, this->buffer, data_length);
DBG3(DBG_ENC, "generated data of this generator %B", data);
}
@@ -521,26 +484,24 @@ static void write_to_chunk (private_generator_t *this,chunk_t *data)
*/
static void generate_payload (private_generator_t *this,payload_t *payload)
{
- int i;
- this->data_struct = payload;
+ int i, offset_start;
size_t rule_count;
encoding_rule_t *rules;
payload_type_t payload_type;
- u_int8_t *payload_start;
- /* get payload type */
+ this->data_struct = payload;
payload_type = payload->get_type(payload);
/* spi size has to get reseted */
this->last_spi_size = 0;
- payload_start = this->out_position;
+ offset_start = this->out_position - this->buffer;
DBG2(DBG_ENC, "generating payload of type %N",
payload_type_names, payload_type);
/* each payload has its own encoding rules */
- payload->get_encoding_rules(payload,&rules,&rule_count);
-
+ payload->get_encoding_rules(payload, &rules, &rule_count);
+
for (i = 0; i < rule_count;i++)
{
DBG2(DBG_ENC, " generating rule %d %N",
@@ -551,13 +512,12 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
case U_INT_8:
case U_INT_16:
case U_INT_32:
- case U_INT_64:
case IKE_SPI:
case TS_TYPE:
case ATTRIBUTE_TYPE:
case CONFIGURATION_ATTRIBUTE_LENGTH:
{
- generate_u_int_type(this, rules[i].type,rules[i].offset);
+ generate_u_int_type(this, rules[i].type, rules[i].offset);
break;
}
case RESERVED_BIT:
@@ -577,35 +537,28 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
}
case PAYLOAD_LENGTH:
{
- /* position of payload lenght field is temporary stored */
- this->last_payload_length_position_offset = get_current_buffer_offset(this);
- /* payload length is generated like an U_INT_16 */
+ this->last_payload_length_position_offset = get_offset(this);
generate_u_int_type(this, U_INT_16,rules[i].offset);
break;
}
case HEADER_LENGTH:
{
- /* position of header length field is temporary stored */
- this->header_length_position_offset = get_current_buffer_offset(this);
- /* header length is generated like an U_INT_32 */
+ this->header_length_position_offset = get_offset(this);
generate_u_int_type(this ,U_INT_32, rules[i].offset);
break;
}
case SPI_SIZE:
- /* spi size is handled as 8 bit unsigned integer */
generate_u_int_type(this, U_INT_8, rules[i].offset);
- /* last spi size is temporary stored */
- this->last_spi_size = *((u_int8_t *)(this->data_struct + rules[i].offset));
+ this->last_spi_size = *((u_int8_t *)(this->data_struct +
+ rules[i].offset));
break;
case ADDRESS:
{
- /* the Address value is generated from chunk */
generate_from_chunk(this, rules[i].offset);
break;
}
case SPI:
{
- /* the SPI value is generated from chunk */
generate_from_chunk(this, rules[i].offset);
break;
}
@@ -625,14 +578,15 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
u_int16_t length_of_payload;
u_int16_t header_length = 0;
u_int16_t length_in_network_order;
-
+
switch(rules[i].type)
{
case KEY_EXCHANGE_DATA:
header_length = KE_PAYLOAD_HEADER_LENGTH;
break;
case NOTIFICATION_DATA:
- header_length = NOTIFY_PAYLOAD_HEADER_LENGTH + this->last_spi_size ;
+ header_length = NOTIFY_PAYLOAD_HEADER_LENGTH +
+ this->last_spi_size;
break;
case NONCE_DATA:
header_length = NONCE_PAYLOAD_HEADER_LENGTH;
@@ -664,47 +618,42 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
default:
break;
}
-
- /* the data value is generated from chunk */
generate_from_chunk(this, rules[i].offset);
- payload_length_position_offset = this->last_payload_length_position_offset;
+ payload_length_position_offset =
+ this->last_payload_length_position_offset;
+ length_of_payload = header_length +
+ ((chunk_t *)(this->data_struct + rules[i].offset))->len;
- /* Length of payload is calculated */
- length_of_payload = header_length + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
-
- length_in_network_order = htons(length_of_payload);
+ length_in_network_order = htons(length_of_payload);
write_bytes_to_buffer_at_offset(this, &length_in_network_order,
- sizeof(u_int16_t),payload_length_position_offset);
+ sizeof(u_int16_t), payload_length_position_offset);
break;
}
case PROPOSALS:
{
- /* before iterative generate the transforms, store the current payload length position */
- u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
+ u_int32_t payload_length_position_offset =
+ this->last_payload_length_position_offset;
/* Length of SA_PAYLOAD is calculated */
u_int16_t length_of_sa_payload = SA_PAYLOAD_HEADER_LENGTH;
u_int16_t int16_val;
- /* proposals are stored in a linked list and so accessed */
- linked_list_t *proposals = *((linked_list_t **)(this->data_struct + rules[i].offset));
+ linked_list_t *proposals = *((linked_list_t **)
+ (this->data_struct + rules[i].offset));
iterator_t *iterator;
payload_t *current_proposal;
- /* create forward iterator */
iterator = proposals->create_iterator(proposals,TRUE);
- /* every proposal is processed (iterative call )*/
while (iterator->iterate(iterator, (void**)&current_proposal))
{
u_int32_t before_generate_position_offset;
u_int32_t after_generate_position_offset;
- before_generate_position_offset = get_current_buffer_offset(this);
- this->public.generate_payload(&(this->public),current_proposal);
- after_generate_position_offset = get_current_buffer_offset(this);
-
- /* increase size of transform */
- length_of_sa_payload += (after_generate_position_offset - before_generate_position_offset);
+ before_generate_position_offset = get_offset(this);
+ generate_payload(this, current_proposal);
+ after_generate_position_offset = get_offset(this);
+ length_of_sa_payload += (after_generate_position_offset -
+ before_generate_position_offset);
}
iterator->destroy(iterator);
@@ -715,60 +664,61 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
}
case TRANSFORMS:
{
- /* before iterative generate the transforms, store the current length position */
- u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
- u_int16_t length_of_proposal = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH + this->last_spi_size;
+ u_int32_t payload_length_position_offset =
+ this->last_payload_length_position_offset;
+ u_int16_t length_of_proposal =
+ PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH + this->last_spi_size;
u_int16_t int16_val;
- linked_list_t *transforms = *((linked_list_t **)(this->data_struct + rules[i].offset));
+ linked_list_t *transforms = *((linked_list_t **)
+ (this->data_struct + rules[i].offset));
iterator_t *iterator;
payload_t *current_transform;
- /* create forward iterator */
iterator = transforms->create_iterator(transforms,TRUE);
while (iterator->iterate(iterator, (void**)&current_transform))
{
u_int32_t before_generate_position_offset;
u_int32_t after_generate_position_offset;
- before_generate_position_offset = get_current_buffer_offset(this);
- this->public.generate_payload(&(this->public),current_transform);
- after_generate_position_offset = get_current_buffer_offset(this);
+ before_generate_position_offset = get_offset(this);
+ generate_payload(this, current_transform);
+ after_generate_position_offset = get_offset(this);
- /* increase size of transform */
- length_of_proposal += (after_generate_position_offset - before_generate_position_offset);
+ length_of_proposal += (after_generate_position_offset -
+ before_generate_position_offset);
}
-
iterator->destroy(iterator);
int16_val = htons(length_of_proposal);
write_bytes_to_buffer_at_offset(this, &int16_val,
sizeof(u_int16_t), payload_length_position_offset);
-
break;
}
case TRANSFORM_ATTRIBUTES:
{
- /* before iterative generate the transform attributes, store the current length position */
- u_int32_t transform_length_position_offset = this->last_payload_length_position_offset;
- u_int16_t length_of_transform = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
+ u_int32_t transform_length_position_offset =
+ this->last_payload_length_position_offset;
+ u_int16_t length_of_transform =
+ TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
u_int16_t int16_val;
- linked_list_t *transform_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
+ linked_list_t *transform_attributes =*((linked_list_t **)
+ (this->data_struct + rules[i].offset));
iterator_t *iterator;
payload_t *current_attribute;
- /* create forward iterator */
- iterator = transform_attributes->create_iterator(transform_attributes,TRUE);
+ iterator = transform_attributes->create_iterator(
+ transform_attributes, TRUE);
while (iterator->iterate(iterator, (void**)&current_attribute))
{
u_int32_t before_generate_position_offset;
u_int32_t after_generate_position_offset;
- before_generate_position_offset = get_current_buffer_offset(this);
- this->public.generate_payload(&(this->public),current_attribute);
- after_generate_position_offset = get_current_buffer_offset(this);
+ before_generate_position_offset = get_offset(this);
+ generate_payload(this, current_attribute);
+ after_generate_position_offset = get_offset(this);
- /* increase size of transform */
- length_of_transform += (after_generate_position_offset - before_generate_position_offset);
+ length_of_transform += (after_generate_position_offset -
+ before_generate_position_offset);
}
iterator->destroy(iterator);
@@ -776,32 +726,32 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
int16_val = htons(length_of_transform);
write_bytes_to_buffer_at_offset(this, &int16_val,
sizeof(u_int16_t),transform_length_position_offset);
-
break;
}
case CONFIGURATION_ATTRIBUTES:
{
- /* before iterative generate the configuration attributes, store the current length position */
- u_int32_t configurations_length_position_offset = this->last_payload_length_position_offset;
+ u_int32_t configurations_length_position_offset =
+ this->last_payload_length_position_offset;
u_int16_t length_of_configurations = CP_PAYLOAD_HEADER_LENGTH;
u_int16_t int16_val;
- linked_list_t *configuration_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
+ linked_list_t *configuration_attributes = *((linked_list_t **)
+ (this->data_struct + rules[i].offset));
iterator_t *iterator;
payload_t *current_attribute;
- /* create forward iterator */
- iterator = configuration_attributes->create_iterator(configuration_attributes,TRUE);
+ iterator = configuration_attributes->create_iterator(
+ configuration_attributes,TRUE);
while (iterator->iterate(iterator, (void**)&current_attribute))
{
u_int32_t before_generate_position_offset;
u_int32_t after_generate_position_offset;
- before_generate_position_offset = get_current_buffer_offset(this);
- this->public.generate_payload(&(this->public),current_attribute);
- after_generate_position_offset = get_current_buffer_offset(this);
+ before_generate_position_offset = get_offset(this);
+ generate_payload(this, current_attribute);
+ after_generate_position_offset = get_offset(this);
- /* increase size of transform */
- length_of_configurations += (after_generate_position_offset - before_generate_position_offset);
+ length_of_configurations += after_generate_position_offset -
+ before_generate_position_offset;
}
iterator->destroy(iterator);
@@ -809,14 +759,14 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
int16_val = htons(length_of_configurations);
write_bytes_to_buffer_at_offset(this, &int16_val,
sizeof(u_int16_t),configurations_length_position_offset);
-
break;
}
case ATTRIBUTE_FORMAT:
{
generate_flag(this, rules[i].offset);
/* Attribute format is a flag which is stored in context*/
- this->attribute_format = *((bool *) (this->data_struct + rules[i].offset));
+ this->attribute_format =
+ *((bool *)(this->data_struct + rules[i].offset));
break;
}
@@ -826,7 +776,8 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
{
generate_u_int_type(this, U_INT_16, rules[i].offset);
/* this field hold the length of the attribute */
- this->attribute_length = *((u_int16_t *)(this->data_struct + rules[i].offset));
+ this->attribute_length =
+ *((u_int16_t *)(this->data_struct + rules[i].offset));
}
else
{
@@ -846,30 +797,28 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
}
case TRAFFIC_SELECTORS:
{
- /* before iterative generate the traffic_selectors, store the current payload length position */
- u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
- /* Length of SA_PAYLOAD is calculated */
+ u_int32_t payload_length_position_offset =
+ this->last_payload_length_position_offset;
u_int16_t length_of_ts_payload = TS_PAYLOAD_HEADER_LENGTH;
u_int16_t int16_val;
- /* traffic selectors are stored in a linked list and so accessed */
- linked_list_t *traffic_selectors = *((linked_list_t **)(this->data_struct + rules[i].offset));
+ linked_list_t *traffic_selectors = *((linked_list_t **)
+ (this->data_struct + rules[i].offset));
iterator_t *iterator;
- payload_t *current_traffic_selector_substructure;
+ payload_t *current_tss;
- /* create forward iterator */
- iterator = traffic_selectors->create_iterator(traffic_selectors,TRUE);
- /* every proposal is processed (iterative call )*/
- while (iterator->iterate(iterator, (void **)&current_traffic_selector_substructure))
+ iterator = traffic_selectors->create_iterator(
+ traffic_selectors,TRUE);
+ while (iterator->iterate(iterator, (void **)&current_tss))
{
u_int32_t before_generate_position_offset;
u_int32_t after_generate_position_offset;
-
- before_generate_position_offset = get_current_buffer_offset(this);
- this->public.generate_payload(&(this->public),current_traffic_selector_substructure);
- after_generate_position_offset = get_current_buffer_offset(this);
- /* increase size of transform */
- length_of_ts_payload += (after_generate_position_offset - before_generate_position_offset);
+ before_generate_position_offset = get_offset(this);
+ generate_payload(this, current_tss);
+ after_generate_position_offset = get_offset(this);
+
+ length_of_ts_payload += (after_generate_position_offset -
+ before_generate_position_offset);
}
iterator->destroy(iterator);
@@ -893,7 +842,8 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
DBG2(DBG_ENC, "generating %N payload finished",
payload_type_names, payload_type);
DBG3(DBG_ENC, "generated data for this payload %b",
- payload_start, this->out_position-payload_start);
+ this->buffer + offset_start,
+ this->out_position - this->buffer - offset_start);
}
/**
@@ -916,9 +866,9 @@ generator_t *generator_create()
this = malloc_thing(private_generator_t);
/* initiate public functions */
- this->public.generate_payload = (void(*)(generator_t*, payload_t *)) generate_payload;
+ this->public.generate_payload = (void(*)(generator_t*, payload_t *))generate_payload;
this->public.destroy = (void(*)(generator_t*)) destroy;
- this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *)) write_to_chunk;
+ this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *))write_to_chunk;
/* allocate memory for buffer */
this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE);
diff --git a/src/charon/encoding/generator.h b/src/charon/encoding/generator.h
index 5c8755d04..f6fb8981c 100644
--- a/src/charon/encoding/generator.h
+++ b/src/charon/encoding/generator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: generator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -67,10 +65,10 @@ struct generator_t {
/**
* Writes all generated data of the generator to a chunk.
*
- * @param data chunk to write the data to
+ * @param data chunk to write the data to
*/
void (*write_to_chunk) (generator_t *this,chunk_t *data);
-
+
/**
* Destroys a generator_t object.
*/
diff --git a/src/charon/encoding/message.c b/src/charon/encoding/message.c
index 600fe97d9..7c6fdb499 100644
--- a/src/charon/encoding/message.c
+++ b/src/charon/encoding/message.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: message.c 4339 2008-09-11 11:14:09Z martin $
*/
#include <stdlib.h>
@@ -208,7 +206,7 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
{AUTHENTICATION, 0, 1, TRUE, TRUE},
- {ID_INITIATOR, 1, 1, TRUE, FALSE},
+ {ID_INITIATOR, 0, 1, TRUE, FALSE},
{CERTIFICATE, 0, 4, TRUE, FALSE},
{CERTIFICATE_REQUEST, 0, 1, TRUE, FALSE},
{ID_RESPONDER, 0, 1, TRUE, FALSE},
@@ -217,9 +215,9 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
{TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
{TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
#else
- {SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
- {TRAFFIC_SELECTOR_INITIATOR, 1, 1, TRUE, FALSE},
- {TRAFFIC_SELECTOR_RESPONDER, 1, 1, TRUE, FALSE},
+ {SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
+ {TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
#endif /* ME */
{CONFIGURATION, 0, 1, TRUE, FALSE},
{VENDOR_ID, 0, 10, TRUE, FALSE},
@@ -261,9 +259,9 @@ static payload_rule_t ike_auth_r_payload_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
+ {AUTHENTICATION, 0, 1, TRUE, TRUE},
{CERTIFICATE, 0, 4, TRUE, FALSE},
{ID_RESPONDER, 0, 1, TRUE, FALSE},
- {AUTHENTICATION, 0, 1, TRUE, FALSE},
{SECURITY_ASSOCIATION, 0, 1, TRUE, FALSE},
{TRAFFIC_SELECTOR_INITIATOR, 0, 1, TRUE, FALSE},
{TRAFFIC_SELECTOR_RESPONDER, 0, 1, TRUE, FALSE},
@@ -846,11 +844,11 @@ static host_t * get_destination(private_message_t *this)
}
/**
- * Implementation of message_t.get_payload_iterator.
+ * Implementation of message_t.create_payload_enumerator.
*/
-static iterator_t *get_payload_iterator(private_message_t *this)
+static enumerator_t *create_payload_enumerator(private_message_t *this)
{
- return this->payloads->create_iterator(this->payloads, TRUE);
+ return this->payloads->create_enumerator(this->payloads);
}
/**
@@ -859,10 +857,10 @@ static iterator_t *get_payload_iterator(private_message_t *this)
static payload_t *get_payload(private_message_t *this, payload_type_t type)
{
payload_t *current, *found = NULL;
- iterator_t *iterator;
+ enumerator_t *enumerator;
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = create_payload_enumerator(this);
+ while (enumerator->enumerate(enumerator, &current))
{
if (current->get_type(current) == type)
{
@@ -870,16 +868,42 @@ static payload_t *get_payload(private_message_t *this, payload_type_t type)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return found;
}
/**
+ * Implementation of message_t.get_notify
+ */
+static notify_payload_t* get_notify(private_message_t *this, notify_type_t type)
+{
+ enumerator_t *enumerator;
+ notify_payload_t *notify = NULL;
+ payload_t *payload;
+
+ enumerator = create_payload_enumerator(this);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ if (notify->get_notify_type(notify) == type)
+ {
+ break;
+ }
+ notify = NULL;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return notify;
+}
+
+/**
* get a string representation of the message
*/
static char* get_string(private_message_t *this, char *buf, int len)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
int written;
char *pos = buf;
@@ -898,8 +922,8 @@ static char* get_string(private_message_t *this, char *buf, int len)
pos += written;
len -= written;
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = create_payload_enumerator(this);
+ while (enumerator->enumerate(enumerator, &payload))
{
written = snprintf(pos, len, " %N", payload_type_short_names,
payload->get_type(payload));
@@ -922,7 +946,7 @@ static char* get_string(private_message_t *this, char *buf, int len)
len -= written;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* remove last space */
snprintf(pos, len, " ]");
@@ -1076,7 +1100,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
generator_t *generator;
ike_header_t *ike_header;
payload_t *payload, *next_payload;
- iterator_t *iterator;
+ enumerator_t *enumerator;
status_t status;
chunk_t packet_data;
char str[256];
@@ -1131,21 +1155,20 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id));
ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id));
-
+
generator = generator_create();
payload = (payload_t*)ike_header;
-
/* generate every payload expect last one, this is done later*/
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
- while(iterator->iterate(iterator, (void**)&next_payload))
+ enumerator = create_payload_enumerator(this);
+ while (enumerator->enumerate(enumerator, &next_payload))
{
payload->set_next_type(payload, next_payload->get_type(next_payload));
generator->generate_payload(generator, payload);
payload = next_payload;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* last payload has no next payload*/
payload->set_next_type(payload, NO_PAYLOAD);
@@ -1411,72 +1434,78 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
static status_t verify(private_message_t *this)
{
int i;
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *current_payload;
size_t total_found_payloads = 0;
DBG2(DBG_ENC, "verifying message structure");
- iterator = this->payloads->create_iterator(this->payloads,TRUE);
/* check for payloads with wrong count*/
- for (i = 0; i < this->message_rule->payload_rule_count;i++)
+ for (i = 0; i < this->message_rule->payload_rule_count; i++)
{
size_t found_payloads = 0;
-
- /* check all payloads for specific rule */
- iterator->reset(iterator);
+ payload_rule_t *rule;
- while(iterator->iterate(iterator,(void **)&current_payload))
+ rule = &this->message_rule->payload_rules[i];
+ enumerator = create_payload_enumerator(this);
+
+ /* check all payloads for specific rule */
+ while (enumerator->enumerate(enumerator, &current_payload))
{
payload_type_t current_payload_type;
+ unknown_payload_t *unknown_payload;
current_payload_type = current_payload->get_type(current_payload);
if (current_payload_type == UNKNOWN_PAYLOAD)
{
/* unknown payloads are ignored, IF they are not critical */
- unknown_payload_t *unknown_payload = (unknown_payload_t*)current_payload;
+ unknown_payload = (unknown_payload_t*)current_payload;
if (unknown_payload->is_critical(unknown_payload))
{
DBG1(DBG_ENC, "%N is not supported, but its critical!",
payload_type_names, current_payload_type);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return NOT_SUPPORTED;
}
}
- else if (current_payload_type == this->message_rule->payload_rules[i].payload_type)
+ else if (current_payload_type == rule->payload_type)
{
found_payloads++;
total_found_payloads++;
- DBG2(DBG_ENC, "found payload of type %N",
- payload_type_names, this->message_rule->payload_rules[i].payload_type);
+ DBG2(DBG_ENC, "found payload of type %N", payload_type_names,
+ rule->payload_type);
- /* as soon as ohe payload occures more then specified, the verification fails */
- if (found_payloads > this->message_rule->payload_rules[i].max_occurence)
+ /* as soon as ohe payload occures more then specified,
+ * the verification fails */
+ if (found_payloads >
+ rule->max_occurence)
{
- DBG1(DBG_ENC, "payload of type %N more than %d times (%d) occured in current message",
- payload_type_names, current_payload_type,
- this->message_rule->payload_rules[i].max_occurence, found_payloads);
- iterator->destroy(iterator);
+ DBG1(DBG_ENC, "payload of type %N more than %d times (%d) "
+ "occured in current message", payload_type_names,
+ current_payload_type, rule->max_occurence,
+ found_payloads);
+ enumerator->destroy(enumerator);
return VERIFY_ERROR;
}
}
}
- if (found_payloads < this->message_rule->payload_rules[i].min_occurence)
+ if (found_payloads < rule->min_occurence)
{
DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)",
- payload_type_names, this->message_rule->payload_rules[i].payload_type,
- this->message_rule->payload_rules[i].min_occurence, found_payloads);
- iterator->destroy(iterator);
+ payload_type_names, rule->payload_type, rule->min_occurence,
+ found_payloads);
+ enumerator->destroy(enumerator);
return VERIFY_ERROR;
}
- if ((this->message_rule->payload_rules[i].sufficient) && (this->payloads->get_count(this->payloads) == total_found_payloads))
+ if (rule->sufficient &&
+ this->payloads->get_count(this->payloads) == total_found_payloads)
{
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return SUCCESS;
}
+ enumerator->destroy(enumerator);
}
- iterator->destroy(iterator);
return SUCCESS;
}
@@ -1604,8 +1633,9 @@ message_t *message_create_from_packet(packet_t *packet)
this->public.get_source = (host_t * (*) (message_t*)) get_source;
this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination;
this->public.get_destination = (host_t * (*) (message_t*)) get_destination;
- this->public.get_payload_iterator = (iterator_t * (*) (message_t *)) get_payload_iterator;
+ this->public.create_payload_enumerator = (enumerator_t * (*) (message_t *)) create_payload_enumerator;
this->public.get_payload = (payload_t * (*) (message_t *, payload_type_t)) get_payload;
+ this->public.get_notify = (notify_payload_t*(*)(message_t*, notify_type_t type))get_notify;
this->public.parse_header = (status_t (*) (message_t *)) parse_header;
this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body;
this->public.get_packet = (packet_t * (*) (message_t*)) get_packet;
diff --git a/src/charon/encoding/message.h b/src/charon/encoding/message.h
index 40941c2c9..1db3ea0cc 100644
--- a/src/charon/encoding/message.h
+++ b/src/charon/encoding/message.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: message.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -286,14 +284,11 @@ struct message_t {
void (*set_destination) (message_t *this, host_t *host);
/**
- * Returns an iterator on all stored payloads.
- *
- * @warning Don't insert payloads over this iterator.
- * Use add_payload() instead.
+ * Create an enumerator over all payloads.
*
- * @return iterator_t object which has to get destroyd by the caller
+ * @return enumerator over payload_t
*/
- iterator_t * (*get_payload_iterator) (message_t *this);
+ enumerator_t * (*create_payload_enumerator) (message_t *this);
/**
* Find a payload of a specific type.
@@ -306,6 +301,14 @@ struct message_t {
payload_t* (*get_payload) (message_t *this, payload_type_t type);
/**
+ * Get the first notify payload of a specific type.
+ *
+ * @param type type of notification payload
+ * @return notify payload, NULL if no such notify found
+ */
+ notify_payload_t* (*get_notify)(message_t *this, notify_type_t type);
+
+ /**
* Returns a clone of the internal stored packet_t object.
*
* @return packet_t object as clone of internal one
diff --git a/src/charon/encoding/parser.c b/src/charon/encoding/parser.c
index 396054810..ac2b78c28 100644
--- a/src/charon/encoding/parser.c
+++ b/src/charon/encoding/parser.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: parser.c 4703 2008-11-26 10:54:08Z martin $
*/
#include <stdlib.h>
@@ -88,29 +86,52 @@ struct private_parser_t {
};
/**
+ * Forward declaration
+ */
+static status_t parse_payload(private_parser_t *this,
+ payload_type_t payload_type, payload_t **payload);
+
+/**
+ * Log invalid length error
+ */
+static bool short_input(private_parser_t *this, int number)
+{
+ DBG1(DBG_ENC, " not enough input to parse rule %d %N",
+ number, encoding_type_names, this->rules[number].type);
+ return FALSE;
+}
+
+/**
+ * Log unaligned rules
+ */
+static bool bad_bitpos(private_parser_t *this, int number)
+{
+ DBG1(DBG_ENC, " found rule %d %N on bitpos %d",
+ number, encoding_type_names, this->rules[number].type, this->bit_pos);
+ return FALSE;
+}
+
+/**
* Parse a 4-Bit unsigned integer from the current parsing position.
*/
-static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *output_pos)
+static bool parse_uint4(private_parser_t *this, int rule_number,
+ u_int8_t *output_pos)
{
- if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
+ if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
switch (this->bit_pos)
{
case 0:
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
*output_pos = *(this->byte_pos) >> 4;
}
this->bit_pos = 4;
break;
- case 4:
- /* caller interested in result ? */
- if (output_pos != NULL)
+ case 4:
+ if (output_pos)
{
*output_pos = *(this->byte_pos) & 0x0F;
}
@@ -118,311 +139,240 @@ static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *o
this->byte_pos++;
break;
default:
- DBG2(DBG_ENC, " found rule %d %N on bitpos %d",
- rule_number, encoding_type_names,
- this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
-
- if (output_pos != NULL)
+ if (output_pos)
{
DBG3(DBG_ENC, " => %d", *output_pos);
}
-
- return SUCCESS;
+ return TRUE;
}
/**
* Parse a 8-Bit unsigned integer from the current parsing position.
*/
-static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *output_pos)
+static bool parse_uint8(private_parser_t *this, int rule_number,
+ u_int8_t *output_pos)
{
- if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
+ if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d",
- rule_number, encoding_type_names,
- this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
-
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
*output_pos = *(this->byte_pos);
DBG3(DBG_ENC, " => %d", *output_pos);
}
this->byte_pos++;
-
- return SUCCESS;
+ return TRUE;
}
/**
* Parse a 15-Bit unsigned integer from the current parsing position.
*/
-static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t *output_pos)
+static bool parse_uint15(private_parser_t *this, int rule_number,
+ u_int16_t *output_pos)
{
if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos != 1)
{
- DBG2(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
- *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
+ memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
+ *output_pos = ntohs(*output_pos) & ~0x8000;
DBG3(DBG_ENC, " => %d", *output_pos);
}
- this->byte_pos += 2;
+ this->byte_pos += sizeof(u_int16_t);
this->bit_pos = 0;
-
- return SUCCESS;
+ return TRUE;
}
/**
* Parse a 16-Bit unsigned integer from the current parsing position.
*/
-static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t *output_pos)
+static bool parse_uint16(private_parser_t *this, int rule_number,
+ u_int16_t *output_pos)
{
if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
- *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
-
+ memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
+ *output_pos = ntohs(*output_pos);
DBG3(DBG_ENC, " => %d", *output_pos);
}
- this->byte_pos += 2;
-
- return SUCCESS;
+ this->byte_pos += sizeof(u_int16_t);
+ return TRUE;
}
/**
* Parse a 32-Bit unsigned integer from the current parsing position.
*/
-static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t *output_pos)
+static bool parse_uint32(private_parser_t *this, int rule_number,
+ u_int32_t *output_pos)
{
if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
- *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
-
+ memcpy(output_pos, this->byte_pos, sizeof(u_int32_t));
+ *output_pos = ntohl(*output_pos);
DBG3(DBG_ENC, " => %d", *output_pos);
}
- this->byte_pos += 4;
-
- return SUCCESS;
-}
-
-/**
- * Parse a 64-Bit unsigned integer from the current parsing position.
- */
-static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t *output_pos)
-{
- if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
- {
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
- }
- if (this->bit_pos)
- {
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
- }
- /* caller interested in result ? */
- if (output_pos != NULL)
- {
- /* assuming little endian host order */
- *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
- *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
-
- DBG3(DBG_ENC, " => %b", (void*)output_pos, sizeof(u_int64_t));
- }
- this->byte_pos += 8;
-
- return SUCCESS;
+ this->byte_pos += sizeof(u_int32_t);
+ return TRUE;
}
/**
* Parse a given amount of bytes and writes them to a specific location
*/
-static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes)
+static bool parse_bytes(private_parser_t *this, int rule_number,
+ u_int8_t *output_pos, int bytes)
{
if (this->byte_pos + bytes > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
-
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
- memcpy(output_pos,this->byte_pos,bytes);
-
- DBG3(DBG_ENC, " => %b", (void*)output_pos, bytes);
+ memcpy(output_pos, this->byte_pos, bytes);
+ DBG3(DBG_ENC, " => %b", output_pos, bytes);
}
this->byte_pos += bytes;
-
- return SUCCESS;
+ return TRUE;
}
/**
* Parse a single Bit from the current parsing position
*/
-static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_pos)
+static bool parse_bit(private_parser_t *this, int rule_number,
+ bool *output_pos)
{
if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input to parse rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
- /* caller interested in result ? */
- if (output_pos != NULL)
+ if (output_pos)
{
u_int8_t mask;
mask = 0x01 << (7 - this->bit_pos);
*output_pos = *this->byte_pos & mask;
-
+
if (*output_pos)
- {
- /* set to a "clean", comparable true */
+ { /* set to a "clean", comparable true */
*output_pos = TRUE;
}
-
DBG3(DBG_ENC, " => %d", *output_pos);
}
this->bit_pos = (this->bit_pos + 1) % 8;
- if (this->bit_pos == 0)
+ if (this->bit_pos == 0)
{
- this->byte_pos++;
+ this->byte_pos++;
}
-
- return SUCCESS;
+ return TRUE;
}
/**
* Parse substructures in a list.
*/
-static status_t parse_list(private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_type, size_t length)
+static bool parse_list(private_parser_t *this, int rule_number,
+ linked_list_t **output_pos, payload_type_t payload_type, int length)
{
- linked_list_t * list = *output_pos;
+ linked_list_t *list = *output_pos;
if (length < 0)
{
- DBG1(DBG_ENC, " invalid length for rule %d %N",
- rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
-
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
-
while (length > 0)
{
u_int8_t *pos_before = this->byte_pos;
payload_t *payload;
- status_t status;
+
DBG2(DBG_ENC, " %d bytes left, parsing recursively %N",
length, payload_type_names, payload_type);
- status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
- if (status != SUCCESS)
+
+ if (parse_payload(this, payload_type, &payload) != SUCCESS)
{
DBG1(DBG_ENC, " parsing of a %N substructure failed",
payload_type_names, payload_type);
- return status;
+ return FALSE;
}
list->insert_last(list, payload);
length -= this->byte_pos - pos_before;
}
+ if (length != 0)
+ { /* must yield exactly to zero */
+ DBG1(DBG_ENC, " length of %N substructure list invalid",
+ payload_type_names, payload_type);
+ return FALSE;
+ }
*output_pos = list;
- return SUCCESS;
+ return TRUE;
}
/**
* Parse data from current parsing position in a chunk.
*/
-static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length)
+static bool parse_chunk(private_parser_t *this, int rule_number,
+ chunk_t *output_pos, int length)
{
if (this->byte_pos + length > this->input_roof)
{
- DBG1(DBG_ENC, " not enough input (%d bytes) to parse rule %d %N",
- length, rule_number, encoding_type_names, this->rules[rule_number].type);
- return PARSE_ERROR;
+ return short_input(this, rule_number);
}
if (this->bit_pos)
{
- DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
- encoding_type_names, this->rules[rule_number].type, this->bit_pos);
- return PARSE_ERROR;
+ return bad_bitpos(this, rule_number);
}
- if (output_pos != NULL)
+ if (output_pos)
{
- output_pos->len = length;
- output_pos->ptr = malloc(length);
+ *output_pos = chunk_alloc(length);
memcpy(output_pos->ptr, this->byte_pos, length);
+ DBG3(DBG_ENC, " => %b", output_pos->ptr, length);
}
this->byte_pos += length;
- DBG3(DBG_ENC, " => %b", (void*)output_pos->ptr, length);
-
- return SUCCESS;
+ return TRUE;
}
/**
* Implementation of parser_t.parse_payload.
*/
-static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload)
+static status_t parse_payload(private_parser_t *this,
+ payload_type_t payload_type, payload_t **payload)
{
payload_t *pld;
void *output;
- size_t rule_count, payload_length = 0, spi_size = 0, attribute_length = 0;
+ size_t rule_count;
+ int payload_length = 0, spi_size = 0, attribute_length = 0;
u_int16_t ts_type = 0;
bool attribute_format = FALSE;
int rule_number;
@@ -435,7 +385,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
payload_type_names, payload_type, this->input_roof - this->byte_pos);
DBG3(DBG_ENC, "parsing payload from %b",
- this->byte_pos, this->input_roof-this->byte_pos);
+ this->byte_pos, this->input_roof - this->byte_pos);
if (pld->get_type(pld) == UNKNOWN_PAYLOAD)
{
@@ -447,7 +397,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
output = pld;
/* parse the payload with its own rulse */
- pld->get_encoding_rules(pld, &(this->rules), &rule_count);
+ pld->get_encoding_rules(pld, &this->rules, &rule_count);
for (rule_number = 0; rule_number < rule_count; rule_number++)
{
rule = &(this->rules[rule_number]);
@@ -457,7 +407,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
{
case U_INT_4:
{
- if (parse_uint4(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint4(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -466,7 +416,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case U_INT_8:
{
- if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint8(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -475,7 +425,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case U_INT_16:
{
- if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint16(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -484,16 +434,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case U_INT_32:
{
- if (parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
- {
- pld->destroy(pld);
- return PARSE_ERROR;
- }
- break;
- }
- case U_INT_64:
- {
- if (parse_uint64(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint32(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -502,7 +443,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case IKE_SPI:
{
- if (parse_bytes(this, rule_number, output + rule->offset,8) != SUCCESS)
+ if (!parse_bytes(this, rule_number, output + rule->offset, 8))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -511,7 +452,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case RESERVED_BIT:
{
- if (parse_bit(this, rule_number, NULL) != SUCCESS)
+ if (!parse_bit(this, rule_number, NULL))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -520,7 +461,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case RESERVED_BYTE:
{
- if (parse_uint8(this, rule_number, NULL) != SUCCESS)
+ if (!parse_uint8(this, rule_number, NULL))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -529,7 +470,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case FLAG:
{
- if (parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_bit(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -538,11 +479,12 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case PAYLOAD_LENGTH:
{
- if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint16(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
}
+ /* parsed u_int16 should be aligned */
payload_length = *(u_int16_t*)(output + rule->offset);
if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH)
{
@@ -553,7 +495,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case HEADER_LENGTH:
{
- if (parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint32(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -562,7 +504,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case SPI_SIZE:
{
- if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint8(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -572,7 +514,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case SPI:
{
- if (parse_chunk(this, rule_number, output + rule->offset, spi_size) != SUCCESS)
+ if (!parse_chunk(this, rule_number, output + rule->offset,
+ spi_size))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -582,8 +525,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case PROPOSALS:
{
if (payload_length < SA_PAYLOAD_HEADER_LENGTH ||
- parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE,
- payload_length - SA_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_list(this, rule_number, output + rule->offset,
+ PROPOSAL_SUBSTRUCTURE,
+ payload_length - SA_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -592,9 +536,11 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case TRANSFORMS:
{
- if (payload_length < spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH ||
- parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE,
- payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS)
+ if (payload_length <
+ spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH ||
+ !parse_list(this, rule_number, output + rule->offset,
+ TRANSFORM_SUBSTRUCTURE, payload_length - spi_size -
+ PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -604,8 +550,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case TRANSFORM_ATTRIBUTES:
{
if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH ||
- parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE,
- payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS)
+ !parse_list(this, rule_number, output + rule->offset,
+ TRANSFORM_ATTRIBUTE,
+ payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -615,8 +562,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case CONFIGURATION_ATTRIBUTES:
{
if (payload_length < CP_PAYLOAD_HEADER_LENGTH ||
- parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE,
- payload_length - CP_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_list(this, rule_number, output + rule->offset,
+ CONFIGURATION_ATTRIBUTE,
+ payload_length - CP_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -625,7 +573,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case ATTRIBUTE_FORMAT:
{
- if (parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_bit(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -635,17 +583,16 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case ATTRIBUTE_TYPE:
{
- if (parse_uint15(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint15(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
}
- attribute_format = *(bool*)(output + rule->offset);
break;
}
case CONFIGURATION_ATTRIBUTE_LENGTH:
{
- if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint16(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -654,8 +601,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
break;
}
case ATTRIBUTE_LENGTH_OR_VALUE:
- {
- if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
+ {
+ if (!parse_uint16(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -665,43 +612,42 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
}
case ATTRIBUTE_VALUE:
{
- if (attribute_format == FALSE)
+ if (attribute_format == FALSE &&
+ !parse_chunk(this, rule_number, output + rule->offset,
+ attribute_length))
{
- if (parse_chunk(this, rule_number, output + rule->offset, attribute_length) != SUCCESS)
- {
- pld->destroy(pld);
- return PARSE_ERROR;
- }
+ pld->destroy(pld);
+ return PARSE_ERROR;
}
break;
}
case NONCE_DATA:
{
if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - NONCE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - NONCE_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
+ }
break;
}
case ID_DATA:
{
if (payload_length < ID_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - ID_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - ID_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
+ }
break;
}
case AUTH_DATA:
{
if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - AUTH_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - AUTH_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -711,8 +657,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case CERT_DATA:
{
if (payload_length < CERT_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - CERT_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - CERT_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -722,8 +668,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case CERTREQ_DATA:
{
if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -733,8 +679,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case EAP_DATA:
{
if (payload_length < EAP_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - EAP_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - EAP_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
@@ -744,109 +690,112 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
case SPIS:
{
if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - DELETE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - DELETE_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case VID_DATA:
{
if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case CONFIGURATION_ATTRIBUTE_VALUE:
{
- size_t data_length = attribute_length;
- if (parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
+ if (!parse_chunk(this, rule_number, output + rule->offset,
+ attribute_length))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case KEY_EXCHANGE_DATA:
{
if (payload_length < KE_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - KE_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - KE_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case NOTIFICATION_DATA:
{
if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case ENCRYPTED_DATA:
- {
+ {
if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
- }
- break;
+ }
+ break;
}
case TS_TYPE:
{
- if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
+ if (!parse_uint8(this, rule_number, output + rule->offset))
{
pld->destroy(pld);
return PARSE_ERROR;
}
ts_type = *(u_int8_t*)(output + rule->offset);
- break;
+ break;
}
case ADDRESS:
{
- size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
- if (parse_chunk(this, rule_number, output + rule->offset,address_length) != SUCCESS)
+ int address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
+
+ if (!parse_chunk(this, rule_number, output + rule->offset,
+ address_length))
{
pld->destroy(pld);
return PARSE_ERROR;
}
- break;
+ break;
}
case TRAFFIC_SELECTORS:
{
if (payload_length < TS_PAYLOAD_HEADER_LENGTH ||
- parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE,
- payload_length - TS_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_list(this, rule_number, output + rule->offset,
+ TRAFFIC_SELECTOR_SUBSTRUCTURE,
+ payload_length - TS_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
}
- break;
+ break;
}
case UNKNOWN_DATA:
{
if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH ||
- parse_chunk(this, rule_number, output + rule->offset,
- payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH) != SUCCESS)
+ !parse_chunk(this, rule_number, output + rule->offset,
+ payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH))
{
pld->destroy(pld);
return PARSE_ERROR;
}
- break;
+ break;
}
default:
{
@@ -871,8 +820,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ
*/
static int get_remaining_byte_count (private_parser_t *this)
{
- int count = (this->input_roof - this->byte_pos);
- return count;
+ return this->input_roof - this->byte_pos;
}
/**
@@ -889,7 +837,7 @@ static void reset_context (private_parser_t *this)
*/
static void destroy(private_parser_t *this)
{
- free(this);
+ free(this);
}
/*
@@ -899,7 +847,7 @@ parser_t *parser_create(chunk_t data)
{
private_parser_t *this = malloc_thing(private_parser_t);
- this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload;
+ this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**))parse_payload;
this->public.reset_context = (void(*)(parser_t*)) reset_context;
this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
this->public.destroy = (void(*)(parser_t*)) destroy;
@@ -909,5 +857,6 @@ parser_t *parser_create(chunk_t data)
this->bit_pos = 0;
this->input_roof = data.ptr + data.len;
- return (parser_t*)this;
+ return &this->public;
}
+
diff --git a/src/charon/encoding/parser.h b/src/charon/encoding/parser.h
index 222e328d1..230492438 100644
--- a/src/charon/encoding/parser.h
+++ b/src/charon/encoding/parser.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: parser.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/auth_payload.c b/src/charon/encoding/payloads/auth_payload.c
index f9ca23236..53406f564 100644
--- a/src/charon/encoding/payloads/auth_payload.c
+++ b/src/charon/encoding/payloads/auth_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: auth_payload.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include "auth_payload.h"
diff --git a/src/charon/encoding/payloads/auth_payload.h b/src/charon/encoding/payloads/auth_payload.h
index 26375a398..4287f14d9 100644
--- a/src/charon/encoding/payloads/auth_payload.h
+++ b/src/charon/encoding/payloads/auth_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: auth_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/cert_payload.c b/src/charon/encoding/payloads/cert_payload.c
index 7ff334006..54a8c1392 100644
--- a/src/charon/encoding/payloads/cert_payload.c
+++ b/src/charon/encoding/payloads/cert_payload.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: cert_payload.c 4317 2008-09-02 11:00:13Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/cert_payload.h b/src/charon/encoding/payloads/cert_payload.h
index d6e328850..fba404ee2 100644
--- a/src/charon/encoding/payloads/cert_payload.h
+++ b/src/charon/encoding/payloads/cert_payload.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: cert_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/certreq_payload.c b/src/charon/encoding/payloads/certreq_payload.c
index 1b499e9e8..50adedb28 100644
--- a/src/charon/encoding/payloads/certreq_payload.c
+++ b/src/charon/encoding/payloads/certreq_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: certreq_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/certreq_payload.h b/src/charon/encoding/payloads/certreq_payload.h
index a246f0e93..ff9814f8a 100644
--- a/src/charon/encoding/payloads/certreq_payload.h
+++ b/src/charon/encoding/payloads/certreq_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: certreq_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/configuration_attribute.c b/src/charon/encoding/payloads/configuration_attribute.c
index ad8177e1f..674feeddd 100644
--- a/src/charon/encoding/payloads/configuration_attribute.c
+++ b/src/charon/encoding/payloads/configuration_attribute.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: configuration_attribute.c 4844 2009-01-20 22:55:13Z andreas $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/configuration_attribute.h b/src/charon/encoding/payloads/configuration_attribute.h
index 13aaa0e90..404130114 100644
--- a/src/charon/encoding/payloads/configuration_attribute.h
+++ b/src/charon/encoding/payloads/configuration_attribute.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: configuration_attribute.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/cp_payload.c b/src/charon/encoding/payloads/cp_payload.c
index d39dc2a47..b5f1b35c7 100644
--- a/src/charon/encoding/payloads/cp_payload.c
+++ b/src/charon/encoding/payloads/cp_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: cp_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/cp_payload.h b/src/charon/encoding/payloads/cp_payload.h
index c31b1667d..6ffcca708 100644
--- a/src/charon/encoding/payloads/cp_payload.h
+++ b/src/charon/encoding/payloads/cp_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: cp_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/delete_payload.c b/src/charon/encoding/payloads/delete_payload.c
index 01ee7f027..c2be1e8b5 100644
--- a/src/charon/encoding/payloads/delete_payload.c
+++ b/src/charon/encoding/payloads/delete_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/delete_payload.h b/src/charon/encoding/payloads/delete_payload.h
index 862deb9dc..58840741a 100644
--- a/src/charon/encoding/payloads/delete_payload.h
+++ b/src/charon/encoding/payloads/delete_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/eap_payload.c b/src/charon/encoding/payloads/eap_payload.c
index d9a6fe6dd..1199bac45 100644
--- a/src/charon/encoding/payloads/eap_payload.c
+++ b/src/charon/encoding/payloads/eap_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/eap_payload.h b/src/charon/encoding/payloads/eap_payload.h
index 337f82e12..a4d8a38c6 100644
--- a/src/charon/encoding/payloads/eap_payload.h
+++ b/src/charon/encoding/payloads/eap_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/encodings.c b/src/charon/encoding/payloads/encodings.c
index 66c1fd999..85caeda82 100644
--- a/src/charon/encoding/payloads/encodings.c
+++ b/src/charon/encoding/payloads/encodings.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: encodings.c 3589 2008-03-13 14:14:44Z martin $
*/
@@ -24,7 +22,6 @@ ENUM(encoding_type_names, U_INT_4, ENCRYPTED_DATA,
"U_INT_8",
"U_INT_16",
"U_INT_32",
- "U_INT_64",
"RESERVED_BIT",
"RESERVED_BYTE",
"FLAG",
diff --git a/src/charon/encoding/payloads/encodings.h b/src/charon/encoding/payloads/encodings.h
index ad98874a2..03554f0af 100644
--- a/src/charon/encoding/payloads/encodings.h
+++ b/src/charon/encoding/payloads/encodings.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: encodings.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -99,19 +97,6 @@ enum encoding_type_t {
U_INT_32,
/**
- * Representing a 64 Bit unsigned int value.
- *
- * When generating it must be changed from host to network order.
- * The value is read from the associated data struct.
- * The current write position is moved 64 bit forward afterwards.
- *
- * When parsing it must be changed from network to host order.
- * The value is written to the associated data struct.
- * The current read pointer is moved 64 bit forward afterwards.
- */
- U_INT_64,
-
- /**
* represents a RESERVED_BIT used in FLAG-Bytes.
*
* When generating, the next bit is set to zero and the current write
diff --git a/src/charon/encoding/payloads/encryption_payload.c b/src/charon/encoding/payloads/encryption_payload.c
index 7237c69c5..55a37bb25 100644
--- a/src/charon/encoding/payloads/encryption_payload.c
+++ b/src/charon/encoding/payloads/encryption_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: encryption_payload.c 3862 2008-04-22 07:14:24Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/encryption_payload.h b/src/charon/encoding/payloads/encryption_payload.h
index 1d3eeb793..3b94587ec 100644
--- a/src/charon/encoding/payloads/encryption_payload.h
+++ b/src/charon/encoding/payloads/encryption_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: encryption_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/endpoint_notify.c b/src/charon/encoding/payloads/endpoint_notify.c
index c9ef47afb..c30d29942 100644
--- a/src/charon/encoding/payloads/endpoint_notify.c
+++ b/src/charon/encoding/payloads/endpoint_notify.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: endpoint_notify.c 3735 2008-04-02 18:21:03Z tobias $
*/
#include "endpoint_notify.h"
diff --git a/src/charon/encoding/payloads/endpoint_notify.h b/src/charon/encoding/payloads/endpoint_notify.h
index 36f483c67..66aabc683 100644
--- a/src/charon/encoding/payloads/endpoint_notify.h
+++ b/src/charon/encoding/payloads/endpoint_notify.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: endpoint_notify.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/id_payload.c b/src/charon/encoding/payloads/id_payload.c
index 347ad7563..4a527cb24 100644
--- a/src/charon/encoding/payloads/id_payload.c
+++ b/src/charon/encoding/payloads/id_payload.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: id_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/id_payload.h b/src/charon/encoding/payloads/id_payload.h
index 9de21cc6a..555b1324b 100644
--- a/src/charon/encoding/payloads/id_payload.h
+++ b/src/charon/encoding/payloads/id_payload.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: id_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/ike_header.c b/src/charon/encoding/payloads/ike_header.c
index 1db64f0e3..d27bfb82c 100644
--- a/src/charon/encoding/payloads/ike_header.c
+++ b/src/charon/encoding/payloads/ike_header.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_header.c 3666 2008-03-26 18:40:19Z tobias $
*/
/* offsetof macro */
diff --git a/src/charon/encoding/payloads/ike_header.h b/src/charon/encoding/payloads/ike_header.h
index 7292c2c9c..8de316d19 100644
--- a/src/charon/encoding/payloads/ike_header.h
+++ b/src/charon/encoding/payloads/ike_header.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_header.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/ke_payload.c b/src/charon/encoding/payloads/ke_payload.c
index 2f718e49c..aa3e075ca 100644
--- a/src/charon/encoding/payloads/ke_payload.c
+++ b/src/charon/encoding/payloads/ke_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ke_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/ke_payload.h b/src/charon/encoding/payloads/ke_payload.h
index bc5c9224a..7e182d970 100644
--- a/src/charon/encoding/payloads/ke_payload.h
+++ b/src/charon/encoding/payloads/ke_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ke_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/nonce_payload.c b/src/charon/encoding/payloads/nonce_payload.c
index da68ce4ab..f9e075380 100644
--- a/src/charon/encoding/payloads/nonce_payload.c
+++ b/src/charon/encoding/payloads/nonce_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: nonce_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
/* offsetof macro */
diff --git a/src/charon/encoding/payloads/nonce_payload.h b/src/charon/encoding/payloads/nonce_payload.h
index b433c7023..4adaba481 100644
--- a/src/charon/encoding/payloads/nonce_payload.h
+++ b/src/charon/encoding/payloads/nonce_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: nonce_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c
index a4377c275..d2a995ace 100644
--- a/src/charon/encoding/payloads/notify_payload.c
+++ b/src/charon/encoding/payloads/notify_payload.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: notify_payload.c 4842 2009-01-19 12:32:42Z andreas $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h
index 9f7577c26..a5f501dca 100644
--- a/src/charon/encoding/payloads/notify_payload.h
+++ b/src/charon/encoding/payloads/notify_payload.h
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: notify_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/payload.c b/src/charon/encoding/payloads/payload.c
index 71350458f..1cee6d2aa 100644
--- a/src/charon/encoding/payloads/payload.c
+++ b/src/charon/encoding/payloads/payload.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: payload.c 4618 2008-11-11 09:22:00Z tobias $
*/
diff --git a/src/charon/encoding/payloads/payload.h b/src/charon/encoding/payloads/payload.h
index 7cb1b7735..78f5b7b97 100644
--- a/src/charon/encoding/payloads/payload.h
+++ b/src/charon/encoding/payloads/payload.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/proposal_substructure.c b/src/charon/encoding/payloads/proposal_substructure.c
index daa015d3e..a8166023c 100644
--- a/src/charon/encoding/payloads/proposal_substructure.c
+++ b/src/charon/encoding/payloads/proposal_substructure.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: proposal_substructure.c 3658 2008-03-26 10:06:45Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/proposal_substructure.h b/src/charon/encoding/payloads/proposal_substructure.h
index 212366d77..8ccb917d6 100644
--- a/src/charon/encoding/payloads/proposal_substructure.h
+++ b/src/charon/encoding/payloads/proposal_substructure.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: proposal_substructure.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/sa_payload.c b/src/charon/encoding/payloads/sa_payload.c
index ecc3b0f60..3ca2f08c8 100644
--- a/src/charon/encoding/payloads/sa_payload.c
+++ b/src/charon/encoding/payloads/sa_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sa_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/sa_payload.h b/src/charon/encoding/payloads/sa_payload.h
index 237432422..58ae72544 100644
--- a/src/charon/encoding/payloads/sa_payload.h
+++ b/src/charon/encoding/payloads/sa_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sa_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/traffic_selector_substructure.c b/src/charon/encoding/payloads/traffic_selector_substructure.c
index eb5bbc626..7dcdce6aa 100644
--- a/src/charon/encoding/payloads/traffic_selector_substructure.c
+++ b/src/charon/encoding/payloads/traffic_selector_substructure.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: traffic_selector_substructure.c 4639 2008-11-12 15:09:24Z martin $
*/
#include "traffic_selector_substructure.h"
diff --git a/src/charon/encoding/payloads/traffic_selector_substructure.h b/src/charon/encoding/payloads/traffic_selector_substructure.h
index 9179d1478..ee3e204a0 100644
--- a/src/charon/encoding/payloads/traffic_selector_substructure.h
+++ b/src/charon/encoding/payloads/traffic_selector_substructure.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: traffic_selector_substructure.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/transform_attribute.c b/src/charon/encoding/payloads/transform_attribute.c
index b9b5ff879..507d04a34 100644
--- a/src/charon/encoding/payloads/transform_attribute.c
+++ b/src/charon/encoding/payloads/transform_attribute.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: transform_attribute.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
@@ -248,7 +246,7 @@ static u_int16_t get_attribute_type (private_transform_attribute_t *this)
/**
* Implementation of transform_attribute_t.clone.
*/
-static transform_attribute_t * clone(private_transform_attribute_t *this)
+static transform_attribute_t * _clone(private_transform_attribute_t *this)
{
private_transform_attribute_t *new_clone;
@@ -302,7 +300,7 @@ transform_attribute_t *transform_attribute_create()
this->public.get_value = (u_int16_t (*) (transform_attribute_t *)) get_value;
this->public.set_attribute_type = (void (*) (transform_attribute_t *,u_int16_t type)) set_attribute_type;
this->public.get_attribute_type = (u_int16_t (*) (transform_attribute_t *)) get_attribute_type;
- this->public.clone = (transform_attribute_t * (*) (transform_attribute_t *)) clone;
+ this->public.clone = (transform_attribute_t * (*) (transform_attribute_t *)) _clone;
this->public.destroy = (void (*) (transform_attribute_t *)) destroy;
/* set default values of the fields */
diff --git a/src/charon/encoding/payloads/transform_attribute.h b/src/charon/encoding/payloads/transform_attribute.h
index 6755ff74c..f7d71a9df 100644
--- a/src/charon/encoding/payloads/transform_attribute.h
+++ b/src/charon/encoding/payloads/transform_attribute.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: transform_attribute.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/transform_substructure.c b/src/charon/encoding/payloads/transform_substructure.c
index 7c3d6421a..497bd53b2 100644
--- a/src/charon/encoding/payloads/transform_substructure.c
+++ b/src/charon/encoding/payloads/transform_substructure.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: transform_substructure.c 3971 2008-05-16 13:27:21Z tobias $
*/
#include <stddef.h>
@@ -382,37 +380,23 @@ transform_substructure_t *transform_substructure_create()
/*
* Described in header
*/
-transform_substructure_t *transform_substructure_create_type(transform_type_t transform_type, u_int16_t transform_id, u_int16_t key_length)
+transform_substructure_t *transform_substructure_create_type(
+ transform_type_t transform_type,
+ u_int16_t transform_id, u_int16_t key_length)
{
transform_substructure_t *transform = transform_substructure_create();
transform->set_transform_type(transform,transform_type);
transform->set_transform_id(transform,transform_id);
- /* a keylength attribute is only created for variable length algos */
- if (transform_type == ENCRYPTION_ALGORITHM)
+ if (key_length)
{
- switch(transform_id)
- {
- case ENCR_AES_CBC:
- case ENCR_IDEA:
- case ENCR_CAST:
- case ENCR_BLOWFISH:
- case ENCR_AES_CCM_ICV8:
- case ENCR_AES_CCM_ICV12:
- case ENCR_AES_CCM_ICV16:
- case ENCR_AES_GCM_ICV8:
- case ENCR_AES_GCM_ICV12:
- case ENCR_AES_GCM_ICV16:
- {
- transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
- transform->add_transform_attribute(transform,attribute);
- break;
- }
- default:
- break;
- }
+ transform_attribute_t *attribute;
+
+ attribute = transform_attribute_create_key_length(key_length);
+ transform->add_transform_attribute(transform, attribute);
+
}
-
return transform;
}
+
diff --git a/src/charon/encoding/payloads/transform_substructure.h b/src/charon/encoding/payloads/transform_substructure.h
index cc8adc38a..b02a94a6c 100644
--- a/src/charon/encoding/payloads/transform_substructure.h
+++ b/src/charon/encoding/payloads/transform_substructure.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: transform_substructure.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/ts_payload.c b/src/charon/encoding/payloads/ts_payload.c
index 5d53793b1..92ddc380f 100644
--- a/src/charon/encoding/payloads/ts_payload.c
+++ b/src/charon/encoding/payloads/ts_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ts_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/ts_payload.h b/src/charon/encoding/payloads/ts_payload.h
index 91f26f55d..3c8a6d595 100644
--- a/src/charon/encoding/payloads/ts_payload.h
+++ b/src/charon/encoding/payloads/ts_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ts_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/unknown_payload.c b/src/charon/encoding/payloads/unknown_payload.c
index 8a8db308d..309663233 100644
--- a/src/charon/encoding/payloads/unknown_payload.c
+++ b/src/charon/encoding/payloads/unknown_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: unknown_payload.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/unknown_payload.h b/src/charon/encoding/payloads/unknown_payload.h
index 03894c619..44b6e1a71 100644
--- a/src/charon/encoding/payloads/unknown_payload.h
+++ b/src/charon/encoding/payloads/unknown_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: unknown_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/encoding/payloads/vendor_id_payload.c b/src/charon/encoding/payloads/vendor_id_payload.c
index 3e47b9348..52d9e12a5 100644
--- a/src/charon/encoding/payloads/vendor_id_payload.c
+++ b/src/charon/encoding/payloads/vendor_id_payload.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: vendor_id_payload.c 4120 2008-06-27 15:22:27Z andreas $
*/
#include <stddef.h>
diff --git a/src/charon/encoding/payloads/vendor_id_payload.h b/src/charon/encoding/payloads/vendor_id_payload.h
index b8798f24e..9ee9ea1d4 100644
--- a/src/charon/encoding/payloads/vendor_id_payload.h
+++ b/src/charon/encoding/payloads/vendor_id_payload.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: vendor_id_payload.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/kernel/kernel_interface.c b/src/charon/kernel/kernel_interface.c
index f099a94ac..5188b79fe 100644
--- a/src/charon/kernel/kernel_interface.c
+++ b/src/charon/kernel/kernel_interface.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_interface.c 4997 2009-03-24 10:24:58Z martin $
*/
#include "kernel_interface.h"
@@ -20,8 +18,6 @@
#include <pthread.h>
#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/mutex.h>
typedef struct private_kernel_interface_t private_kernel_interface_t;
@@ -36,16 +32,6 @@ struct private_kernel_interface_t {
kernel_interface_t public;
/**
- * list of registered ipsec kernel interfaces
- */
- linked_list_t *ipsec_interfaces;
-
- /**
- * list of registered network kernel interfaces
- */
- linked_list_t *net_interfaces;
-
- /**
* ipsec interface
*/
kernel_ipsec_t *ipsec;
@@ -54,11 +40,6 @@ struct private_kernel_interface_t {
* network interface
*/
kernel_net_t *net;
-
- /**
- * locking mutex
- */
- mutex_t *mutex;
};
/**
@@ -67,6 +48,10 @@ struct private_kernel_interface_t {
static status_t get_spi(private_kernel_interface_t *this, host_t *src, host_t *dst,
protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi);
}
@@ -76,6 +61,10 @@ static status_t get_spi(private_kernel_interface_t *this, host_t *src, host_t *d
static status_t get_cpi(private_kernel_interface_t *this, host_t *src, host_t *dst,
u_int32_t reqid, u_int16_t *cpi)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi);
}
@@ -90,6 +79,10 @@ static status_t add_sa(private_kernel_interface_t *this, host_t *src, host_t *ds
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
bool inbound)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
expire_soft, expire_hard, enc_alg, enc_key, int_alg, int_key,
mode, ipcomp, cpi, encap, inbound);
@@ -102,6 +95,10 @@ static status_t update_sa(private_kernel_interface_t *this, u_int32_t spi,
protocol_id_t protocol, u_int16_t cpi, host_t *src, host_t *dst,
host_t *new_src, host_t *new_dst, bool encap, bool new_encap)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst,
new_src, new_dst, encap, new_encap);
}
@@ -109,10 +106,14 @@ static status_t update_sa(private_kernel_interface_t *this, u_int32_t spi,
/**
* Implementation of kernel_interface_t.del_sa
*/
-static status_t del_sa(private_kernel_interface_t *this, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int16_t cpi)
+static status_t del_sa(private_kernel_interface_t *this, host_t *src, host_t *dst,
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
{
- return this->ipsec->del_sa(this->ipsec, dst, spi, protocol, cpi);
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
+ return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi);
}
/**
@@ -124,6 +125,10 @@ static status_t add_policy(private_kernel_interface_t *this, host_t *src, host_t
u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
bool routed)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
direction, spi, protocol, reqid, mode, ipcomp, cpi, routed);
}
@@ -135,6 +140,10 @@ static status_t query_policy(private_kernel_interface_t *this,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, u_int32_t *use_time)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts, direction, use_time);
}
@@ -145,6 +154,10 @@ static status_t del_policy(private_kernel_interface_t *this,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, bool unrouted)
{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts, direction, unrouted);
}
@@ -154,6 +167,10 @@ static status_t del_policy(private_kernel_interface_t *this,
static host_t *get_source_addr(private_kernel_interface_t *this,
host_t *dest, host_t *src)
{
+ if (!this->net)
+ {
+ return NULL;
+ }
return this->net->get_source_addr(this->net, dest, src);
}
@@ -162,6 +179,10 @@ static host_t *get_source_addr(private_kernel_interface_t *this,
*/
static host_t *get_nexthop(private_kernel_interface_t *this, host_t *dest)
{
+ if (!this->net)
+ {
+ return NULL;
+ }
return this->net->get_nexthop(this->net, dest);
}
@@ -170,6 +191,10 @@ static host_t *get_nexthop(private_kernel_interface_t *this, host_t *dest)
*/
static char* get_interface(private_kernel_interface_t *this, host_t *host)
{
+ if (!this->net)
+ {
+ return NULL;
+ }
return this->net->get_interface(this->net, host);
}
@@ -179,6 +204,10 @@ static char* get_interface(private_kernel_interface_t *this, host_t *host)
static enumerator_t *create_address_enumerator(private_kernel_interface_t *this,
bool include_down_ifaces, bool include_virtual_ips)
{
+ if (!this->net)
+ {
+ return enumerator_create_empty();
+ }
return this->net->create_address_enumerator(this->net, include_down_ifaces,
include_virtual_ips);
}
@@ -189,6 +218,10 @@ static enumerator_t *create_address_enumerator(private_kernel_interface_t *this,
static status_t add_ip(private_kernel_interface_t *this, host_t *virtual_ip,
host_t *iface_ip)
{
+ if (!this->net)
+ {
+ return NOT_SUPPORTED;
+ }
return this->net->add_ip(this->net, virtual_ip, iface_ip);
}
@@ -197,6 +230,10 @@ static status_t add_ip(private_kernel_interface_t *this, host_t *virtual_ip,
*/
static status_t del_ip(private_kernel_interface_t *this, host_t *virtual_ip)
{
+ if (!this->net)
+ {
+ return NOT_SUPPORTED;
+ }
return this->net->del_ip(this->net, virtual_ip);
}
@@ -206,6 +243,10 @@ static status_t del_ip(private_kernel_interface_t *this, host_t *virtual_ip)
static status_t add_route(private_kernel_interface_t *this, chunk_t dst_net,
u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
{
+ if (!this->net)
+ {
+ return NOT_SUPPORTED;
+ }
return this->net->add_route(this->net, dst_net, prefixlen, gateway, src_ip,
if_name);
}
@@ -216,6 +257,10 @@ static status_t add_route(private_kernel_interface_t *this, chunk_t dst_net,
static status_t del_route(private_kernel_interface_t *this, chunk_t dst_net,
u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
{
+ if (!this->net)
+ {
+ return NOT_SUPPORTED;
+ }
return this->net->del_route(this->net, dst_net, prefixlen, gateway, src_ip,
if_name);
}
@@ -283,70 +328,42 @@ static status_t get_address_by_ts(private_kernel_interface_t *this,
* Implementation of kernel_interface_t.add_ipsec_interface.
*/
static void add_ipsec_interface(private_kernel_interface_t *this,
- kernel_ipsec_constructor_t *create)
+ kernel_ipsec_constructor_t constructor)
{
- this->mutex->lock(this->mutex);
- this->ipsec_interfaces->insert_last(this->ipsec_interfaces, create);
- this->mutex->unlock(this->mutex);
+ if (!this->ipsec)
+ {
+ this->ipsec = constructor();
+ }
}
/**
* Implementation of kernel_interface_t.remove_ipsec_interface.
*/
static void remove_ipsec_interface(private_kernel_interface_t *this,
- kernel_ipsec_constructor_t *create)
+ kernel_ipsec_constructor_t constructor)
{
- this->mutex->lock(this->mutex);
- this->ipsec_interfaces->remove(this->ipsec_interfaces, create, NULL);
- this->mutex->unlock(this->mutex);
+ /* TODO: replace if interface currently in use */
}
/**
* Implementation of kernel_interface_t.add_net_interface.
*/
static void add_net_interface(private_kernel_interface_t *this,
- kernel_net_constructor_t *create)
+ kernel_net_constructor_t constructor)
{
- this->mutex->lock(this->mutex);
- this->net_interfaces->insert_last(this->net_interfaces, create);
- this->mutex->unlock(this->mutex);
+ if (!this->net)
+ {
+ this->net = constructor();
+ }
}
/**
* Implementation of kernel_interface_t.remove_net_interface.
*/
static void remove_net_interface(private_kernel_interface_t *this,
- kernel_net_constructor_t *create)
-{
- this->mutex->lock(this->mutex);
- this->net_interfaces->remove(this->net_interfaces, create, NULL);
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Implementation of kernel_interface_t.create_interfaces.
- */
-static void create_interfaces(private_kernel_interface_t *this)
+ kernel_net_constructor_t constructor)
{
- kernel_ipsec_constructor_t create_ipsec;
- kernel_net_constructor_t create_net;
-
- this->mutex->lock(this->mutex);
- if (this->ipsec_interfaces->get_first(this->ipsec_interfaces, (void**)&create_ipsec) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- charon->kill(charon, "no ipsec kernel interface loaded");
- }
-
- if (this->net_interfaces->get_first(this->net_interfaces, (void**)&create_net) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- charon->kill(charon, "no network kernel interface loaded");
- }
- this->mutex->unlock(this->mutex);
-
- this->ipsec = create_ipsec();
- this->net = create_net();
+ /* TODO: replace if interface currently in use */
}
/**
@@ -356,9 +373,6 @@ static void destroy(private_kernel_interface_t *this)
{
DESTROY_IF(this->ipsec);
DESTROY_IF(this->net);
- this->ipsec_interfaces->destroy(this->ipsec_interfaces);
- this->net_interfaces->destroy(this->net_interfaces);
- this->mutex->destroy(this->mutex);
free(this);
}
@@ -373,7 +387,7 @@ kernel_interface_t *kernel_interface_create()
this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
- this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
+ this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
@@ -394,12 +408,8 @@ kernel_interface_t *kernel_interface_create()
this->public.add_net_interface = (void(*)(kernel_interface_t*, kernel_net_constructor_t))add_net_interface;
this->public.remove_net_interface = (void(*)(kernel_interface_t*, kernel_net_constructor_t))remove_net_interface;
- this->public.create_interfaces = (void (*)(kernel_interface_t*))create_interfaces;
this->public.destroy = (void (*)(kernel_interface_t*))destroy;
- this->ipsec_interfaces = linked_list_create();
- this->net_interfaces = linked_list_create();
- this->mutex = mutex_create(MUTEX_RECURSIVE);
this->ipsec = NULL;
this->net = NULL;
diff --git a/src/charon/kernel/kernel_interface.h b/src/charon/kernel/kernel_interface.h
index 29a07f74f..8c58c959a 100644
--- a/src/charon/kernel/kernel_interface.h
+++ b/src/charon/kernel/kernel_interface.h
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_interface.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -145,14 +143,15 @@ struct kernel_interface_t {
/**
* Delete a previously installed SA from the SAD.
*
+ * @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 cpi CPI for IPComp or 0
* @return SUCCESS if operation completed
*/
- status_t (*del_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int16_t cpi);
+ status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi);
/**
* Add a policy to the SPD.
@@ -364,11 +363,6 @@ struct kernel_interface_t {
void (*remove_net_interface)(kernel_interface_t *this, kernel_net_constructor_t create);
/**
- * Create the kernel interfaces classes.
- */
- void (*create_interfaces)(kernel_interface_t *this);
-
- /**
* Destroys a kernel_interface_manager_t object.
*/
void (*destroy) (kernel_interface_t *this);
diff --git a/src/charon/kernel/kernel_ipsec.c b/src/charon/kernel/kernel_ipsec.c
index 1fef2acca..45eef4907 100644
--- a/src/charon/kernel/kernel_ipsec.c
+++ b/src/charon/kernel/kernel_ipsec.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_ipsec.c 4430 2008-10-14 08:46:31Z tobias $
*/
#include "kernel_ipsec.h"
diff --git a/src/charon/kernel/kernel_ipsec.h b/src/charon/kernel/kernel_ipsec.h
index 24834c4b1..6e8c5bc63 100644
--- a/src/charon/kernel/kernel_ipsec.h
+++ b/src/charon/kernel/kernel_ipsec.h
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_ipsec.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -35,17 +33,15 @@ typedef struct kernel_ipsec_t kernel_ipsec_t;
#include <encoding/payloads/proposal_substructure.h>
/**
- * Mode of an CHILD_SA.
- *
- * These are equal to those defined in XFRM, so don't change.
+ * Mode of a CHILD_SA.
*/
enum ipsec_mode_t {
/** transport mode, no inner address */
- MODE_TRANSPORT = 0,
+ MODE_TRANSPORT = 1,
/** tunnel mode, inner and outer addresses */
- MODE_TUNNEL = 1,
+ MODE_TUNNEL,
/** BEET mode, tunnel mode but fixed, bound inner addresses */
- MODE_BEET = 4,
+ MODE_BEET,
};
/**
@@ -177,14 +173,15 @@ struct kernel_ipsec_t {
/**
* Delete a previusly installed SA from the SAD.
*
+ * @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 cpi CPI for IPComp or 0
* @return SUCCESS if operation completed
*/
- status_t (*del_sa) (kernel_ipsec_t *this, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int16_t cpi);
+ status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
+ u_int32_t spi, protocol_id_t protocol, u_int16_t cpi);
/**
* Add a policy to the SPD.
diff --git a/src/charon/kernel/kernel_net.h b/src/charon/kernel/kernel_net.h
index df73bc1f9..02242f3a8 100644
--- a/src/charon/kernel/kernel_net.h
+++ b/src/charon/kernel/kernel_net.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_net.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/network/packet.c b/src/charon/network/packet.c
index b47e6322f..fd3a274bd 100644
--- a/src/charon/network/packet.c
+++ b/src/charon/network/packet.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: packet.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "packet.h"
diff --git a/src/charon/network/packet.h b/src/charon/network/packet.h
index 8c1a07ab5..aacb203e9 100644
--- a/src/charon/network/packet.h
+++ b/src/charon/network/packet.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: packet.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/network/receiver.c b/src/charon/network/receiver.c
index 7f55df4d2..ab4d6d592 100644
--- a/src/charon/network/receiver.c
+++ b/src/charon/network/receiver.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: receiver.c 4699 2008-11-26 09:22:19Z tobias $
*/
#include <stdlib.h>
@@ -57,56 +55,56 @@ struct private_receiver_t {
* Threads job receiving packets
*/
callback_job_t *job;
-
+
/**
* Assigned thread.
*/
pthread_t assigned_thread;
- /**
- * current secret to use for cookie calculation
- */
- char secret[SECRET_LENGTH];
-
- /**
- * previous secret used to verify older cookies
- */
- char secret_old[SECRET_LENGTH];
-
- /**
- * how many times we have used "secret" so far
- */
- u_int32_t secret_used;
-
- /**
- * time we did the cookie switch
- */
- u_int32_t secret_switch;
-
- /**
- * time offset to use, hides our system time
- */
- u_int32_t secret_offset;
-
- /**
- * the RNG to use for secret generation
- */
- rng_t *rng;
-
- /**
- * hasher to use for cookie calculation
- */
- hasher_t *hasher;
-
- /**
- * require cookies after this many half open IKE_SAs
- */
- u_int32_t cookie_threshold;
-
- /**
- * how many half open IKE_SAs per peer before blocking
- */
- u_int32_t block_threshold;
+ /**
+ * current secret to use for cookie calculation
+ */
+ char secret[SECRET_LENGTH];
+
+ /**
+ * previous secret used to verify older cookies
+ */
+ char secret_old[SECRET_LENGTH];
+
+ /**
+ * how many times we have used "secret" so far
+ */
+ u_int32_t secret_used;
+
+ /**
+ * time we did the cookie switch
+ */
+ u_int32_t secret_switch;
+
+ /**
+ * time offset to use, hides our system time
+ */
+ u_int32_t secret_offset;
+
+ /**
+ * the RNG to use for secret generation
+ */
+ rng_t *rng;
+
+ /**
+ * hasher to use for cookie calculation
+ */
+ hasher_t *hasher;
+
+ /**
+ * require cookies after this many half open IKE_SAs
+ */
+ u_int32_t cookie_threshold;
+
+ /**
+ * how many half open IKE_SAs per peer before blocking
+ */
+ u_int32_t block_threshold;
};
/**
@@ -169,10 +167,10 @@ static bool cookie_verify(private_receiver_t *this, message_t *message,
u_int32_t t, now;
chunk_t reference;
chunk_t secret;
-
+
now = time(NULL);
t = *(u_int32_t*)cookie.ptr;
-
+
if (cookie.len != sizeof(u_int32_t) +
this->hasher->get_hash_size(this->hasher) ||
t < now - this->secret_offset - COOKIE_LIFETIME)
@@ -355,7 +353,7 @@ receiver_t *receiver_create()
{
private_receiver_t *this = malloc_thing(private_receiver_t);
u_int32_t now = time(NULL);
-
+
this->public.destroy = (void(*)(receiver_t*)) destroy;
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
@@ -387,7 +385,7 @@ receiver_t *receiver_create()
this->cookie_threshold = 0;
this->block_threshold = 0;
}
-
+
this->job = callback_job_create((callback_job_cb_t)receive_packets,
this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job);
diff --git a/src/charon/network/receiver.h b/src/charon/network/receiver.h
index 36a57df79..87797634e 100644
--- a/src/charon/network/receiver.h
+++ b/src/charon/network/receiver.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: receiver.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/network/sender.c b/src/charon/network/sender.c
index 3295ec2df..4910fe2e8 100644
--- a/src/charon/network/sender.c
+++ b/src/charon/network/sender.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sender.c 4582 2008-11-05 12:24:36Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/network/sender.h b/src/charon/network/sender.h
index 0c92017e4..55f67af70 100644
--- a/src/charon/network/sender.h
+++ b/src/charon/network/sender.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sender.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/network/socket-raw.c b/src/charon/network/socket-raw.c
index 40218f67d..148be486c 100644
--- a/src/charon/network/socket-raw.c
+++ b/src/charon/network/socket-raw.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: socket-raw.c 4646 2008-11-13 07:15:45Z martin $
*/
/* for struct in6_pktinfo */
@@ -374,7 +372,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
msg.msg_iovlen = 1;
msg.msg_flags = 0;
- if (!dst->is_anyaddr(dst))
+ if (!src->is_anyaddr(src))
{
if (family == AF_INET)
{
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c
index 8c516a9da..8627ca76d 100644
--- a/src/charon/network/socket.c
+++ b/src/charon/network/socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006-2009 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: socket.c 4688 2008-11-24 08:22:05Z martin $
*/
/* for struct in6_pktinfo */
@@ -30,12 +28,11 @@
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
-#include <linux/types.h>
-#include <linux/filter.h>
#include <net/if.h>
#include "socket.h"
@@ -54,10 +51,23 @@
#define UDP_ENCAP_ESPINUDP 2
#endif /*UDP_ENCAP_ESPINUDP*/
-/* needed for older kernel headers */
-#ifndef IPV6_2292PKTINFO
-#define IPV6_2292PKTINFO 2
-#endif /*IPV6_2292PKTINFO*/
+/* these are not defined on some platforms */
+#ifndef SOL_IP
+#define SOL_IP IPPROTO_IP
+#endif
+#ifndef SOL_IPV6
+#define SOL_IPV6 IPPROTO_IPV6
+#endif
+#ifndef SOL_UDP
+#define SOL_UDP IPPROTO_UDP
+#endif
+
+/* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
+ * previously defined IPV6_PKTINFO */
+#ifndef IPV6_RECVPKTINFO
+#define IPV6_RECVPKTINFO IPV6_PKTINFO;
+#endif
+
typedef struct private_socket_t private_socket_t;
@@ -68,27 +78,27 @@ struct private_socket_t {
/**
* public functions
*/
- socket_t public;
-
- /**
- * IPv4 socket (500)
- */
- int ipv4;
-
- /**
- * IPv4 socket for NATT (4500)
- */
- int ipv4_natt;
-
- /**
- * IPv6 socket (500)
- */
- int ipv6;
+ socket_t public;
+
+ /**
+ * IPv4 socket (500)
+ */
+ int ipv4;
- /**
- * IPv6 socket for NATT (4500)
- */
- int ipv6_natt;
+ /**
+ * IPv4 socket for NATT (4500)
+ */
+ int ipv4_natt;
+
+ /**
+ * IPv6 socket (500)
+ */
+ int ipv6;
+
+ /**
+ * IPv6 socket for NATT (4500)
+ */
+ int ipv6_natt;
};
/**
@@ -104,8 +114,8 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
int data_offset, oldstate;
fd_set rfds;
int max_fd = 0, selected = 0;
- u_int16_t port;
-
+ u_int16_t port = 0;
+
FD_ZERO(&rfds);
if (this->ipv4)
@@ -201,7 +211,7 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
}
if (cmsgptr->cmsg_level == SOL_IPV6 &&
- cmsgptr->cmsg_type == IPV6_2292PKTINFO)
+ cmsgptr->cmsg_type == IPV6_PKTINFO)
{
struct in6_pktinfo *pktinfo;
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
@@ -214,14 +224,28 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
}
if (cmsgptr->cmsg_level == SOL_IP &&
- cmsgptr->cmsg_type == IP_PKTINFO)
- {
+#ifdef IP_PKTINFO
+ cmsgptr->cmsg_type == IP_PKTINFO
+#elif defined(IP_RECVDSTADDR)
+ cmsgptr->cmsg_type == IP_RECVDSTADDR
+#else
+ FALSE
+#endif
+ )
+ {
+ struct in_addr *addr;
+ struct sockaddr_in dst;
+
+#ifdef IP_PKTINFO
struct in_pktinfo *pktinfo;
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
- struct sockaddr_in dst;
-
+ addr = &pktinfo->ipi_addr;
+#elif defined(IP_RECVDSTADDR)
+ addr = (struct in_addr*)CMSG_DATA(cmsgptr);
+#endif
memset(&dst, 0, sizeof(dst));
- memcpy(&dst.sin_addr, &pktinfo->ipi_addr, sizeof(dst.sin_addr));
+ memcpy(&dst.sin_addr, addr, sizeof(dst.sin_addr));
+
dst.sin_family = AF_INET;
dst.sin_port = htons(port);
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
@@ -340,24 +364,37 @@ status_t sender(private_socket_t *this, packet_t *packet)
msg.msg_iovlen = 1;
msg.msg_flags = 0;
- if (!dst->is_anyaddr(dst))
+ if (!src->is_anyaddr(src))
{
if (family == AF_INET)
{
+#if defined(IP_PKTINFO) || defined(IP_SENDSRCADDR)
+ struct in_addr *addr;
+ struct sockaddr_in *sin;
+#ifdef IP_PKTINFO
char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct in_pktinfo *pktinfo;
- struct sockaddr_in *sin;
-
+#elif defined(IP_SENDSRCADDR)
+ char buf[CMSG_SPACE(sizeof(struct in_addr))];
+#endif
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_IP;
+#ifdef IP_PKTINFO
cmsg->cmsg_type = IP_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
memset(pktinfo, 0, sizeof(struct in_pktinfo));
+ addr = &pktinfo->ipi_spec_dst;
+#elif defined(IP_SENDSRCADDR)
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ addr = (struct in_addr*)CMSG_DATA(cmsg);
+#endif
sin = (struct sockaddr_in*)src->get_sockaddr(src);
- memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr));
+ memcpy(addr, &sin->sin_addr, sizeof(struct in_addr));
+#endif /* IP_PKTINFO || IP_SENDSRCADDR */
}
else
{
@@ -369,7 +406,7 @@ status_t sender(private_socket_t *this, packet_t *packet)
msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_IPV6;
- cmsg->cmsg_type = IPV6_2292PKTINFO;
+ cmsg->cmsg_type = IPV6_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
memset(pktinfo, 0, sizeof(struct in6_pktinfo));
@@ -389,14 +426,15 @@ status_t sender(private_socket_t *this, packet_t *packet)
}
/**
- * open a socket to send packets
+ * open a socket to send and receive packets
*/
static int open_socket(private_socket_t *this, int family, u_int16_t port)
{
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
- u_int sol, pktinfo;
+ socklen_t addrlen;
+ u_int sol, pktinfo = 0;
int skt;
memset(&addr, 0, sizeof(addr));
@@ -409,8 +447,13 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = htons(port);
+ addrlen = sizeof(struct sockaddr_in);
sol = SOL_IP;
+#ifdef IP_PKTINFO
pktinfo = IP_PKTINFO;
+#elif defined(IP_RECVDSTADDR)
+ pktinfo = IP_RECVDSTADDR;
+#endif
break;
}
case AF_INET6:
@@ -419,8 +462,9 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
sin6->sin6_port = htons(port);
+ addrlen = sizeof(struct sockaddr_in6);
sol = SOL_IPV6;
- pktinfo = IPV6_2292PKTINFO;
+ pktinfo = IPV6_RECVPKTINFO;
break;
}
default:
@@ -440,8 +484,8 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
return 0;
}
- /* bind the send socket */
- if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ /* bind the socket */
+ if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0)
{
DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
close(skt);
@@ -449,11 +493,14 @@ static int open_socket(private_socket_t *this, int family, u_int16_t port)
}
/* get additional packet info on receive */
- if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
+ if (pktinfo > 0)
{
- DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
- close(skt);
- return 0;
+ if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
+ close(skt);
+ return 0;
+ }
}
/* enable UDP decapsulation globally, only for one socket needed */
@@ -578,7 +625,7 @@ socket_t *socket_create()
DBG1(DBG_NET, "could not open IPv4 NAT-T socket");
}
}
-
+
this->ipv6 = open_socket(this, AF_INET6, IKEV2_UDP_PORT);
if (this->ipv6 == 0)
{
diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h
index af5d64edf..81f2ec5fe 100644
--- a/src/charon/network/socket.h
+++ b/src/charon/network/socket.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: socket.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/attr/Makefile.am b/src/charon/plugins/attr/Makefile.am
new file mode 100644
index 000000000..d5eb99d9f
--- /dev/null
+++ b/src/charon/plugins/attr/Makefile.am
@@ -0,0 +1,9 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+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
diff --git a/src/charon/plugins/attr/Makefile.in b/src/charon/plugins/attr/Makefile.in
new file mode 100644
index 000000000..c0467054e
--- /dev/null
+++ b/src/charon/plugins/attr/Makefile.in
@@ -0,0 +1,507 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/charon/plugins/attr
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_attr_la_LIBADD =
+am_libstrongswan_attr_la_OBJECTS = attr_plugin.lo attr_provider.lo
+libstrongswan_attr_la_OBJECTS = $(am_libstrongswan_attr_la_OBJECTS)
+libstrongswan_attr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_attr_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_attr_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_attr_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+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
+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/charon/plugins/attr/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/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
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-attr.la: $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_DEPENDENCIES)
+ $(libstrongswan_attr_la_LINK) -rpath $(plugindir) $(libstrongswan_attr_la_OBJECTS) $(libstrongswan_attr_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_provider.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/charon/plugins/attr/attr_plugin.c b/src/charon/plugins/attr/attr_plugin.c
new file mode 100644
index 000000000..9d5532310
--- /dev/null
+++ b/src/charon/plugins/attr/attr_plugin.c
@@ -0,0 +1,63 @@
+/*
+ * 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;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_attr_plugin_t *this)
+{
+ charon->attributes->remove_provider(charon->attributes, &this->provider->provider);
+ this->provider->destroy(this->provider);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_attr_plugin_t *this = malloc_thing(private_attr_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->provider = attr_provider_create();
+ charon->attributes->add_provider(charon->attributes, &this->provider->provider);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/scepclient/rsakey.h b/src/charon/plugins/attr/attr_plugin.h
index 3e3156d81..9cbbd8bf5 100644
--- a/src/scepclient/rsakey.h
+++ b/src/charon/plugins/attr/attr_plugin.h
@@ -1,11 +1,5 @@
-/**
- * @file rsakey.h
- * @brief Functions for RSA key generation
- */
-
-/*
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005 Jan Hutter, Martin Willi
+/*
+ * Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -17,15 +11,37 @@
* WITHOUT 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
*
- * $Id: rsakey.h,v 1.2 2005/08/11 21:52:56 as Exp $
+ * @defgroup attr_plugin attr_plugin
+ * @{ @ingroup attr
*/
-
-#ifndef RSAKEY_H_
-#define RSAKEY_H_
-#include "../pluto/pkcs1.h"
+#ifndef ATTR_PLUGIN_H_
+#define ATTR_PLUGIN_H_
+
+#include <plugins/plugin.h>
-extern err_t generate_rsa_private_key(int nbits, RSA_private_key_t *key);
+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;
+};
+
+/**
+ * Create a attr_plugin instance.
+ */
+plugin_t *plugin_create();
-#endif // RSAKEY_H_
+#endif /** ATTR_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/attr/attr_provider.c b/src/charon/plugins/attr/attr_provider.c
new file mode 100644
index 000000000..02fa11327
--- /dev/null
+++ b/src/charon/plugins/attr/attr_provider.c
@@ -0,0 +1,154 @@
+/*
+ * 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>
+
+#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;
+};
+
+struct attribute_entry_t {
+ /** type of attribute */
+ configuration_attribute_type_t type;
+ /** attribute value */
+ chunk_t value;
+};
+
+/**
+ * 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;
+}
+
+/**
+ * Implementation of attribute_provider_t.create_attribute_enumerator
+ */
+static enumerator_t* create_attribute_enumerator(
+ private_attr_provider_t *this, identification_t *id)
+{
+ return enumerator_create_filter(
+ this->attributes->create_enumerator(this->attributes),
+ (void*)attr_enum_filter, NULL, NULL);
+}
+
+/**
+ * Implementation of attr_provider_t.destroy
+ */
+static void destroy(private_attr_provider_t *this)
+{
+ attribute_entry_t *entry;
+
+ while (this->attributes->remove_last(this->attributes,
+ (void**)&entry) == SUCCESS)
+ {
+ free(entry->value.ptr);
+ free(entry);
+ }
+ this->attributes->destroy(this->attributes);
+ free(this);
+}
+
+/**
+ * Add an attribute entry to the list
+ */
+static void add_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, "charon.%s%d", NULL, 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);
+ this->attributes->insert_last(this->attributes, entry);
+ }
+ }
+}
+
+/*
+ * see header file
+ */
+attr_provider_t *attr_provider_create(database_t *db)
+{
+ private_attr_provider_t *this;
+ int i;
+
+ this = malloc_thing(private_attr_provider_t);
+
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))return_null;
+ this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))return_false;
+ this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))create_attribute_enumerator;
+ this->public.destroy = (void(*)(attr_provider_t*))destroy;
+
+ this->attributes = linked_list_create();
+
+ for (i = 1; i <= SERVER_MAX; i++)
+ {
+ add_entry(this, "dns", i, INTERNAL_IP4_DNS);
+ add_entry(this, "nbns", i, INTERNAL_IP4_NBNS);
+ }
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/attr/attr_provider.h b/src/charon/plugins/attr/attr_provider.h
new file mode 100644
index 000000000..03cbadb4e
--- /dev/null
+++ b/src/charon/plugins/attr/attr_provider.h
@@ -0,0 +1,49 @@
+/*
+ * 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_provider attr_provider
+ * @{ @ingroup attr
+ */
+
+#ifndef ATTR_PROVIDER_H_
+#define ATTR_PROVIDER_H_
+
+#include <config/attributes/attribute_provider.h>
+
+typedef struct attr_provider_t attr_provider_t;
+
+/**
+ * Provide configuration attributes through static strongswan.conf definition.
+ */
+struct attr_provider_t {
+
+ /**
+ * Implements attribute provider interface
+ */
+ attribute_provider_t provider;
+
+ /**
+ * Destroy a attr_provider instance.
+ */
+ void (*destroy)(attr_provider_t *this);
+};
+
+/**
+ * Create a attr_provider instance.
+ */
+attr_provider_t *attr_provider_create();
+
+#endif /** ATTR_PROVIDER @}*/
diff --git a/src/charon/plugins/eap_aka/Makefile.in b/src/charon/plugins/eap_aka/Makefile.in
index 47eece7ab..74d49ac73 100644
--- a/src/charon/plugins/eap_aka/Makefile.in
+++ b/src/charon/plugins/eap_aka/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -223,8 +232,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -319,7 +328,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_aka/eap_aka.c b/src/charon/plugins/eap_aka/eap_aka.c
index bb3825d3d..82ee6c3f0 100644
--- a/src/charon/plugins/eap_aka/eap_aka.c
+++ b/src/charon/plugins/eap_aka/eap_aka.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_aka.c 4628 2008-11-11 15:19:13Z martin $
*/
@@ -880,7 +878,7 @@ static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
/* Get the shared key K: */
if (load_key(this->server, this->peer, &this->k) != SUCCESS)
{
- DBG1(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+ DBG1(DBG_IKE, "no shared key found for IDs '%Y' - '%Y' to authenticate "
"with EAP-AKA", this->server, this->peer);
return FAILED;
}
@@ -1202,7 +1200,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
{
*out = build_aka_payload(this, EAP_RESPONSE, identifier,
AKA_AUTHENTICATION_REJECT, AT_END);
- DBG3(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+ DBG3(DBG_IKE, "no shared key found for IDs '%Y' - '%Y' to authenticate "
"with EAP-AKA, sending %N", this->peer, this->server,
aka_subtype_names, AKA_AUTHENTICATION_REJECT);
return NEED_MORE;
diff --git a/src/charon/plugins/eap_aka/eap_aka.h b/src/charon/plugins/eap_aka/eap_aka.h
index 196eaf429..7686802cf 100644
--- a/src/charon/plugins/eap_aka/eap_aka.h
+++ b/src/charon/plugins/eap_aka/eap_aka.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_aka.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.c b/src/charon/plugins/eap_aka/eap_aka_plugin.c
index 5c15b6d7e..e4a5326fe 100644
--- a/src/charon/plugins/eap_aka/eap_aka_plugin.c
+++ b/src/charon/plugins/eap_aka/eap_aka_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_aka_plugin.c 3491 2008-02-22 14:04:00Z martin $
*/
#include "eap_aka_plugin.h"
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.h b/src/charon/plugins/eap_aka/eap_aka_plugin.h
index 5fdc5c768..2c086ca80 100644
--- a/src/charon/plugins/eap_aka/eap_aka_plugin.h
+++ b/src/charon/plugins/eap_aka/eap_aka_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_aka_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_gtc/Makefile.in b/src/charon/plugins/eap_gtc/Makefile.in
index 0e8245804..19d648bbd 100644
--- a/src/charon/plugins/eap_gtc/Makefile.in
+++ b/src/charon/plugins/eap_gtc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -222,8 +231,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -318,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_gtc/eap_gtc.c b/src/charon/plugins/eap_gtc/eap_gtc.c
index 0a93a90f6..cb4ab2e59 100644
--- a/src/charon/plugins/eap_gtc/eap_gtc.c
+++ b/src/charon/plugins/eap_gtc/eap_gtc.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_gtc.c 3806 2008-04-15 05:56:35Z martin $
*/
#include "eap_gtc.h"
@@ -174,7 +172,7 @@ static status_t process_peer(private_eap_gtc_t *this,
this->peer, this->server);
if (shared == NULL)
{
- DBG1(DBG_IKE, "no EAP key found for '%D' - '%D'",
+ DBG1(DBG_IKE, "no EAP key found for '%Y' - '%Y'",
this->peer, this->server);
return FAILED;
}
diff --git a/src/charon/plugins/eap_gtc/eap_gtc.h b/src/charon/plugins/eap_gtc/eap_gtc.h
index 722881249..2eb8482f8 100644
--- a/src/charon/plugins/eap_gtc/eap_gtc.h
+++ b/src/charon/plugins/eap_gtc/eap_gtc.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_gtc.h 3589 2008-03-13 14:14:44Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c
index cea88ef9f..fda6c744a 100644
--- a/src/charon/plugins/eap_gtc/eap_gtc_plugin.c
+++ b/src/charon/plugins/eap_gtc/eap_gtc_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_gtc_plugin.h"
diff --git a/src/charon/plugins/eap_gtc/eap_gtc_plugin.h b/src/charon/plugins/eap_gtc/eap_gtc_plugin.h
index f858f0d15..abb6bdcb6 100644
--- a/src/charon/plugins/eap_gtc/eap_gtc_plugin.h
+++ b/src/charon/plugins/eap_gtc/eap_gtc_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_identity/Makefile.in b/src/charon/plugins/eap_identity/Makefile.in
index 212df3a94..f275cd770 100644
--- a/src/charon/plugins/eap_identity/Makefile.in
+++ b/src/charon/plugins/eap_identity/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,6 +215,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_identity/eap_identity.c b/src/charon/plugins/eap_identity/eap_identity.c
index deaa183f4..e43c50c50 100644
--- a/src/charon/plugins/eap_identity/eap_identity.c
+++ b/src/charon/plugins/eap_identity/eap_identity.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_identity.c 4276 2008-08-22 10:44:51Z martin $
*/
#include "eap_identity.h"
diff --git a/src/charon/plugins/eap_identity/eap_identity.h b/src/charon/plugins/eap_identity/eap_identity.h
index 60f62e17c..7364a8bda 100644
--- a/src/charon/plugins/eap_identity/eap_identity.h
+++ b/src/charon/plugins/eap_identity/eap_identity.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_identity.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_identity/eap_identity_plugin.c b/src/charon/plugins/eap_identity/eap_identity_plugin.c
index 1393a21a0..809254ccb 100644
--- a/src/charon/plugins/eap_identity/eap_identity_plugin.c
+++ b/src/charon/plugins/eap_identity/eap_identity_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_identity_plugin.c 4276 2008-08-22 10:44:51Z martin $
*/
#include "eap_identity_plugin.h"
diff --git a/src/charon/plugins/eap_identity/eap_identity_plugin.h b/src/charon/plugins/eap_identity/eap_identity_plugin.h
index ddb3ed457..0a7fb8228 100644
--- a/src/charon/plugins/eap_identity/eap_identity_plugin.h
+++ b/src/charon/plugins/eap_identity/eap_identity_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_identity_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_md5/Makefile.in b/src/charon/plugins/eap_md5/Makefile.in
index 7009f6488..372b80b3e 100644
--- a/src/charon/plugins/eap_md5/Makefile.in
+++ b/src/charon/plugins/eap_md5/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -222,8 +231,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -318,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_md5/eap_md5.c b/src/charon/plugins/eap_md5/eap_md5.c
index 0781e024b..36d726947 100644
--- a/src/charon/plugins/eap_md5/eap_md5.c
+++ b/src/charon/plugins/eap_md5/eap_md5.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_md5.c 4276 2008-08-22 10:44:51Z martin $
*/
#include "eap_md5.h"
@@ -90,7 +88,7 @@ static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response)
this->server, this->peer);
if (shared == NULL)
{
- DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
+ DBG1(DBG_IKE, "no EAP key found for hosts '%Y' - '%Y'",
this->server, this->peer);
return NOT_FOUND;
}
diff --git a/src/charon/plugins/eap_md5/eap_md5.h b/src/charon/plugins/eap_md5/eap_md5.h
index 2617b9aea..3cff0dd79 100644
--- a/src/charon/plugins/eap_md5/eap_md5.h
+++ b/src/charon/plugins/eap_md5/eap_md5.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_md5.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_md5/eap_md5_plugin.c b/src/charon/plugins/eap_md5/eap_md5_plugin.c
index cb6a9bd7c..e30152fc5 100644
--- a/src/charon/plugins/eap_md5/eap_md5_plugin.c
+++ b/src/charon/plugins/eap_md5/eap_md5_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_md5_plugin.c 3491 2008-02-22 14:04:00Z martin $
*/
#include "eap_md5_plugin.h"
diff --git a/src/charon/plugins/eap_md5/eap_md5_plugin.h b/src/charon/plugins/eap_md5/eap_md5_plugin.h
index 3adbcfe27..eb5b38e94 100644
--- a/src/charon/plugins/eap_md5/eap_md5_plugin.h
+++ b/src/charon/plugins/eap_md5/eap_md5_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_md5_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_mschapv2/Makefile.in b/src/charon/plugins/eap_mschapv2/Makefile.in
index e9dcae03e..5ae41d896 100644
--- a/src/charon/plugins/eap_mschapv2/Makefile.in
+++ b/src/charon/plugins/eap_mschapv2/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,6 +215,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -227,8 +236,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -323,7 +332,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_mschapv2/eap_mschapv2.c b/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
index 07ca48e6f..0e3fac780 100644
--- a/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/charon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -11,12 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_mschapv2.c 4896 2009-02-24 13:39:50Z martin $
*/
#include "eap_mschapv2.h"
+#include <ctype.h>
+#include <unistd.h>
+
#include <daemon.h>
#include <library.h>
#include <utils/enumerator.h>
@@ -141,7 +142,7 @@ ENUM_END(mschapv2_error_names, ERROR_CHANGING_PASSWORD);
/* Name we send as authenticator */
#define MSCHAPV2_HOST_NAME "strongSwan"
/* Message sent on success */
-#define SUCCESS_MESSAGE " M=Welcome to strongSwan"
+#define SUCCESS_MESSAGE " M=Welcome2strongSwan"
/* Message sent on failure */
#define FAILURE_MESSAGE "E=691 R=1 C="
/* Length of the complete failure message */
@@ -366,7 +367,6 @@ static status_t AuthenticatorResponse(chunk_t password_hash_hash,
static const chunk_t magic1 = chunk_from_buf(magic1_data);
static const chunk_t magic2 = chunk_from_buf(magic2_data);
- status_t status = FAILED;
chunk_t digest = chunk_empty, concat;
hasher_t *hasher;
@@ -456,7 +456,7 @@ static status_t GenerateMSK(chunk_t password_hash_hash,
hasher->allocate_hash(hasher, concat, &master_send_key);
master_send_key.len = 16;
- *msk = chunk_cat("cccc", master_receive_key, keypad, master_send_key, keypad);
+ *msk = chunk_cat("cccc", master_receive_key, master_send_key, keypad, keypad);
hasher->destroy(hasher);
chunk_free(&master_key);
@@ -527,6 +527,24 @@ static chunk_t ascii_to_unicode(chunk_t ascii)
}
/**
+ * sanitize a string for printing
+ */
+static char* sanitize(char *str)
+{
+ char *pos = str;
+
+ while (pos && *pos)
+ {
+ if (!isprint(*pos))
+ {
+ *pos = '?';
+ }
+ pos++;
+ }
+ return str;
+}
+
+/**
* Returns a chunk of just the username part of the given user identity.
* Note: the chunk points to internal data of the identification.
*/
@@ -535,7 +553,7 @@ static chunk_t extract_username(identification_t* identification)
char *has_domain;
chunk_t id;
id = identification->get_encoding(identification);
- has_domain = (char*)memrchr(id.ptr, '\\', id.len);
+ has_domain = (char*)memchr(id.ptr, '\\', id.len);
if (has_domain)
{
int len;
@@ -546,6 +564,14 @@ static chunk_t extract_username(identification_t* identification)
return id;
}
+/**
+ * Set the ms_length field using aligned write
+ */
+static void set_ms_length(eap_mschapv2_header_t *eap, u_int16_t len)
+{
+ len = htons(len - 5);
+ memcpy(&eap->ms_length, &len, sizeof(u_int16_t));
+}
/**
* Implementation of eap_method_t.initiate for the peer
@@ -567,8 +593,6 @@ static status_t initiate_server(private_eap_mschapv2_t *this, eap_payload_t **ou
const char *name = MSCHAPV2_HOST_NAME;
u_int16_t len = CHALLENGE_PAYLOAD_LEN + sizeof(MSCHAPV2_HOST_NAME) - 1;
- DBG1(DBG_IKE, "initiating EAP-MS-CHAPv2");
-
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (!rng)
{
@@ -585,7 +609,7 @@ static status_t initiate_server(private_eap_mschapv2_t *this, eap_payload_t **ou
eap->type = EAP_MSCHAPV2;
eap->opcode = MSCHAPV2_CHALLENGE;
eap->ms_chapv2_id = this->mschapv2id;
- eap->ms_length = htons(len - 5);
+ set_ms_length(eap, len);
cha = (eap_mschapv2_challenge_t*)eap->data;
cha->value_size = CHALLENGE_LEN;
@@ -625,7 +649,8 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
if (cha->value_size != CHALLENGE_LEN)
{
- DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid challenge size");
+ DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+ "invalid challenge size");
return FAILED;
}
@@ -643,11 +668,11 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
rng->destroy(rng);
shared = charon->credentials->get_shared(charon->credentials,
- SHARED_EAP, this->peer, this->server);
+ SHARED_EAP, this->peer, this->server);
if (shared == NULL)
{
- DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
- this->server, this->peer);
+ DBG1(DBG_IKE, "no EAP key found for hosts '%Y' - '%Y'",
+ this->server, this->peer);
return NOT_FOUND;
}
@@ -672,7 +697,7 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
eap->type = EAP_MSCHAPV2;
eap->opcode = MSCHAPV2_RESPONSE;
eap->ms_chapv2_id = this->mschapv2id;
- eap->ms_length = htons(len - 5);
+ set_ms_length(eap, len);
res = (eap_mschapv2_response_t*)eap->data;
res->value_size = RESPONSE_LEN;
@@ -725,7 +750,8 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
token += 2;
if (strlen(token) != AUTH_RESPONSE_LEN - 2)
{
- DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid auth string");
+ DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+ "invalid auth string");
goto error;
}
hex = chunk_create(token, AUTH_RESPONSE_LEN - 2);
@@ -741,7 +767,8 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
if (auth_string.ptr == NULL)
{
- DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: auth string missing");
+ DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+ "auth string missing");
goto error;
}
@@ -751,7 +778,7 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
goto error;
}
- DBG1(DBG_IKE, "EAP-MS-CHAPv2 succeeded: '%s'", msg);
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 succeeded: '%s'", sanitize(msg));
eap = alloca(len);
eap->code = EAP_RESPONSE;
@@ -780,7 +807,6 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
char *message, *token, *msg = NULL;
int message_len, error, retryable;
chunk_t challenge = chunk_empty;
- u_int16_t len = SHORT_HEADER_LEN;
data = in->get_data(in);
eap = (eap_mschapv2_header_t*)data.ptr;
@@ -816,7 +842,8 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
token += 2;
if (strlen(token) != 2 * CHALLENGE_LEN)
{
- DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid challenge");
+ DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message:"
+ "invalid challenge");
goto error;
}
hex = chunk_create(token, 2 * CHALLENGE_LEN);
@@ -836,7 +863,8 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
}
enumerator->destroy(enumerator);
- DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed with error %N: '%s'", mschapv2_error_names, error, msg);
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed with error %N: '%s'",
+ mschapv2_error_names, error, sanitize(msg));
/**
* at this point, if the error is retryable, we MAY retry the authentication
@@ -898,8 +926,8 @@ static status_t process_peer(private_eap_mschapv2_t *this, eap_payload_t *in,
}
default:
{
- DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported OpCode (%N)!",
- mschapv2_opcode_names, eap->opcode);
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
+ "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
break;
}
}
@@ -925,7 +953,8 @@ static status_t process_server_retry(private_eap_mschapv2_t *this,
* so, to clean up our state we just fail with an EAP-Failure.
* this gives an unknown error on the windows side, but is also fine
* with the standard. */
- DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed: maximum number of retries reached");
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed: "
+ "maximum number of retries reached");
return FAILED;
}
@@ -951,7 +980,7 @@ static status_t process_server_retry(private_eap_mschapv2_t *this,
eap->type = EAP_MSCHAPV2;
eap->opcode = MSCHAPV2_FAILURE;
eap->ms_chapv2_id = this->mschapv2id++; /* increase for each retry */
- eap->ms_length = htons(len - 5);
+ set_ms_length(eap, len);
hex = chunk_to_hex(this->challenge, NULL, TRUE);
snprintf(msg, FAILURE_MESSAGE_LEN, "%s%s", FAILURE_MESSAGE, hex.ptr);
@@ -977,6 +1006,7 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
identification_t *userid;
shared_key_t *shared;
int name_len;
+ char buf[256];
data = in->get_data(in);
eap = (eap_mschapv2_header_t*)data.ptr;
@@ -991,16 +1021,16 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
peer_challenge = chunk_create(res->response.peer_challenge, CHALLENGE_LEN);
name_len = min(data.len - RESPONSE_PAYLOAD_LEN, 255);
- userid = identification_create_from_encoding(ID_EAP,
- chunk_create(res->name, name_len));
+ snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
+ userid = identification_create_from_string(buf);
+ DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
username = extract_username(userid);
- DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%.*s'", name_len, res->name);
shared = charon->credentials->get_shared(charon->credentials,
SHARED_EAP, this->server, userid);
if (shared == NULL)
{
- DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
+ DBG1(DBG_IKE, "no EAP key found for hosts '%Y' - '%Y'",
this->server, userid);
/* FIXME: windows 7 always sends the username that is first entered in
* the username box, even, if the user changes it during retries (probably
@@ -1015,7 +1045,8 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
password = ascii_to_unicode(shared->get_key(shared));
shared->destroy(shared);
- if (GenerateStuff(this, this->challenge, peer_challenge, username, password) != SUCCESS)
+ if (GenerateStuff(this, this->challenge, peer_challenge,
+ username, password) != SUCCESS)
{
DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed");
userid->destroy(userid);
@@ -1038,7 +1069,7 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
eap->type = EAP_MSCHAPV2;
eap->opcode = MSCHAPV2_SUCCESS;
eap->ms_chapv2_id = this->mschapv2id;
- eap->ms_length = htons(len - 5);
+ set_ms_length(eap, len);
hex = chunk_to_hex(this->auth_response, NULL, TRUE);
snprintf(msg, AUTH_RESPONSE_LEN + sizeof(SUCCESS_MESSAGE),
@@ -1063,7 +1094,8 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
if (this->identifier != in->get_identifier(in))
{
- DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: unexpected identifier");
+ DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+ "unexpected identifier");
return FAILED;
}
@@ -1092,8 +1124,8 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
}
default:
{
- DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported OpCode (%N)!",
- mschapv2_opcode_names, eap->opcode);
+ DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
+ "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
break;
}
}
diff --git a/src/charon/plugins/eap_mschapv2/eap_mschapv2.h b/src/charon/plugins/eap_mschapv2/eap_mschapv2.h
index d5638db00..34cc1141e 100644
--- a/src/charon/plugins/eap_mschapv2/eap_mschapv2.h
+++ b/src/charon/plugins/eap_mschapv2/eap_mschapv2.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_mschapv2.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.c b/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
index 4303a3a7a..d0995c477 100644
--- a/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
+++ b/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_mschapv2_plugin.c 4882 2009-02-18 19:57:15Z tobias $
*/
#include "eap_mschapv2_plugin.h"
diff --git a/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.h b/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.h
index 0e671c3d6..9048fc64e 100644
--- a/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.h
+++ b/src/charon/plugins/eap_mschapv2/eap_mschapv2_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_mschapv2_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_radius/Makefile.in b/src/charon/plugins/eap_radius/Makefile.in
index 329ff981b..e7a4cd0f8 100644
--- a/src/charon/plugins/eap_radius/Makefile.in
+++ b/src/charon/plugins/eap_radius/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,6 +215,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -229,8 +238,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -327,7 +336,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_radius/eap_radius.c b/src/charon/plugins/eap_radius/eap_radius.c
index 1a02c5acf..ee2477440 100644
--- a/src/charon/plugins/eap_radius/eap_radius.c
+++ b/src/charon/plugins/eap_radius/eap_radius.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_radius.h"
@@ -22,7 +20,6 @@
#include <daemon.h>
-
typedef struct private_eap_radius_t private_eap_radius_t;
/**
@@ -64,6 +61,11 @@ struct private_eap_radius_t {
* RADIUS client instance
*/
radius_client_t *client;
+
+ /**
+ * TRUE to use EAP-Start, FALSE to send EAP-Identity Response directly
+ */
+ bool eap_start;
};
/**
@@ -137,7 +139,16 @@ static status_t initiate(private_eap_radius_t *this, eap_payload_t **out)
request = radius_message_create_request();
request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer));
- add_eap_identity(this, request);
+
+ if (this->eap_start)
+ {
+ request->add(request, RAT_EAP_MESSAGE, chunk_empty);
+ }
+ else
+ {
+ add_eap_identity(this, request);
+ }
+
response = this->client->request(this->client, request);
if (response)
{
@@ -270,6 +281,8 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
this->type = EAP_RADIUS;
this->vendor = 0;
this->msk = chunk_empty;
+ this->eap_start = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap_radius.eap_start", FALSE);
return &this->public;
}
diff --git a/src/charon/plugins/eap_radius/eap_radius.h b/src/charon/plugins/eap_radius/eap_radius.h
index 7cb0a8615..8eb9e8c2d 100644
--- a/src/charon/plugins/eap_radius/eap_radius.h
+++ b/src/charon/plugins/eap_radius/eap_radius.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_radius/eap_radius_plugin.c b/src/charon/plugins/eap_radius/eap_radius_plugin.c
index a429859a7..7c6a3c9ff 100644
--- a/src/charon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/charon/plugins/eap_radius/eap_radius_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_radius_plugin.h"
diff --git a/src/charon/plugins/eap_radius/eap_radius_plugin.h b/src/charon/plugins/eap_radius/eap_radius_plugin.h
index 3ed194619..a79640796 100644
--- a/src/charon/plugins/eap_radius/eap_radius_plugin.h
+++ b/src/charon/plugins/eap_radius/eap_radius_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_radius/radius_client.c b/src/charon/plugins/eap_radius/radius_client.c
index a3ab1dd78..57d3f8f21 100644
--- a/src/charon/plugins/eap_radius/radius_client.c
+++ b/src/charon/plugins/eap_radius/radius_client.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "radius_client.h"
diff --git a/src/charon/plugins/eap_radius/radius_client.h b/src/charon/plugins/eap_radius/radius_client.h
index 2207b8713..889861a16 100644
--- a/src/charon/plugins/eap_radius/radius_client.h
+++ b/src/charon/plugins/eap_radius/radius_client.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_radius/radius_message.c b/src/charon/plugins/eap_radius/radius_message.c
index a95d2bb93..59a639f31 100644
--- a/src/charon/plugins/eap_radius/radius_message.c
+++ b/src/charon/plugins/eap_radius/radius_message.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "radius_message.h"
diff --git a/src/charon/plugins/eap_radius/radius_message.h b/src/charon/plugins/eap_radius/radius_message.h
index d195bbe23..d4eec8590 100644
--- a/src/charon/plugins/eap_radius/radius_message.h
+++ b/src/charon/plugins/eap_radius/radius_message.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_sim/Makefile.in b/src/charon/plugins/eap_sim/Makefile.in
index be84728a4..2374567bc 100644
--- a/src/charon/plugins/eap_sim/Makefile.in
+++ b/src/charon/plugins/eap_sim/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -320,7 +329,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_sim/eap_sim.c b/src/charon/plugins/eap_sim/eap_sim.c
index 6110e823c..2dd6e534b 100644
--- a/src/charon/plugins/eap_sim/eap_sim.c
+++ b/src/charon/plugins/eap_sim/eap_sim.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_sim.c 4755 2008-12-04 10:10:37Z martin $
*/
#include "eap_sim.h"
@@ -571,7 +569,7 @@ static bool get_card_triplet(private_eap_sim_t *this,
enumerator->destroy(enumerator);
if (!card)
{
- DBG1(DBG_IKE, "no SIM card found matching '%D'", this->peer);
+ DBG1(DBG_IKE, "no SIM card found matching '%Y'", this->peer);
}
return success;
}
@@ -775,7 +773,7 @@ static bool get_provider_triplet(private_eap_sim_t *this,
tried++;
}
enumerator->destroy(enumerator);
- DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%D'",
+ DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'",
tried, this->peer);
return FALSE;
}
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.c b/src/charon/plugins/eap_sim/eap_sim_plugin.c
index d937c57b4..cf18007c0 100644
--- a/src/charon/plugins/eap_sim/eap_sim_plugin.c
+++ b/src/charon/plugins/eap_sim/eap_sim_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_sim_plugin.c 3491 2008-02-22 14:04:00Z martin $
*/
#include "eap_sim_plugin.h"
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.h b/src/charon/plugins/eap_sim/eap_sim_plugin.h
index d90a72092..767eb65a5 100644
--- a/src/charon/plugins/eap_sim/eap_sim_plugin.h
+++ b/src/charon/plugins/eap_sim/eap_sim_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_sim_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/eap_sim_file/Makefile.in b/src/charon/plugins/eap_sim_file/Makefile.in
index 9396b98cf..554b3a7bc 100644
--- a/src/charon/plugins/eap_sim_file/Makefile.in
+++ b/src/charon/plugins/eap_sim_file/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -91,6 +91,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -113,6 +114,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -124,6 +128,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -137,6 +142,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -197,6 +204,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -208,6 +216,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -230,8 +239,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -328,7 +337,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c
index 7969007d0..7d441ffb2 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_sim_file_card.h"
@@ -52,13 +50,13 @@ static bool get_triplet(private_eap_sim_file_card_t *this,
identification_t *id;
char *c_rand, *c_sres, *c_kc;
-
- DBG1(DBG_CFG, "looking for rand: %b", rand, RAND_LEN);
+ DBG2(DBG_CFG, "looking for rand: %b", rand, RAND_LEN);
enumerator = this->triplets->create_enumerator(this->triplets);
while (enumerator->enumerate(enumerator, &id, &c_rand, &c_sres, &c_kc))
{
- DBG1(DBG_CFG, "found triplet: %b %b %b", c_rand, RAND_LEN, c_sres, SRES_LEN, c_kc, KC_LEN);
+ DBG2(DBG_CFG, "found triplet: rand %b\nsres %b\n kc %b",
+ c_rand, RAND_LEN, c_sres, SRES_LEN, c_kc, KC_LEN);
if (memeq(c_rand, rand, RAND_LEN))
{
memcpy(sres, c_sres, SRES_LEN);
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_card.h b/src/charon/plugins/eap_sim_file/eap_sim_file_card.h
index 9f28aa8fc..e7160a33b 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_card.h
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_card.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.c b/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.c
index 6129ebb72..eb6fb4c9c 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.c
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_sim_file_plugin.h"
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.h b/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.h
index 8e603258f..24857d0b0 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.h
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c
index ffb4b2901..89866ade6 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_sim_file_provider.h"
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.h b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.h
index efd73802a..ec3bfb469 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.h
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c
index 409e9cbd5..d093851c2 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "eap_sim_file_triplets.h"
@@ -45,16 +43,16 @@ struct private_eap_sim_file_triplets_t {
* mutex to lock triplets list
*/
mutex_t *mutex;
-};
+};
/**
* A single triplet
- */
-typedef struct {
- identification_t *imsi;
- char rand[RAND_LEN];
- char sres[SRES_LEN];
- char kc[KC_LEN];
+ */
+typedef struct {
+ identification_t *imsi;
+ char rand[RAND_LEN];
+ char sres[SRES_LEN];
+ char kc[KC_LEN];
} triplet_t;
/**
@@ -105,7 +103,7 @@ static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **ims
char **rand, char **sres, char **kc)
{
triplet_t *triplet;
-
+
if (e->inner->enumerate(e->inner, &triplet))
{
e->current = triplet;
@@ -148,45 +146,45 @@ static void parse_token(char *to, char *from, size_t len)
memset(to, 0, len);
memcpy(to + len - chunk.len, chunk.ptr, chunk.len);
free(chunk.ptr);
-}
-
-/**
- * Read the triplets from the file
- */
-static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
-{
- char line[512];
- FILE *file;
- int i, nr = 0;
-
- file = fopen(path, "r");
- if (file == NULL)
- {
+}
+
+/**
+ * Read the triplets from the file
+ */
+static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
+{
+ char line[512];
+ FILE *file;
+ int i, nr = 0;
+
+ file = fopen(path, "r");
+ if (file == NULL)
+ {
DBG1(DBG_CFG, "opening triplet file %s failed: %s",
- path, strerror(errno));
- return;
- }
-
- /* read line by line */
- while (fgets(line, sizeof(line), file))
- {
+ path, strerror(errno));
+ return;
+ }
+
+ /* read line by line */
+ while (fgets(line, sizeof(line), file))
+ {
triplet_t *triplet;
enumerator_t *enumerator;
char *token;
-
- nr++;
- /* skip comments, empty lines */
- switch (line[0])
- {
- case '\n':
- case '\r':
- case '#':
- case '\0':
- continue;
- default:
- break;
+
+ nr++;
+ /* skip comments, empty lines */
+ switch (line[0])
+ {
+ case '\n':
+ case '\r':
+ case '#':
+ case '\0':
+ continue;
+ default:
+ break;
}
- triplet = malloc_thing(triplet_t);
+ triplet = malloc_thing(triplet_t);
memset(triplet, 0, sizeof(triplet_t));
i = 0;
@@ -196,8 +194,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
switch (i++)
{
case 0: /* IMSI */
- triplet->imsi = identification_create_from_encoding(ID_EAP,
- chunk_create(token, strlen(token)));
+ triplet->imsi = identification_create_from_string(token);
continue;
case 1: /* rand */
parse_token(triplet->rand, token, RAND_LEN);
@@ -215,22 +212,22 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
}
enumerator->destroy(enumerator);
if (i < 4)
- {
+ {
DBG1(DBG_CFG, "error in triplet file, line %d", nr);
triplet_destroy(triplet);
continue;
- }
-
- DBG1(DBG_CFG, "triplet: imsi %D\nrand %b\nsres %b\nkc %b",
- triplet->imsi, triplet->rand, RAND_LEN,
+ }
+
+ DBG2(DBG_CFG, "triplet: imsi %Y\nrand %b\nsres %b\nkc %b",
+ triplet->imsi, triplet->rand, RAND_LEN,
triplet->sres, SRES_LEN, triplet->kc, KC_LEN);
- this->triplets->insert_last(this->triplets, triplet);
- }
+ this->triplets->insert_last(this->triplets, triplet);
+ }
fclose(file);
-
+
DBG1(DBG_CFG, "read %d triplets from %s",
- this->triplets->get_count(this->triplets), path);
+ this->triplets->get_count(this->triplets), path);
}
/**
diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.h b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.h
index a6e9188a5..d4ff2a781 100644
--- a/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.h
+++ b/src/charon/plugins/eap_sim_file/eap_sim_file_triplets.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -28,17 +26,17 @@
/**
* size of RAND value
- */
+ */
#define RAND_LEN 16
/**
* size of SRES value
- */
+ */
#define SRES_LEN 4
/**
* size of KC value
- */
+ */
#define KC_LEN 8
typedef struct eap_sim_file_triplets_t eap_sim_file_triplets_t;
@@ -46,7 +44,7 @@ typedef struct eap_sim_file_triplets_t eap_sim_file_triplets_t;
/**
* Reads triplets from a triplets.dat file.
*
- * The file is in freeradius triplet file syntax:
+ * The file is in freeradius triplet file syntax:
* http://www.freeradius.org/radiusd/doc/rlm_sim_triplets
*/
struct eap_sim_file_triplets_t {
diff --git a/src/charon/plugins/kernel_klips/Makefile.in b/src/charon/plugins/kernel_klips/Makefile.in
index 4e3312f2b..a1efe9d5a 100644
--- a/src/charon/plugins/kernel_klips/Makefile.in
+++ b/src/charon/plugins/kernel_klips/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,6 +215,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
index b2811aa9d..c69ce4c9a 100644
--- a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_klips_ipsec.c 4793 2008-12-11 13:39:30Z tobias $
*/
#include <sys/types.h>
@@ -1530,7 +1528,7 @@ static void schedule_expire(private_kernel_klips_ipsec_t *this,
expire->reqid = reqid;
expire->type = type;
job = callback_job_create((callback_job_cb_t)sa_expires, expire, free, NULL);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, time * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, time);
}
/**
@@ -1938,8 +1936,9 @@ static status_t update_sa(private_kernel_klips_ipsec_t *this,
/**
* Implementation of kernel_interface_t.del_sa.
*/
-static status_t del_sa(private_kernel_klips_ipsec_t *this, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+static status_t del_sa(private_kernel_klips_ipsec_t *this, host_t *src,
+ host_t *dst, u_int32_t spi, protocol_id_t protocol,
+ u_int16_t cpi)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -2610,7 +2609,7 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
- this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
+ this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.interface.del_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
diff --git a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.h b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.h
index 4d4e33813..306ec0ada 100644
--- a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.h
+++ b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_klips_ipsec.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_klips/kernel_klips_plugin.c b/src/charon/plugins/kernel_klips/kernel_klips_plugin.c
index 42d7307ec..d153ea8af 100644
--- a/src/charon/plugins/kernel_klips/kernel_klips_plugin.c
+++ b/src/charon/plugins/kernel_klips/kernel_klips_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_klips_plugin.c 4617 2008-11-11 08:45:19Z tobias $
*/
diff --git a/src/charon/plugins/kernel_klips/kernel_klips_plugin.h b/src/charon/plugins/kernel_klips/kernel_klips_plugin.h
index 8dd2f1895..123550bf5 100644
--- a/src/charon/plugins/kernel_klips/kernel_klips_plugin.h
+++ b/src/charon/plugins/kernel_klips/kernel_klips_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_klips_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_netlink/Makefile.in b/src/charon/plugins/kernel_netlink/Makefile.in
index b3b161315..b97738bff 100644
--- a/src/charon/plugins/kernel_netlink/Makefile.in
+++ b/src/charon/plugins/kernel_netlink/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -91,6 +91,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -113,6 +114,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -124,6 +128,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -137,6 +142,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -197,6 +204,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -208,6 +216,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -228,8 +237,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -326,7 +335,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index ee47914d3..9322d8dfe 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -16,8 +16,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_ipsec.c 4997 2009-03-24 10:24:58Z martin $
*/
#include <sys/types.h>
@@ -170,14 +168,20 @@ static kernel_algorithm_t encryption_algs[] = {
/* {ENCR_DES_IV32, "***" }, */
{ENCR_NULL, "cipher_null" },
{ENCR_AES_CBC, "aes" },
-/* {ENCR_AES_CTR, "***" }, */
+ {ENCR_AES_CTR, "rfc3686(ctr(aes))" },
{ENCR_AES_CCM_ICV8, "rfc4309(ccm(aes))" },
{ENCR_AES_CCM_ICV12, "rfc4309(ccm(aes))" },
{ENCR_AES_CCM_ICV16, "rfc4309(ccm(aes))" },
{ENCR_AES_GCM_ICV8, "rfc4106(gcm(aes))" },
{ENCR_AES_GCM_ICV12, "rfc4106(gcm(aes))" },
{ENCR_AES_GCM_ICV16, "rfc4106(gcm(aes))" },
- {END_OF_LIST, NULL },
+/* {ENCR_NULL_AUTH_AES_GMAC, "***" }, */
+ {ENCR_CAMELLIA_CBC, "cbc(camellia)" },
+/* {ENCR_CAMELLIA_CTR, "***" }, */
+/* {ENCR_CAMELLIA_CCM_ICV8, "***" }, */
+/* {ENCR_CAMELLIA_CCM_ICV12, "***" }, */
+/* {ENCR_CAMELLIA_CCM_ICV16, "***" }, */
+ {END_OF_LIST, NULL }
};
/**
@@ -192,7 +196,7 @@ static kernel_algorithm_t integrity_algs[] = {
/* {AUTH_DES_MAC, "***" }, */
/* {AUTH_KPDK_MD5, "***" }, */
{AUTH_AES_XCBC_96, "xcbc(aes)" },
- {END_OF_LIST, NULL },
+ {END_OF_LIST, NULL }
};
/**
@@ -203,7 +207,7 @@ static kernel_algorithm_t compression_algs[] = {
{IPCOMP_DEFLATE, "deflate" },
{IPCOMP_LZS, "lzs" },
{IPCOMP_LZJH, "lzjh" },
- {END_OF_LIST, NULL },
+ {END_OF_LIST, NULL }
};
/**
@@ -369,6 +373,24 @@ static protocol_id_t proto_kernel2ike(u_int8_t proto)
}
/**
+ * convert the general ipsec mode to the one defined in xfrm.h
+ */
+static u_int8_t mode2kernel(ipsec_mode_t mode)
+{
+ switch (mode)
+ {
+ case MODE_TRANSPORT:
+ return XFRM_MODE_TRANSPORT;
+ case MODE_TUNNEL:
+ return XFRM_MODE_TUNNEL;
+ case MODE_BEET:
+ return XFRM_MODE_BEET;
+ default:
+ return mode;
+ }
+}
+
+/**
* convert a host_t to a struct xfrm_address
*/
static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
@@ -797,7 +819,7 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
host2xfrm(src, &userspi->info.saddr);
host2xfrm(dst, &userspi->info.id.daddr);
userspi->info.id.proto = proto;
- userspi->info.mode = TRUE; /* tunnel mode */
+ userspi->info.mode = XFRM_MODE_TUNNEL;
userspi->info.reqid = reqid;
userspi->info.family = src->get_family(src);
userspi->min = min;
@@ -935,7 +957,7 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this,
sa->id.spi = spi;
sa->id.proto = proto_ike2kernel(protocol);
sa->family = src->get_family(src);
- sa->mode = mode;
+ sa->mode = mode2kernel(mode);
if (mode == MODE_TUNNEL)
{
sa->flags |= XFRM_STATE_AF_UNSPEC;
@@ -1210,8 +1232,9 @@ static status_t get_replay_state(private_kernel_netlink_ipsec_t *this,
/**
* Implementation of kernel_interface_t.del_sa.
*/
-static status_t del_sa(private_kernel_netlink_ipsec_t *this, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+static status_t del_sa(private_kernel_netlink_ipsec_t *this, host_t *src,
+ host_t *dst, u_int32_t spi, protocol_id_t protocol,
+ u_int16_t cpi)
{
netlink_buf_t request;
struct nlmsghdr *hdr;
@@ -1220,7 +1243,7 @@ static status_t del_sa(private_kernel_netlink_ipsec_t *this, host_t *dst,
/* if IPComp was used, we first delete the additional IPComp SA */
if (cpi)
{
- del_sa(this, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0);
+ del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0);
}
memset(&request, 0, sizeof(request));
@@ -1333,7 +1356,7 @@ static status_t update_sa(private_kernel_netlink_ipsec_t *this,
}
/* delete the old SA (without affecting the IPComp SA) */
- if (del_sa(this, dst, spi, protocol, 0) != SUCCESS)
+ if (del_sa(this, src, dst, spi, protocol, 0) != SUCCESS)
{
DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", ntohl(spi));
free(out);
@@ -1520,7 +1543,7 @@ static status_t add_policy(private_kernel_netlink_ipsec_t *this,
tmpl->reqid = reqid;
tmpl->id.proto = IPPROTO_COMP;
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
- tmpl->mode = mode;
+ tmpl->mode = mode2kernel(mode);
tmpl->optional = direction != POLICY_OUT;
tmpl->family = src->get_family(src);
@@ -1541,7 +1564,7 @@ static status_t add_policy(private_kernel_netlink_ipsec_t *this,
tmpl->reqid = reqid;
tmpl->id.proto = proto_ike2kernel(protocol);
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
- tmpl->mode = mode;
+ tmpl->mode = mode2kernel(mode);
tmpl->family = src->get_family(src);
host2xfrm(src, &tmpl->saddr);
@@ -1865,7 +1888,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
- this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
+ this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.interface.del_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.h b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.h
index 0b65c5213..3a45cce06 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.h
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_ipsec.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c
index 6e4ddffe5..32154a7ea 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_net.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_net.c 4671 2008-11-18 09:52:28Z martin $
*/
#include <sys/socket.h>
@@ -163,7 +161,11 @@ struct private_kernel_netlink_net_t {
* whether to react to RTM_NEWROUTE or RTM_DELROUTE events
*/
bool process_route;
-
+
+ /**
+ * whether to actually install virtual IPs
+ */
+ bool install_virtual_ip;
};
/**
@@ -219,7 +221,7 @@ static void fire_roam_job(private_kernel_netlink_net_t *this, bool address)
now.tv_usec -= 1000000;
}
this->last_roam = now;
- charon->scheduler->schedule_job(charon->scheduler,
+ charon->scheduler->schedule_job_ms(charon->scheduler,
(job_t*)roam_job_create(address), ROAM_DELAY);
}
}
@@ -985,7 +987,12 @@ static status_t add_ip(private_kernel_netlink_net_t *this,
addr_entry_t *addr;
enumerator_t *addrs, *ifaces;
int ifindex;
-
+
+ if (!this->install_virtual_ip)
+ { /* disabled by config */
+ return SUCCESS;
+ }
+
DBG2(DBG_KNL, "adding virtual IP %H", virtual_ip);
this->mutex->lock(this->mutex);
@@ -1059,7 +1066,12 @@ static status_t del_ip(private_kernel_netlink_net_t *this, host_t *virtual_ip)
enumerator_t *addrs, *ifaces;
status_t status;
int ifindex;
-
+
+ if (!this->install_virtual_ip)
+ { /* disabled by config */
+ return SUCCESS;
+ }
+
DBG2(DBG_KNL, "deleting virtual IP %H", virtual_ip);
this->mutex->lock(this->mutex);
@@ -1175,7 +1187,7 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this, int nlmsg_ty
/**
* Implementation of kernel_net_t.add_route.
*/
-status_t add_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
+static status_t add_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
{
return manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL,
@@ -1185,7 +1197,7 @@ status_t add_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
/**
* Implementation of kernel_net_t.del_route.
*/
-status_t del_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
+static status_t del_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
{
return manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen,
@@ -1367,6 +1379,8 @@ kernel_netlink_net_t *kernel_netlink_net_create()
"charon.routing_table_prio", IPSEC_ROUTING_TABLE_PRIO);
this->process_route = lib->settings->get_bool(lib->settings,
"charon.process_route", TRUE);
+ this->install_virtual_ip = lib->settings->get_bool(lib->settings,
+ "charon.install_virtual_ip", TRUE);
this->socket = netlink_socket_create(NETLINK_ROUTE);
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_net.h b/src/charon/plugins/kernel_netlink/kernel_netlink_net.h
index 39b96837b..ff9831d3c 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_net.h
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_net.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_net.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.c
index adc3d585f..77005e871 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_plugin.c 4350 2008-09-18 15:16:43Z tobias $
*/
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.h b/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.h
index f08dbc023..ec6036b98 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.h
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c
index 05bd4e397..7ef7cc56e 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_shared.c 4831 2009-01-09 09:37:13Z andreas $
*/
#include <sys/socket.h>
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.h
index 90e464796..5a70e4d9b 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_shared.h
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_shared.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_netlink_shared.h 4660 2008-11-14 14:23:11Z martin $
*/
#ifndef KERNEL_NETLINK_SHARED_H_
diff --git a/src/charon/plugins/kernel_pfkey/Makefile.in b/src/charon/plugins/kernel_pfkey/Makefile.in
index d606f4a23..df2492ef7 100644
--- a/src/charon/plugins/kernel_pfkey/Makefile.in
+++ b/src/charon/plugins/kernel_pfkey/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,6 +215,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 656c83083..56f0320dc 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2008 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
@@ -12,16 +12,38 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_pfkey_ipsec.c 4793 2008-12-11 13:39:30Z tobias $
*/
#include <sys/types.h>
#include <sys/socket.h>
+
+#ifdef HAVE_NET_PFKEYV2_H
+#include <net/pfkeyv2.h>
+#else
#include <stdint.h>
-#include <linux/ipsec.h>
#include <linux/pfkeyv2.h>
+#endif
+
+#ifdef SADB_X_EXT_NAT_T_TYPE
+#define HAVE_NATT
+#endif
+
+#ifdef HAVE_NETIPSEC_IPSEC_H
+#include <netipsec/ipsec.h>
+#elif defined(HAVE_NETINET6_IPSEC_H)
+#include <netinet6/ipsec.h>
+#else
+#include <linux/ipsec.h>
+#endif
+
+#ifdef HAVE_NATT
+#ifdef HAVE_NETINET_UDP_H
+#include <netinet/udp.h>
+#else
#include <linux/udp.h>
+#endif /*HAVE_NETINET_UDP_H*/
+#endif /*HAVE_NATT*/
+
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
@@ -38,6 +60,30 @@
#include <processing/jobs/delete_child_sa_job.h>
#include <processing/jobs/update_sa_job.h>
+/** non linux specific */
+#ifndef IPPROTO_COMP
+#define IPPROTO_COMP IPPROTO_IPCOMP
+#endif
+
+#ifndef SADB_X_AALG_SHA2_256HMAC
+#define SADB_X_AALG_SHA2_256HMAC SADB_X_AALG_SHA2_256
+#define SADB_X_AALG_SHA2_384HMAC SADB_X_AALG_SHA2_384
+#define SADB_X_AALG_SHA2_512HMAC SADB_X_AALG_SHA2_512
+#endif
+
+#ifndef SADB_X_EALG_AESCBC
+#define SADB_X_EALG_AESCBC SADB_X_EALG_AES
+#endif
+
+#ifndef SADB_X_EALG_CASTCBC
+#define SADB_X_EALG_CASTCBC SADB_X_EALG_CAST128CBC
+#endif
+
+#ifndef SOL_IP
+#define SOL_IP IPPROTO_IP
+#define SOL_IPV6 IPPROTO_IPV6
+#endif
+
/** from linux/in.h */
#ifndef IP_IPSEC_POLICY
#define IP_IPSEC_POLICY 16
@@ -46,7 +92,7 @@
/* missing on uclibc */
#ifndef IPV6_IPSEC_POLICY
#define IPV6_IPSEC_POLICY 34
-#endif /*IPV6_IPSEC_POLICY*/
+#endif
/** default priority of installed policies */
#define PRIO_LOW 3000
@@ -160,8 +206,8 @@ struct route_entry_t {
static void route_entry_destroy(route_entry_t *this)
{
free(this->if_name);
- this->src_ip->destroy(this->src_ip);
- this->gateway->destroy(this->gateway);
+ DESTROY_IF(this->src_ip);
+ DESTROY_IF(this->gateway);
chunk_free(&this->dst_net);
free(this);
}
@@ -217,7 +263,7 @@ static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts,
/* src or dest proto may be "any" (0), use more restrictive one */
policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts));
- policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY;
+ policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY;
policy->dst.proto = policy->src.proto;
return policy;
@@ -268,7 +314,6 @@ struct pfkey_msg_t
*/
struct sadb_msg *msg;
-
/**
* PF_KEY message extensions
*/
@@ -305,7 +350,7 @@ struct pfkey_msg_t
};
};
-ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_X_EXT_KMADDRESS,
+ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_EXT_MAX,
"SADB_EXT_RESERVED",
"SADB_EXT_SA",
"SADB_EXT_LIFETIME_CURRENT",
@@ -333,6 +378,7 @@ ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_X_EXT_KMADDRESS,
"SADB_X_EXT_SEC_CTX",
"SADB_X_EXT_KMADDRESS"
);
+
/**
* convert a IKEv2 specific protocol identifier to the PF_KEY sa type
*/
@@ -396,8 +442,10 @@ static u_int8_t mode2kernel(ipsec_mode_t mode)
return IPSEC_MODE_TRANSPORT;
case MODE_TUNNEL:
return IPSEC_MODE_TUNNEL;
+#ifdef HAVE_IPSEC_MODE_BEET
case MODE_BEET:
return IPSEC_MODE_BEET;
+#endif
default:
return mode;
}
@@ -414,13 +462,16 @@ static u_int8_t dir2kernel(policy_dir_t dir)
return IPSEC_DIR_INBOUND;
case POLICY_OUT:
return IPSEC_DIR_OUTBOUND;
+#ifdef HAVE_IPSEC_DIR_FWD
case POLICY_FWD:
return IPSEC_DIR_FWD;
+#endif
default:
return dir;
}
}
+#ifdef SADB_X_MIGRATE
/**
* convert the policy direction in ipsec.h to the general one.
*/
@@ -432,12 +483,16 @@ static policy_dir_t kernel2dir(u_int8_t dir)
return POLICY_IN;
case IPSEC_DIR_OUTBOUND:
return POLICY_OUT;
+#ifdef HAVE_IPSEC_DIR_FWD
case IPSEC_DIR_FWD:
return POLICY_FWD;
+#endif
default:
return dir;
}
}
+#endif /*SADB_X_MIGRATE*/
+
typedef struct kernel_algorithm_t kernel_algorithm_t;
/**
@@ -461,40 +516,42 @@ struct kernel_algorithm_t {
* Algorithms for encryption
*/
static kernel_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, 0 }, */
- {ENCR_DES, SADB_EALG_DESCBC },
- {ENCR_3DES, SADB_EALG_3DESCBC },
-/* {ENCR_RC5, 0 }, */
-/* {ENCR_IDEA, 0 }, */
- {ENCR_CAST, SADB_X_EALG_CASTCBC },
- {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC },
-/* {ENCR_3IDEA, 0 }, */
-/* {ENCR_DES_IV32, 0 }, */
- {ENCR_NULL, SADB_EALG_NULL },
- {ENCR_AES_CBC, SADB_X_EALG_AESCBC },
-/* {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, */
+/* {ENCR_DES_IV64, 0 }, */
+ {ENCR_DES, SADB_EALG_DESCBC },
+ {ENCR_3DES, SADB_EALG_3DESCBC },
+/* {ENCR_RC5, 0 }, */
+/* {ENCR_IDEA, 0 }, */
+ {ENCR_CAST, SADB_X_EALG_CASTCBC },
+ {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC },
+/* {ENCR_3IDEA, 0 }, */
+/* {ENCR_DES_IV32, 0 }, */
+ {ENCR_NULL, SADB_EALG_NULL },
+ {ENCR_AES_CBC, SADB_X_EALG_AESCBC },
+/* {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, */
/* {ENCR_AES_CCM_ICV8, SADB_X_EALG_AES_CCM_ICV8 }, */
/* {ENCR_AES_CCM_ICV12, SADB_X_EALG_AES_CCM_ICV12 }, */
/* {ENCR_AES_CCM_ICV16, SADB_X_EALG_AES_CCM_ICV16 }, */
/* {ENCR_AES_GCM_ICV8, SADB_X_EALG_AES_GCM_ICV8 }, */
/* {ENCR_AES_GCM_ICV12, SADB_X_EALG_AES_GCM_ICV12 }, */
/* {ENCR_AES_GCM_ICV16, SADB_X_EALG_AES_GCM_ICV16 }, */
- {END_OF_LIST, 0 },
+ {END_OF_LIST, 0 },
};
/**
* Algorithms for integrity protection
*/
static kernel_algorithm_t integrity_algs[] = {
- {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC },
+ {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC },
{AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC },
{AUTH_HMAC_SHA2_256_128, SADB_X_AALG_SHA2_256HMAC },
{AUTH_HMAC_SHA2_384_192, SADB_X_AALG_SHA2_384HMAC },
{AUTH_HMAC_SHA2_512_256, SADB_X_AALG_SHA2_512HMAC },
/* {AUTH_DES_MAC, 0, }, */
/* {AUTH_KPDK_MD5, 0, }, */
+#ifdef SADB_X_AALG_AES_XCBC_MAC
{AUTH_AES_XCBC_96, SADB_X_AALG_AES_XCBC_MAC, },
- {END_OF_LIST, 0, },
+#endif
+ {END_OF_LIST, 0, },
};
#if 0
@@ -502,11 +559,11 @@ static kernel_algorithm_t integrity_algs[] = {
* Algorithms for IPComp, unused yet
*/
static kernel_algorithm_t compression_algs[] = {
-/* {IPCOMP_OUI, 0 }, */
+/* {IPCOMP_OUI, 0 }, */
{IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE },
{IPCOMP_LZS, SADB_X_CALG_LZS },
{IPCOMP_LZJH, SADB_X_CALG_LZJH },
- {END_OF_LIST, 0 },
+ {END_OF_LIST, 0 },
};
#endif
@@ -533,8 +590,11 @@ static void host2ext(host_t *host, struct sadb_address *ext)
{
sockaddr_t *host_addr = host->get_sockaddr(host);
socklen_t *len = host->get_sockaddr_len(host);
- memcpy((char*)(ext + 1), host_addr, *len);
- ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + *len);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ host_addr->sa_len = *len;
+#endif
+ memcpy((char*)(ext + 1), host_addr, *len);
+ ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + *len);
}
/**
@@ -562,10 +622,14 @@ static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type)
addr->sadb_address_exttype = type;
sockaddr_t *saddr = (sockaddr_t*)(addr + 1);
saddr->sa_family = family;
- addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+ saddr->sa_len = len;
+#endif
+ addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
PFKEY_EXT_ADD(msg, addr);
}
+#ifdef HAVE_NATT
/**
* add udp encap extensions to a sadb_msg
*/
@@ -592,6 +656,7 @@ static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst)
nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst));
PFKEY_EXT_ADD(msg, nat_port);
}
+#endif /*HAVE_NATT*/
/**
* Convert a sadb_address to a traffic_selector
@@ -606,7 +671,7 @@ static traffic_selector_t* sadb_address2ts(struct sadb_address *address)
*/
host = host_create_from_sockaddr((sockaddr_t*)&address[1]) ;
ts = traffic_selector_create_from_subnet(host, address->sadb_address_prefixlen,
- address->sadb_address_proto, host->get_port(host));
+ address->sadb_address_proto, host->get_port(host));
return ts;
}
@@ -645,7 +710,7 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out)
if (out->ext[ext->sadb_ext_type])
{
- DBG1(DBG_KNL, "duplicate %N extension",
+ DBG1(DBG_KNL, "duplicate %N extension",
sadb_ext_type_names, ext->sadb_ext_type);
break;
}
@@ -699,7 +764,7 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
}
while (TRUE)
- {
+ {
msg = (struct sadb_msg*)buf;
len = recv(socket, buf, sizeof(buf), 0);
@@ -757,7 +822,7 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
*out_len = len;
*out = (struct sadb_msg*)malloc(len);
memcpy(*out, buf, len);
-
+
this->mutex_pfkey->unlock(this->mutex_pfkey);
return SUCCESS;
@@ -868,8 +933,9 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
charon->processor->queue_job(charon->processor, job);
}
+#ifdef SADB_X_MIGRATE
/**
- * Process a SADB_MIGRATE message from the kernel
+ * Process a SADB_X_MIGRATE message from the kernel
*/
static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
{
@@ -893,7 +959,7 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts,
policy_dir_names, dir);
- /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */
+ /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */
if (response.x_kmaddress)
{
sockaddr_t *local_addr, *remote_addr;
@@ -924,7 +990,9 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
DESTROY_IF(remote);
}
}
+#endif /*SADB_X_MIGRATE*/
+#ifdef HAVE_NATT
/**
* Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel
*/
@@ -980,6 +1048,7 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
}
}
}
+#endif /*HAVE_NATT*/
/**
* Receives events from kernel
@@ -991,7 +1060,7 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
int len, oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- len = recv(this->socket_events, buf, sizeof(buf), 0);
+ len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
pthread_setcancelstate(oldstate, NULL);
if (len < 0)
@@ -1035,12 +1104,16 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
case SADB_EXPIRE:
process_expire(this, msg);
break;
+#ifdef SADB_X_MIGRATE
case SADB_X_MIGRATE:
process_migrate(this, msg);
break;
+#endif /*SADB_X_MIGRATE*/
+#ifdef HAVE_NATT
case SADB_X_NAT_T_NEW_MAPPING:
process_mapping(this, msg);
break;
+#endif /*HAVE_NATT*/
default:
break;
}
@@ -1051,8 +1124,8 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
/**
* Implementation of kernel_interface_t.get_spi.
*/
-static status_t get_spi(private_kernel_pfkey_ipsec_t *this,
- host_t *src, host_t *dst,
+static status_t get_spi(private_kernel_pfkey_ipsec_t *this,
+ host_t *src, host_t *dst,
protocol_id_t protocol, u_int32_t reqid,
u_int32_t *spi)
{
@@ -1099,7 +1172,7 @@ static status_t get_spi(private_kernel_pfkey_ipsec_t *this,
{
received_spi = response.sa->sadb_sa_spi;
}
- free(out);
+ free(out);
}
if (received_spi == 0)
@@ -1114,8 +1187,8 @@ static status_t get_spi(private_kernel_pfkey_ipsec_t *this,
/**
* Implementation of kernel_interface_t.get_cpi.
*/
-static status_t get_cpi(private_kernel_pfkey_ipsec_t *this,
- host_t *src, host_t *dst,
+static status_t get_cpi(private_kernel_pfkey_ipsec_t *this,
+ host_t *src, host_t *dst,
u_int32_t reqid, u_int16_t *cpi)
{
return FAILED;
@@ -1226,11 +1299,13 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this,
{
/*TODO*/
}
-
+
+#ifdef HAVE_NATT
if (encap)
{
add_encap_ext(msg, src, dst);
}
+#endif /*HAVE_NATT*/
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
@@ -1346,11 +1421,13 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this,
{
PFKEY_EXT_COPY(msg, response.key_auth);
}
-
+
+#ifdef HAVE_NATT
if (new_encap)
{
add_encap_ext(msg, new_src, new_dst);
}
+#endif /*HAVE_NATT*/
free(out);
@@ -1374,8 +1451,9 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this,
/**
* Implementation of kernel_interface_t.del_sa.
*/
-static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *src,
+ host_t *dst, u_int32_t spi, protocol_id_t protocol,
+ u_int16_t cpi)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1398,9 +1476,8 @@ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *dst,
sa->sadb_sa_spi = spi;
PFKEY_EXT_ADD(msg, sa);
- /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though
- * it is not used for anything. */
- add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC);
+ /* the Linux Kernel doesn't care for the src address, but other systems do (e.g. FreeBSD) */
+ add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
@@ -1424,7 +1501,7 @@ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *dst,
/**
* Implementation of kernel_interface_t.add_policy.
*/
-static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
+static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
host_t *src, host_t *dst,
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
@@ -1463,7 +1540,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
this->policies->insert_last(this->policies, policy);
policy->refcount = 1;
}
-
+
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
@@ -1480,12 +1557,14 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
pol->sadb_x_policy_id = 0;
pol->sadb_x_policy_dir = dir2kernel(direction);
+ pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
+#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY
/* calculate priority based on source selector size, small size = high prio */
pol->sadb_x_policy_priority = routed ? PRIO_LOW : PRIO_HIGH;
pol->sadb_x_policy_priority -= policy->src.mask * 10;
pol->sadb_x_policy_priority -= policy->src.proto != IPSEC_PROTO_ANY ? 2 : 0;
pol->sadb_x_policy_priority -= policy->src.net->get_port(policy->src.net) ? 1 : 0;
- pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
+#endif
/* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */
req = (struct sadb_x_ipsecrequest*)(pol + 1);
@@ -1599,9 +1678,9 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
{
free(route);
}
- }
+ }
- this->mutex->unlock(this->mutex);
+ this->mutex->unlock(this->mutex);
return SUCCESS;
}
@@ -1610,7 +1689,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this,
* Implementation of kernel_interface_t.query_policy.
*/
static status_t query_policy(private_kernel_pfkey_ipsec_t *this,
- traffic_selector_t *src_ts,
+ traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, u_int32_t *use_time)
{
@@ -1689,7 +1768,7 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this,
*use_time = response.lft_current->sadb_lifetime_usetime;
free(out);
-
+
return SUCCESS;
}
@@ -1697,7 +1776,7 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this,
* Implementation of kernel_interface_t.del_policy.
*/
static status_t del_policy(private_kernel_pfkey_ipsec_t *this,
- traffic_selector_t *src_ts,
+ traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, bool unrouted)
{
@@ -1722,7 +1801,7 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this,
if (--found->refcount > 0)
{
/* is used by more SAs, keep in kernel */
- DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
+ DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
policy_entry_destroy(policy);
this->mutex->unlock(this->mutex);
return SUCCESS;
@@ -1741,7 +1820,7 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this,
return NOT_FOUND;
}
this->mutex->unlock(this->mutex);
-
+
memset(&request, 0, sizeof(request));
msg = (struct sadb_msg*)request;
@@ -1791,7 +1870,7 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this,
DBG1(DBG_KNL, "error uninstalling route installed with "
"policy %R === %R %N", src_ts, dst_ts,
policy_dir_names, direction);
- }
+ }
route_entry_destroy(route);
}
@@ -1863,22 +1942,26 @@ static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this)
switch (family)
{
case AF_INET:
+ {
sol = SOL_IP;
ipsec_policy = IP_IPSEC_POLICY;
break;
+ }
case AF_INET6:
{
sol = SOL_IPV6;
ipsec_policy = IPV6_IPSEC_POLICY;
break;
}
+ default:
+ continue;
}
memset(&policy, 0, sizeof(policy));
policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
-
+
policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
@@ -1890,7 +1973,7 @@ static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this)
policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
+ DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
strerror(errno));
status = FALSE;
break;
@@ -1912,7 +1995,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
- this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
+ this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.interface.del_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h
index db05462f4..649f93733 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_pfkey_ipsec.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c
index 93015d75a..09dc4780d 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_pfkey_plugin.c 4361 2008-10-01 16:47:51Z tobias $
*/
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.h b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.h
index f091c6d81..2f168aa9c 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.h
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: kernel_pfkey_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/kernel_pfroute/Makefile.am b/src/charon/plugins/kernel_pfroute/Makefile.am
new file mode 100644
index 000000000..3ad445c09
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/Makefile.am
@@ -0,0 +1,10 @@
+
+INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la
+
+libstrongswan_kernel_pfroute_la_SOURCES = kernel_pfroute_plugin.h kernel_pfroute_plugin.c \
+ kernel_pfroute_net.h kernel_pfroute_net.c
+libstrongswan_kernel_pfroute_la_LDFLAGS = -module
diff --git a/src/charon/plugins/kernel_pfroute/Makefile.in b/src/charon/plugins/kernel_pfroute/Makefile.in
new file mode 100644
index 000000000..e585a7db2
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/Makefile.in
@@ -0,0 +1,510 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/charon/plugins/kernel_pfroute
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_kernel_pfroute_la_LIBADD =
+am_libstrongswan_kernel_pfroute_la_OBJECTS = kernel_pfroute_plugin.lo \
+ kernel_pfroute_net.lo
+libstrongswan_kernel_pfroute_la_OBJECTS = \
+ $(am_libstrongswan_kernel_pfroute_la_OBJECTS)
+libstrongswan_kernel_pfroute_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_kernel_pfroute_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la
+libstrongswan_kernel_pfroute_la_SOURCES = kernel_pfroute_plugin.h kernel_pfroute_plugin.c \
+ kernel_pfroute_net.h kernel_pfroute_net.c
+
+libstrongswan_kernel_pfroute_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfroute/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfroute/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-kernel-pfroute.la: $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_DEPENDENCIES)
+ $(libstrongswan_kernel_pfroute_la_LINK) -rpath $(plugindir) $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_net.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c
new file mode 100644
index 000000000..c2b35a5ce
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (C) 2009 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 <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <net/route.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include "kernel_pfroute_net.h"
+
+#include <daemon.h>
+#include <utils/host.h>
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+#include <processing/jobs/callback_job.h>
+#include <processing/jobs/roam_job.h>
+
+#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
+#error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member.
+#endif
+
+/** delay before firing roam jobs (ms) */
+#define ROAM_DELAY 100
+
+/** buffer size for PF_ROUTE messages */
+#define PFROUTE_BUFFER_SIZE 4096
+
+typedef struct addr_entry_t addr_entry_t;
+
+/**
+ * IP address in an inface_entry_t
+ */
+struct addr_entry_t {
+
+ /** The ip address */
+ host_t *ip;
+
+ /** virtual IP managed by us */
+ bool virtual;
+
+ /** Number of times this IP is used, if virtual */
+ u_int refcount;
+};
+
+/**
+ * destroy a addr_entry_t object
+ */
+static void addr_entry_destroy(addr_entry_t *this)
+{
+ this->ip->destroy(this->ip);
+ free(this);
+}
+
+typedef struct iface_entry_t iface_entry_t;
+
+/**
+ * A network interface on this system, containing addr_entry_t's
+ */
+struct iface_entry_t {
+
+ /** interface index */
+ int ifindex;
+
+ /** name of the interface */
+ char ifname[IFNAMSIZ];
+
+ /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
+ u_int flags;
+
+ /** list of addresses as host_t */
+ linked_list_t *addrs;
+};
+
+/**
+ * destroy an interface entry
+ */
+static void iface_entry_destroy(iface_entry_t *this)
+{
+ this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
+ free(this);
+}
+
+
+typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t;
+
+/**
+ * Private variables and functions of kernel_pfroute class.
+ */
+struct private_kernel_pfroute_net_t
+{
+ /**
+ * Public part of the kernel_pfroute_t object.
+ */
+ kernel_pfroute_net_t public;
+
+ /**
+ * mutex to lock access to various lists
+ */
+ mutex_t *mutex;
+
+ /**
+ * Cached list of interfaces and their addresses (iface_entry_t)
+ */
+ linked_list_t *ifaces;
+
+ /**
+ * job receiving PF_ROUTE events
+ */
+ callback_job_t *job;
+
+ /**
+ * mutex to lock access to the PF_ROUTE socket
+ */
+ mutex_t *mutex_pfroute;
+
+ /**
+ * PF_ROUTE socket to communicate with the kernel
+ */
+ int socket;
+
+ /**
+ * PF_ROUTE socket to receive events
+ */
+ int socket_events;
+
+ /**
+ * sequence number for messages sent to the kernel
+ */
+ int seq;
+
+ /**
+ * time of last roam job
+ */
+ struct timeval last_roam;
+};
+
+/**
+ * Start a roaming job. We delay it a bit and fire only one job
+ * for multiple events. Otherwise we would create too many jobs.
+ */
+static void fire_roam_job(private_kernel_pfroute_net_t *this, bool address)
+{
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) == 0)
+ {
+ if (timercmp(&now, &this->last_roam, >))
+ {
+ now.tv_usec += ROAM_DELAY * 1000;
+ while (now.tv_usec > 1000000)
+ {
+ now.tv_sec++;
+ now.tv_usec -= 1000000;
+ }
+ this->last_roam = now;
+ charon->scheduler->schedule_job_ms(charon->scheduler,
+ (job_t*)roam_job_create(address), ROAM_DELAY);
+ }
+ }
+}
+
+/**
+ * Process an RTM_*ADDR message from the kernel
+ */
+static void process_addr(private_kernel_pfroute_net_t *this,
+ struct rt_msghdr *msg)
+{
+ struct ifa_msghdr *ifa = (struct ifa_msghdr*)msg;
+ sockaddr_t *sockaddr = (sockaddr_t*)(ifa + 1);
+ host_t *host = NULL;
+ enumerator_t *ifaces, *addrs;
+ iface_entry_t *iface;
+ addr_entry_t *addr;
+ bool found = FALSE, changed = FALSE, roam = FALSE;
+ int i;
+
+ for (i = 1; i < (1 << RTAX_MAX); i <<= 1)
+ {
+ if (ifa->ifam_addrs & i)
+ {
+ if (RTA_IFA & i)
+ {
+ host = host_create_from_sockaddr(sockaddr);
+ break;
+ }
+ sockaddr = (sockaddr_t*)((char*)sockaddr + sockaddr->sa_len);
+ }
+ }
+
+ if (!host)
+ {
+ return;
+ }
+
+ this->mutex->lock(this->mutex);
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, &iface))
+ {
+ if (iface->ifindex == ifa->ifam_index)
+ {
+ addrs = iface->addrs->create_enumerator(iface->addrs);
+ while (addrs->enumerate(addrs, &addr))
+ {
+ if (host->ip_equals(host, addr->ip))
+ {
+ found = TRUE;
+ if (ifa->ifam_type == RTM_DELADDR)
+ {
+ iface->addrs->remove_at(iface->addrs, addrs);
+ if (!addr->virtual)
+ {
+ changed = TRUE;
+ DBG1(DBG_KNL, "%H disappeared from %s",
+ host, iface->ifname);
+ }
+ addr_entry_destroy(addr);
+ }
+ else if (ifa->ifam_type == RTM_NEWADDR && addr->virtual)
+ {
+ addr->refcount = 1;
+ }
+ }
+ }
+ addrs->destroy(addrs);
+
+ if (!found && ifa->ifam_type == RTM_NEWADDR)
+ {
+ changed = TRUE;
+ addr = malloc_thing(addr_entry_t);
+ addr->ip = host->clone(host);
+ addr->virtual = FALSE;
+ addr->refcount = 1;
+ iface->addrs->insert_last(iface->addrs, addr);
+ DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
+ }
+
+ if (changed && (iface->flags & IFF_UP))
+ {
+ roam = TRUE;
+ }
+ break;
+ }
+ }
+ ifaces->destroy(ifaces);
+ this->mutex->unlock(this->mutex);
+ host->destroy(host);
+
+ if (roam)
+ {
+ fire_roam_job(this, TRUE);
+ }
+}
+
+/**
+ * Process an RTM_IFINFO message from the kernel
+ */
+static void process_link(private_kernel_pfroute_net_t *this,
+ struct rt_msghdr *hdr)
+{
+ struct if_msghdr *msg = (struct if_msghdr*)hdr;
+ enumerator_t *enumerator;
+ iface_entry_t *iface;
+ bool roam = FALSE;
+
+ if (msg->ifm_flags & IFF_LOOPBACK)
+ { /* ignore loopback interfaces */
+ return;
+ }
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->ifaces->create_enumerator(this->ifaces);
+ while (enumerator->enumerate(enumerator, &iface))
+ {
+ if (iface->ifindex == msg->ifm_index)
+ {
+ if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP))
+ {
+ roam = TRUE;
+ DBG1(DBG_KNL, "interface %s activated", iface->ifname);
+ }
+ else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP))
+ {
+ roam = TRUE;
+ DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
+ }
+ iface->flags = msg->ifm_flags;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ if (roam)
+ {
+ fire_roam_job(this, TRUE);
+ }
+}
+
+/**
+ * Process an RTM_*ROUTE message from the kernel
+ */
+static void process_route(private_kernel_pfroute_net_t *this,
+ struct rt_msghdr *msg)
+{
+
+}
+
+/**
+ * Receives events from kernel
+ */
+static job_requeue_t receive_events(private_kernel_pfroute_net_t *this)
+{
+ unsigned char buf[PFROUTE_BUFFER_SIZE];
+ struct rt_msghdr *msg = (struct rt_msghdr*)buf;
+ int len, oldstate;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+ len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
+ pthread_setcancelstate(oldstate, NULL);
+
+ if (len < 0)
+ {
+ switch (errno)
+ {
+ case EINTR:
+ /* interrupted, try again */
+ return JOB_REQUEUE_DIRECT;
+ case EAGAIN:
+ /* no data ready, select again */
+ return JOB_REQUEUE_DIRECT;
+ default:
+ DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket");
+ sleep(1);
+ return JOB_REQUEUE_FAIR;
+ }
+ }
+
+ if (len < sizeof(msg->rtm_msglen) || len < msg->rtm_msglen ||
+ msg->rtm_version != RTM_VERSION)
+ {
+ DBG2(DBG_KNL, "received corrupted PF_ROUTE message");
+ return JOB_REQUEUE_DIRECT;
+ }
+
+ switch (msg->rtm_type)
+ {
+ case RTM_NEWADDR:
+ case RTM_DELADDR:
+ process_addr(this, msg);
+ break;
+ case RTM_IFINFO:
+ /*case RTM_IFANNOUNCE <- what about this*/
+ process_link(this, msg);
+ break;
+ case RTM_ADD:
+ case RTM_DELETE:
+ process_route(this, msg);
+ default:
+ break;
+ }
+
+ return JOB_REQUEUE_DIRECT;
+}
+
+
+/** enumerator over addresses */
+typedef struct {
+ private_kernel_pfroute_net_t* this;
+ /** whether to enumerate down interfaces */
+ bool include_down_ifaces;
+ /** whether to enumerate virtual ip addresses */
+ bool include_virtual_ips;
+} address_enumerator_t;
+
+/**
+ * cleanup function for address enumerator
+ */
+static void address_enumerator_destroy(address_enumerator_t *data)
+{
+ data->this->mutex->unlock(data->this->mutex);
+ free(data);
+}
+
+/**
+ * filter for addresses
+ */
+static bool filter_addresses(address_enumerator_t *data, addr_entry_t** in, host_t** out)
+{
+ host_t *ip;
+ if (!data->include_virtual_ips && (*in)->virtual)
+ { /* skip virtual interfaces added by us */
+ return FALSE;
+ }
+ ip = (*in)->ip;
+ if (ip->get_family(ip) == AF_INET6)
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
+ if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+ { /* skip addresses with a unusable scope */
+ return FALSE;
+ }
+ }
+ *out = ip;
+ return TRUE;
+}
+
+/**
+ * enumerator constructor for interfaces
+ */
+static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data)
+{
+ return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
+ (void*)filter_addresses, data, NULL);
+}
+
+/**
+ * filter for interfaces
+ */
+static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, iface_entry_t** out)
+{
+ if (!data->include_down_ifaces && !((*in)->flags & IFF_UP))
+ { /* skip interfaces not up */
+ return FALSE;
+ }
+ *out = *in;
+ return TRUE;
+}
+
+/**
+ * implementation of kernel_net_t.create_address_enumerator
+ */
+static enumerator_t *create_address_enumerator(private_kernel_pfroute_net_t *this,
+ bool include_down_ifaces, bool include_virtual_ips)
+{
+ address_enumerator_t *data = malloc_thing(address_enumerator_t);
+ data->this = this;
+ data->include_down_ifaces = include_down_ifaces;
+ data->include_virtual_ips = include_virtual_ips;
+
+ this->mutex->lock(this->mutex);
+ return enumerator_create_nested(
+ enumerator_create_filter(this->ifaces->create_enumerator(this->ifaces),
+ (void*)filter_interfaces, data, NULL),
+ (void*)create_iface_enumerator, data, (void*)address_enumerator_destroy);
+}
+
+/**
+ * implementation of kernel_net_t.get_interface_name
+ */
+static char *get_interface_name(private_kernel_pfroute_net_t *this, host_t* ip)
+{
+ enumerator_t *ifaces, *addrs;
+ iface_entry_t *iface;
+ addr_entry_t *addr;
+ char *name = NULL;
+
+ DBG2(DBG_KNL, "getting interface name for %H", ip);
+
+ this->mutex->lock(this->mutex);
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, &iface))
+ {
+ addrs = iface->addrs->create_enumerator(iface->addrs);
+ while (addrs->enumerate(addrs, &addr))
+ {
+ if (ip->ip_equals(ip, addr->ip))
+ {
+ name = strdup(iface->ifname);
+ break;
+ }
+ }
+ addrs->destroy(addrs);
+ if (name)
+ {
+ break;
+ }
+ }
+ ifaces->destroy(ifaces);
+ this->mutex->unlock(this->mutex);
+
+ if (name)
+ {
+ DBG2(DBG_KNL, "%H is on interface %s", ip, name);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "%H is not a local address", ip);
+ }
+ return name;
+}
+
+/**
+ * Implementation of kernel_net_t.get_source_addr.
+ */
+static host_t* get_source_addr(private_kernel_pfroute_net_t *this,
+ host_t *dest, host_t *src)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of kernel_net_t.get_nexthop.
+ */
+static host_t* get_nexthop(private_kernel_pfroute_net_t *this, host_t *dest)
+{
+ return NULL;
+}
+
+/**
+ * Implementation of kernel_net_t.add_ip.
+ */
+static status_t add_ip(private_kernel_pfroute_net_t *this,
+ host_t *virtual_ip, host_t *iface_ip)
+{
+ return FAILED;
+}
+
+/**
+ * Implementation of kernel_net_t.del_ip.
+ */
+static status_t del_ip(private_kernel_pfroute_net_t *this, host_t *virtual_ip)
+{
+ return FAILED;
+}
+
+/**
+ * Implementation of kernel_net_t.add_route.
+ */
+static status_t add_route(private_kernel_pfroute_net_t *this, chunk_t dst_net,
+ u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+{
+ return FAILED;
+}
+
+/**
+ * Implementation of kernel_net_t.del_route.
+ */
+static status_t del_route(private_kernel_pfroute_net_t *this, chunk_t dst_net,
+ u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+{
+ return FAILED;
+}
+
+/**
+ * Initialize a list of local addresses.
+ */
+static status_t init_address_list(private_kernel_pfroute_net_t *this)
+{
+ struct ifaddrs *ifap, *ifa;
+ iface_entry_t *iface, *current;
+ addr_entry_t *addr;
+ enumerator_t *ifaces, *addrs;
+
+ DBG1(DBG_KNL, "listening on interfaces:");
+
+ if (getifaddrs(&ifap) < 0)
+ {
+ DBG1(DBG_KNL, " failed to get interfaces!");
+ return FAILED;
+ }
+
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ {
+ continue;
+ }
+ switch(ifa->ifa_addr->sa_family)
+ {
+ case AF_LINK:
+ case AF_INET:
+ case AF_INET6:
+ {
+ if (ifa->ifa_flags & IFF_LOOPBACK)
+ { /* ignore loopback interfaces */
+ continue;
+ }
+
+ iface = NULL;
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, &current))
+ {
+ if (streq(current->ifname, ifa->ifa_name))
+ {
+ iface = current;
+ break;
+ }
+ }
+ ifaces->destroy(ifaces);
+
+ if (!iface)
+ {
+ iface = malloc_thing(iface_entry_t);
+ memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ);
+ iface->ifindex = if_nametoindex(ifa->ifa_name);
+ iface->flags = ifa->ifa_flags;
+ iface->addrs = linked_list_create();
+ this->ifaces->insert_last(this->ifaces, iface);
+ }
+
+ if (ifa->ifa_addr->sa_family != AF_LINK)
+ {
+ addr = malloc_thing(addr_entry_t);
+ addr->ip = host_create_from_sockaddr(ifa->ifa_addr);
+ addr->virtual = FALSE;
+ addr->refcount = 1;
+ iface->addrs->insert_last(iface->addrs, addr);
+ }
+ }
+ }
+ }
+ freeifaddrs(ifap);
+
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, &iface))
+ {
+ if (iface->flags & IFF_UP)
+ {
+ DBG1(DBG_KNL, " %s", iface->ifname);
+ addrs = iface->addrs->create_enumerator(iface->addrs);
+ while (addrs->enumerate(addrs, (void**)&addr))
+ {
+ DBG1(DBG_KNL, " %H", addr->ip);
+ }
+ addrs->destroy(addrs);
+ }
+ }
+ ifaces->destroy(ifaces);
+
+ return SUCCESS;
+}
+
+/**
+ * Implementation of kernel_netlink_net_t.destroy.
+ */
+static void destroy(private_kernel_pfroute_net_t *this)
+{
+ this->job->cancel(this->job);
+ close(this->socket);
+ close(this->socket_events);
+ this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
+ this->mutex->destroy(this->mutex);
+ this->mutex_pfroute->destroy(this->mutex_pfroute);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+kernel_pfroute_net_t *kernel_pfroute_net_create()
+{
+ private_kernel_pfroute_net_t *this = malloc_thing(private_kernel_pfroute_net_t);
+
+ /* public functions */
+ this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name;
+ this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator;
+ this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr;
+ this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop;
+ this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip;
+ this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip;
+ this->public.interface.add_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route;
+ this->public.interface.del_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route;
+
+ this->public.interface.destroy = (void(*)(kernel_net_t*)) destroy;
+
+ /* private members */
+ this->ifaces = linked_list_create();
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->mutex_pfroute = mutex_create(MUTEX_DEFAULT);
+
+ this->seq = 0;
+
+ /* create a PF_ROUTE socket to communicate with the kernel */
+ this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
+ if (this->socket <= 0)
+ {
+ charon->kill(charon, "unable to create PF_ROUTE socket");
+ }
+
+ /* create a PF_ROUTE socket to receive events */
+ this->socket_events = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
+ if (this->socket_events <= 0)
+ {
+ charon->kill(charon, "unable to create PF_ROUTE event socket");
+ }
+
+ this->job = callback_job_create((callback_job_cb_t)receive_events,
+ this, NULL, NULL);
+ charon->processor->queue_job(charon->processor, (job_t*)this->job);
+
+ if (init_address_list(this) != SUCCESS)
+ {
+ charon->kill(charon, "unable to get interface list");
+ }
+
+ return &this->public;
+}
diff --git a/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.h b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.h
new file mode 100644
index 000000000..10c3c9eb7
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/kernel_pfroute_net.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 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 kernel_pfroute_net_i kernel_pfroute_net
+ * @{ @ingroup kernel_pfroute
+ */
+
+#ifndef KERNEL_PFROUTE_NET_H_
+#define KERNEL_PFROUTE_NET_H_
+
+#include <kernel/kernel_net.h>
+
+typedef struct kernel_pfroute_net_t kernel_pfroute_net_t;
+
+/**
+ * Implementation of the kernel net interface using PF_ROUTE.
+ */
+struct kernel_pfroute_net_t {
+
+ /**
+ * Implements kernel_net_t interface
+ */
+ kernel_net_t interface;
+};
+
+/**
+ * Create a PF_ROUTE kernel net interface instance.
+ *
+ * @return kernel_pfroute_net_t instance
+ */
+kernel_pfroute_net_t *kernel_pfroute_net_create();
+
+#endif /** KERNEL_PFROUTE_NET_H_ @}*/
diff --git a/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.c b/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.c
new file mode 100644
index 000000000..767049bb0
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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 "kernel_pfroute_plugin.h"
+
+#include "kernel_pfroute_net.h"
+
+#include <daemon.h>
+
+typedef struct private_kernel_pfroute_plugin_t private_kernel_pfroute_plugin_t;
+
+/**
+ * private data of kernel PF_ROUTE plugin
+ */
+struct private_kernel_pfroute_plugin_t {
+ /**
+ * implements plugin interface
+ */
+ kernel_pfroute_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_kernel_pfroute_plugin_t *this)
+{
+ charon->kernel_interface->remove_net_interface(charon->kernel_interface,
+ (kernel_net_constructor_t)kernel_pfroute_net_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_kernel_pfroute_plugin_t *this = malloc_thing(private_kernel_pfroute_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ charon->kernel_interface->add_net_interface(charon->kernel_interface,
+ (kernel_net_constructor_t)kernel_pfroute_net_create);
+
+ return &this->public.plugin;
+}
diff --git a/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.h b/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.h
new file mode 100644
index 000000000..6caf097c6
--- /dev/null
+++ b/src/charon/plugins/kernel_pfroute/kernel_pfroute_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 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 kernel_pfroute kernel_pfroute
+ * @ingroup cplugins
+ *
+ * @defgroup kernel_pfroute_plugin kernel_pfroute_plugin
+ * @{ @ingroup kernel_pfroute
+ */
+
+#ifndef KERNEL_PFROUTE_PLUGIN_H_
+#define KERNEL_PFROUTE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct kernel_pfroute_plugin_t kernel_pfroute_plugin_t;
+
+/**
+ * PF_ROUTE kernel interface plugin
+ */
+struct kernel_pfroute_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a kernel_pfroute_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** KERNEL_PFROUTE_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/load_tester/Makefile.in b/src/charon/plugins/load_tester/Makefile.in
index 5a24e83e9..056ac16d3 100644
--- a/src/charon/plugins/load_tester/Makefile.in
+++ b/src/charon/plugins/load_tester/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -92,6 +92,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -114,6 +115,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -125,6 +129,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -138,6 +143,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -198,6 +205,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -209,6 +217,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -233,8 +242,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -333,7 +342,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/load_tester/load_tester_config.c b/src/charon/plugins/load_tester/load_tester_config.c
index f3cd33b61..963f7cc01 100644
--- a/src/charon/plugins/load_tester/load_tester_config.c
+++ b/src/charon/plugins/load_tester/load_tester_config.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_config.h"
@@ -57,9 +55,24 @@ struct private_load_tester_config_t {
proposal_t *proposal;
/**
- * Authentication method to use
+ * Authentication method(s) to use/expect from initiator
*/
- auth_class_t class;
+ char *initiator_auth;
+
+ /**
+ * Authentication method(s) use/expected from responder
+ */
+ char *responder_auth;
+
+ /**
+ * IKE_SA rekeying delay
+ */
+ u_int ike_rekey;
+
+ /**
+ * CHILD_SA rekeying delay
+ */
+ u_int child_rekey;
/**
* incremental numbering of generated configs
@@ -68,6 +81,97 @@ struct private_load_tester_config_t {
};
/**
+ * Generate auth config from string
+ */
+static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
+ peer_cfg_t *peer_cfg, bool local, int num)
+{
+ enumerator_t *enumerator;
+ auth_cfg_t *auth;
+ identification_t *id;
+ auth_class_t class;
+ eap_type_t type;
+ char buf[128];
+ int rnd = 0;
+
+ enumerator = enumerator_create_token(str, "|", " ");
+ while (enumerator->enumerate(enumerator, &str))
+ {
+ auth = auth_cfg_create();
+ rnd++;
+
+ if (streq(str, "psk"))
+ { /* PSK authentication, use FQDNs */
+ class = AUTH_CLASS_PSK;
+ if ((local && !num) || (!local && num))
+ {
+ id = identification_create_from_string("srv.strongswan.org");
+ }
+ else if (local)
+ {
+ snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_string("*.strongswan.org");
+ }
+ }
+ else if (strneq(str, "eap", strlen("eap")))
+ { /* EAP authentication, use a NAI */
+ class = AUTH_CLASS_EAP;
+ if (*(str + strlen("eap")) == '-')
+ {
+ type = eap_type_from_string(str + strlen("eap-"));
+ if (type)
+ {
+ auth->add(auth, AUTH_RULE_EAP_TYPE, type);
+ }
+ }
+ if (local && num)
+ {
+ snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
+ }
+ else
+ {
+ if (!streq(str, "pubkey"))
+ {
+ DBG1(DBG_CFG, "invalid authentication: '%s', fallback to pubkey",
+ str);
+ }
+ /* certificate authentication, use distinguished names */
+ class = AUTH_CLASS_PUBKEY;
+ if ((local && !num) || (!local && num))
+ {
+ id = identification_create_from_string(
+ "CN=srv, OU=load-test, O=strongSwan");
+ }
+ else if (local)
+ {
+ snprintf(buf, sizeof(buf),
+ "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_string(
+ "CN=*, OU=load-test, O=strongSwan");
+ }
+ }
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
+ auth->add(auth, AUTH_RULE_IDENTITY, id);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, local);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* Generate a new initiator config, num = 0 for responder config
*/
static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
@@ -76,36 +180,29 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
child_cfg_t *child_cfg;
peer_cfg_t *peer_cfg;
traffic_selector_t *ts;
- auth_info_t *auth;
- identification_t *local, *remote;
proposal_t *proposal;
- char buf[128];
+ ike_cfg = ike_cfg_create(FALSE, FALSE, "0.0.0.0", this->remote);
+ ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
+ peer_cfg = peer_cfg_create("load-test", 2, ike_cfg,
+ CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */
+ this->ike_rekey, 0, /* rekey, reauth */
+ 0, this->ike_rekey, /* jitter, overtime */
+ FALSE, 0, /* mobike, dpddelay */
+ this->vip ? this->vip->clone(this->vip) : NULL,
+ this->pool, FALSE, NULL, NULL);
if (num)
{ /* initiator */
- snprintf(buf, sizeof(buf), "CN=cli-%d, OU=load-test, O=strongSwan", num);
- local = identification_create_from_string(buf);
- snprintf(buf, sizeof(buf), "CN=srv, OU=load-test, O=strongSwan", num);
- remote = identification_create_from_string(buf);
+ generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
+ generate_auth_cfg(this, this->responder_auth, peer_cfg, FALSE, num);
}
else
{ /* responder */
- local = identification_create_from_string(
- "CN=srv, OU=load-test, O=strongSwan");
- remote = identification_create_from_string(
- "CN=*, OU=load-test, O=strongSwan");
+ generate_auth_cfg(this, this->responder_auth, peer_cfg, TRUE, num);
+ generate_auth_cfg(this, this->initiator_auth, peer_cfg, FALSE, num);
}
-
- ike_cfg = ike_cfg_create(FALSE, FALSE, "0.0.0.0", this->remote);
- ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
- peer_cfg = peer_cfg_create("load-test", 2, ike_cfg, local, remote,
- CERT_SEND_IF_ASKED, UNIQUE_NO, 1, 0, 0, /* keytries, rekey, reauth */
- 0, 0, FALSE, 0, /* jitter, overtime, mobike, dpddelay */
- this->vip ? this->vip->clone(this->vip) : NULL,
- this->pool, FALSE, NULL, NULL);
- auth = peer_cfg->get_auth(peer_cfg);
- auth->add_item(auth, AUTHN_AUTH_CLASS, &this->class);
- child_cfg = child_cfg_create("load-test", 600, 400, 100, NULL, TRUE,
+ child_cfg = child_cfg_create("load-test", this->child_rekey * 2,
+ this->child_rekey, 0, NULL, TRUE,
MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
child_cfg->add_proposal(child_cfg, proposal);
@@ -169,7 +266,6 @@ static void destroy(private_load_tester_config_t *this)
load_tester_config_t *load_tester_config_create()
{
private_load_tester_config_t *this = malloc_thing(private_load_tester_config_t);
- char *authstr;
this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
@@ -195,16 +291,15 @@ load_tester_config_t *load_tester_config_create()
this->proposal = proposal_create_from_string(PROTO_IKE,
"aes128-sha1-modp768");
}
- authstr = lib->settings->get_str(lib->settings,
- "charon.plugins.load_tester.auth", "pubkey");
- if (streq(authstr, "psk"))
- {
- this->class = AUTH_CLASS_PSK;
- }
- else
- {
- this->class = AUTH_CLASS_PUBKEY;
- }
+ this->ike_rekey = lib->settings->get_int(lib->settings,
+ "charon.plugins.load_tester.ike_rekey", 0);
+ this->child_rekey = lib->settings->get_int(lib->settings,
+ "charon.plugins.load_tester.child_rekey", 600);
+
+ this->initiator_auth = lib->settings->get_str(lib->settings,
+ "charon.plugins.load_tester.initiator_auth", "pubkey");
+ this->responder_auth = lib->settings->get_str(lib->settings,
+ "charon.plugins.load_tester.responder_auth", "pubkey");
this->num = 1;
this->peer_cfg = generate_config(this, 0);
diff --git a/src/charon/plugins/load_tester/load_tester_config.h b/src/charon/plugins/load_tester/load_tester_config.h
index 92a0ff95b..f09a3f832 100644
--- a/src/charon/plugins/load_tester/load_tester_config.h
+++ b/src/charon/plugins/load_tester/load_tester_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/load_tester/load_tester_creds.c b/src/charon/plugins/load_tester/load_tester_creds.c
index 476a90b9f..fdb5fa370 100644
--- a/src/charon/plugins/load_tester/load_tester_creds.c
+++ b/src/charon/plugins/load_tester/load_tester_creds.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_creds.h"
diff --git a/src/charon/plugins/load_tester/load_tester_creds.h b/src/charon/plugins/load_tester/load_tester_creds.h
index ed73f14c3..60cf67795 100644
--- a/src/charon/plugins/load_tester/load_tester_creds.h
+++ b/src/charon/plugins/load_tester/load_tester_creds.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/load_tester/load_tester_diffie_hellman.c b/src/charon/plugins/load_tester/load_tester_diffie_hellman.c
index 4cc9dbc48..87d9ef42b 100644
--- a/src/charon/plugins/load_tester/load_tester_diffie_hellman.c
+++ b/src/charon/plugins/load_tester/load_tester_diffie_hellman.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_diffie_hellman.h"
diff --git a/src/charon/plugins/load_tester/load_tester_diffie_hellman.h b/src/charon/plugins/load_tester/load_tester_diffie_hellman.h
index 422428a54..045c4bb4a 100644
--- a/src/charon/plugins/load_tester/load_tester_diffie_hellman.h
+++ b/src/charon/plugins/load_tester/load_tester_diffie_hellman.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/load_tester/load_tester_ipsec.c b/src/charon/plugins/load_tester/load_tester_ipsec.c
index 9abd65195..d37f7a7bd 100644
--- a/src/charon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/charon/plugins/load_tester/load_tester_ipsec.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_ipsec.h"
@@ -88,8 +86,9 @@ static status_t update_sa(private_load_tester_ipsec_t *this,
/**
* Implementation of kernel_interface_t.del_sa.
*/
-static status_t del_sa(private_load_tester_ipsec_t *this, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
+static status_t del_sa(private_load_tester_ipsec_t *this, host_t *src,
+ host_t *dst, u_int32_t spi, protocol_id_t protocol,
+ u_int16_t cpi)
{
return SUCCESS;
}
@@ -152,7 +151,7 @@ load_tester_ipsec_t *load_tester_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
- this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
+ this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t *this,host_t *, host_t *,traffic_selector_t *,traffic_selector_t *,policy_dir_t, u_int32_t,protocol_id_t, u_int32_t,ipsec_mode_t, u_int16_t, u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.interface.del_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy;
diff --git a/src/charon/plugins/load_tester/load_tester_ipsec.h b/src/charon/plugins/load_tester/load_tester_ipsec.h
index 4f374032f..1e1bff84a 100644
--- a/src/charon/plugins/load_tester/load_tester_ipsec.h
+++ b/src/charon/plugins/load_tester/load_tester_ipsec.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/load_tester/load_tester_listener.c b/src/charon/plugins/load_tester/load_tester_listener.c
index fe9e16fe7..fe9a90aed 100644
--- a/src/charon/plugins/load_tester/load_tester_listener.c
+++ b/src/charon/plugins/load_tester/load_tester_listener.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_listener.h"
diff --git a/src/charon/plugins/load_tester/load_tester_listener.h b/src/charon/plugins/load_tester/load_tester_listener.h
index b61da0cb3..6842b3532 100644
--- a/src/charon/plugins/load_tester/load_tester_listener.h
+++ b/src/charon/plugins/load_tester/load_tester_listener.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/load_tester/load_tester_plugin.c b/src/charon/plugins/load_tester/load_tester_plugin.c
index 444a92e2b..12ac7b090 100644
--- a/src/charon/plugins/load_tester/load_tester_plugin.c
+++ b/src/charon/plugins/load_tester/load_tester_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "load_tester_plugin.h"
diff --git a/src/charon/plugins/load_tester/load_tester_plugin.h b/src/charon/plugins/load_tester/load_tester_plugin.h
index e0b64cfef..87e8914e0 100644
--- a/src/charon/plugins/load_tester/load_tester_plugin.h
+++ b/src/charon/plugins/load_tester/load_tester_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medcli/Makefile.in b/src/charon/plugins/medcli/Makefile.in
index 33c08eea8..cef486411 100644
--- a/src/charon/plugins/medcli/Makefile.in
+++ b/src/charon/plugins/medcli/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -227,8 +236,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -325,7 +334,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/medcli/medcli_config.c b/src/charon/plugins/medcli/medcli_config.c
index d1e6c0c9e..3b3332549 100644
--- a/src/charon/plugins/medcli/medcli_config.c
+++ b/src/charon/plugins/medcli/medcli_config.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -97,6 +95,7 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
{
enumerator_t *e;
peer_cfg_t *peer_cfg, *med_cfg;
+ auth_cfg_t *auth;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
chunk_t me, other;
@@ -118,8 +117,6 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
med_cfg = peer_cfg_create(
"mediation", 2, ike_cfg,
- identification_create_from_encoding(ID_KEY_ID, me),
- identification_create_from_encoding(ID_KEY_ID, other),
CERT_NEVER_SEND, UNIQUE_REPLACE,
1, this->rekey*60, 0, /* keytries, rekey, reauth */
this->rekey*5, this->rekey*3, /* jitter, overtime */
@@ -128,6 +125,17 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
TRUE, NULL, NULL); /* mediation, med by, peer id */
e->destroy(e);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, me));
+ med_cfg->add_auth_cfg(med_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, other));
+ med_cfg->add_auth_cfg(med_cfg, auth, FALSE);
+
/* query mediated config:
* - use any-any ike_cfg
* - build peer_cfg on-the-fly using med_cfg
@@ -146,8 +154,6 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
}
peer_cfg = peer_cfg_create(
name, 2, this->ike->get_ref(this->ike),
- identification_create_from_encoding(ID_KEY_ID, me),
- identification_create_from_encoding(ID_KEY_ID, other),
CERT_NEVER_SEND, UNIQUE_REPLACE,
1, this->rekey*60, 0, /* keytries, rekey, reauth */
this->rekey*5, this->rekey*3, /* jitter, overtime */
@@ -156,6 +162,17 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
FALSE, med_cfg, /* mediation, med by */
identification_create_from_encoding(ID_KEY_ID, other));
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, me));
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, other));
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+
child_cfg = child_cfg_create(name, this->rekey*60 + this->rekey,
this->rekey*60, this->rekey, NULL, TRUE,
MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
@@ -199,7 +216,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
char *name, *local_net, *remote_net;
chunk_t me, other;
child_cfg_t *child_cfg;
-
+ auth_cfg_t *auth;
+
DESTROY_IF(this->current);
if (!this->inner->enumerate(this->inner, &name, &me, &other,
&local_net, &remote_net))
@@ -209,14 +227,24 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
}
this->current = peer_cfg_create(
name, 2, this->ike->get_ref(this->ike),
- identification_create_from_encoding(ID_KEY_ID, me),
- identification_create_from_encoding(ID_KEY_ID, other),
CERT_NEVER_SEND, UNIQUE_REPLACE,
1, this->rekey*60, 0, /* keytries, rekey, reauth */
this->rekey*5, this->rekey*3, /* jitter, overtime */
TRUE, this->dpd, /* mobike, dpddelay */
NULL, NULL, /* vip, pool */
FALSE, NULL, NULL); /* mediation, med by, peer id */
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, me));
+ this->current->add_auth_cfg(this->current, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_encoding(ID_KEY_ID, other));
+ this->current->add_auth_cfg(this->current, auth, FALSE);
+
child_cfg = child_cfg_create(
name, this->rekey*60 + this->rekey,
this->rekey*60, this->rekey, NULL, TRUE,
diff --git a/src/charon/plugins/medcli/medcli_config.h b/src/charon/plugins/medcli/medcli_config.h
index 9c0357a26..a37280bd0 100644
--- a/src/charon/plugins/medcli/medcli_config.h
+++ b/src/charon/plugins/medcli/medcli_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medcli/medcli_creds.c b/src/charon/plugins/medcli/medcli_creds.c
index 1e99f6990..d3c66ae35 100644
--- a/src/charon/plugins/medcli/medcli_creds.c
+++ b/src/charon/plugins/medcli/medcli_creds.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "medcli_creds.h"
@@ -96,7 +94,7 @@ static enumerator_t* create_private_enumerator(private_medcli_creds_t *this,
if ((type != KEY_RSA && type != KEY_ANY) ||
id == NULL || id->get_type(id) != ID_KEY_ID)
{
- DBG1(DBG_CFG, "%N - %D", key_type_names, type, id);
+ DBG1(DBG_CFG, "%N - %Y", key_type_names, type, id);
return NULL;
}
diff --git a/src/charon/plugins/medcli/medcli_creds.h b/src/charon/plugins/medcli/medcli_creds.h
index 4e563b4ac..97bf1c226 100644
--- a/src/charon/plugins/medcli/medcli_creds.h
+++ b/src/charon/plugins/medcli/medcli_creds.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medcli/medcli_listener.c b/src/charon/plugins/medcli/medcli_listener.c
index c057ea2b5..4d058c0cd 100644
--- a/src/charon/plugins/medcli/medcli_listener.c
+++ b/src/charon/plugins/medcli/medcli_listener.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "medcli_listener.h"
diff --git a/src/charon/plugins/medcli/medcli_listener.h b/src/charon/plugins/medcli/medcli_listener.h
index 291e66097..c6881f88a 100644
--- a/src/charon/plugins/medcli/medcli_listener.h
+++ b/src/charon/plugins/medcli/medcli_listener.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medcli/medcli_plugin.c b/src/charon/plugins/medcli/medcli_plugin.c
index 1642ed2fe..908b144f0 100644
--- a/src/charon/plugins/medcli/medcli_plugin.c
+++ b/src/charon/plugins/medcli/medcli_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "medcli_plugin.h"
diff --git a/src/charon/plugins/medcli/medcli_plugin.h b/src/charon/plugins/medcli/medcli_plugin.h
index 791a5cea5..06f674b37 100644
--- a/src/charon/plugins/medcli/medcli_plugin.h
+++ b/src/charon/plugins/medcli/medcli_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medsrv/Makefile.in b/src/charon/plugins/medsrv/Makefile.in
index 2e97ca503..ec537e505 100644
--- a/src/charon/plugins/medsrv/Makefile.in
+++ b/src/charon/plugins/medsrv/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -323,7 +332,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/medsrv/medsrv_config.c b/src/charon/plugins/medsrv/medsrv_config.c
index bec6837c0..1ab7f3864 100644
--- a/src/charon/plugins/medsrv/medsrv_config.c
+++ b/src/charon/plugins/medsrv/medsrv_config.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <string.h>
@@ -92,13 +90,13 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this,
if (e)
{
peer_cfg_t *peer_cfg;
+ auth_cfg_t *auth;
char *name;
if (e->enumerate(e, &name))
{
peer_cfg = peer_cfg_create(
name, 2, this->ike->get_ref(this->ike),
- me->clone(me), other->clone(other),
CERT_NEVER_SEND, UNIQUE_REPLACE,
1, this->rekey*60, 0, /* keytries, rekey, reauth */
this->rekey*5, this->rekey*3, /* jitter, overtime */
@@ -106,6 +104,16 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this,
NULL, NULL, /* vip, pool */
TRUE, NULL, NULL); /* mediation, med by, peer id */
e->destroy(e);
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY, me->clone(me));
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY, other->clone(other));
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+
return enumerator_create_single(peer_cfg, (void*)peer_cfg->destroy);
}
e->destroy(e);
diff --git a/src/charon/plugins/medsrv/medsrv_config.h b/src/charon/plugins/medsrv/medsrv_config.h
index a92780144..2ed63bca7 100644
--- a/src/charon/plugins/medsrv/medsrv_config.h
+++ b/src/charon/plugins/medsrv/medsrv_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/medsrv/medsrv_creds.c b/src/charon/plugins/medsrv/medsrv_creds.c
index 5d2d46e53..7dac37f1f 100644
--- a/src/charon/plugins/medsrv/medsrv_creds.c
+++ b/src/charon/plugins/medsrv/medsrv_creds.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: medsrv_creds.c 4317 2008-09-02 11:00:13Z martin $
*/
#include "medsrv_creds.h"
diff --git a/src/charon/plugins/medsrv/medsrv_creds.h b/src/charon/plugins/medsrv/medsrv_creds.h
index 0ce77167c..da23220c2 100644
--- a/src/charon/plugins/medsrv/medsrv_creds.h
+++ b/src/charon/plugins/medsrv/medsrv_creds.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: medsrv_creds.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/medsrv/medsrv_plugin.c b/src/charon/plugins/medsrv/medsrv_plugin.c
index e34a1d4de..4340d7991 100644
--- a/src/charon/plugins/medsrv/medsrv_plugin.c
+++ b/src/charon/plugins/medsrv/medsrv_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: medsrv_plugin.c 4137 2008-07-01 13:57:47Z martin $
*/
#include "medsrv_plugin.h"
diff --git a/src/charon/plugins/medsrv/medsrv_plugin.h b/src/charon/plugins/medsrv/medsrv_plugin.h
index fbe04021f..4b183994f 100644
--- a/src/charon/plugins/medsrv/medsrv_plugin.h
+++ b/src/charon/plugins/medsrv/medsrv_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: medsrv_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/nm/Makefile.am b/src/charon/plugins/nm/Makefile.am
index 9c8c64fe1..9a0b48cd2 100644
--- a/src/charon/plugins/nm/Makefile.am
+++ b/src/charon/plugins/nm/Makefile.am
@@ -5,6 +5,9 @@ AM_CFLAGS = -rdynamic
plugin_LTLIBRARIES = libstrongswan-nm.la
libstrongswan_nm_la_SOURCES = \
- nm_plugin.h nm_plugin.c nm_service.h nm_service.c nm_creds.h nm_creds.c
+ nm_plugin.h nm_plugin.c \
+ nm_service.h nm_service.c \
+ nm_creds.h nm_creds.c \
+ nm_handler.h nm_handler.c
libstrongswan_nm_la_LDFLAGS = -module
libstrongswan_nm_la_LIBADD = ${nm_LIBS}
diff --git a/src/charon/plugins/nm/Makefile.in b/src/charon/plugins/nm/Makefile.in
index b3990fab1..a75af8a0f 100644
--- a/src/charon/plugins/nm/Makefile.in
+++ b/src/charon/plugins/nm/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -52,7 +52,7 @@ LTLIBRARIES = $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
libstrongswan_nm_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_libstrongswan_nm_la_OBJECTS = nm_plugin.lo nm_service.lo \
- nm_creds.lo
+ nm_creds.lo nm_handler.lo
libstrongswan_nm_la_OBJECTS = $(am_libstrongswan_nm_la_OBJECTS)
libstrongswan_nm_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -214,7 +223,10 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${nm_CFL
AM_CFLAGS = -rdynamic
plugin_LTLIBRARIES = libstrongswan-nm.la
libstrongswan_nm_la_SOURCES = \
- nm_plugin.h nm_plugin.c nm_service.h nm_service.c nm_creds.h nm_creds.c
+ nm_plugin.h nm_plugin.c \
+ nm_service.h nm_service.c \
+ nm_creds.h nm_creds.c \
+ nm_handler.h nm_handler.c
libstrongswan_nm_la_LDFLAGS = -module
libstrongswan_nm_la_LIBADD = ${nm_LIBS}
@@ -226,8 +238,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -288,6 +300,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_handler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_plugin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_service.Plo@am__quote@
@@ -323,7 +336,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/nm/nm_creds.c b/src/charon/plugins/nm/nm_creds.c
index e7cd640a7..d93b81c9a 100644
--- a/src/charon/plugins/nm/nm_creds.c
+++ b/src/charon/plugins/nm/nm_creds.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "nm_creds.h"
@@ -259,9 +257,7 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id
{
this->lock->write_lock(this->lock);
DESTROY_IF(this->user);
- /* for EAP authentication, we use always use ID_EAP type */
- this->user = identification_create_from_encoding(ID_EAP,
- id->get_encoding(id));
+ this->user = id->clone(id);
free(this->pass);
this->pass = password ? strdup(password) : NULL;
this->lock->unlock(this->lock);
diff --git a/src/charon/plugins/nm/nm_creds.h b/src/charon/plugins/nm/nm_creds.h
index b0cc7a098..421442c81 100644
--- a/src/charon/plugins/nm/nm_creds.h
+++ b/src/charon/plugins/nm/nm_creds.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -23,6 +21,7 @@
#ifndef NM_CREDS_H_
#define NM_CREDS_H_
+#include <credentials/keys/private_key.h>
#include <credentials/credential_set.h>
typedef struct nm_creds_t nm_creds_t;
diff --git a/src/charon/plugins/nm/nm_handler.c b/src/charon/plugins/nm/nm_handler.c
new file mode 100644
index 000000000..026c47af2
--- /dev/null
+++ b/src/charon/plugins/nm/nm_handler.c
@@ -0,0 +1,148 @@
+/*
+ * 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 "nm_handler.h"
+
+#include <daemon.h>
+
+typedef struct private_nm_handler_t private_nm_handler_t;
+
+/**
+ * Private data of an nm_handler_t object.
+ */
+struct private_nm_handler_t {
+
+ /**
+ * Public nm_handler_t interface.
+ */
+ nm_handler_t public;
+
+ /**
+ * list of received DNS server attributes, pointer to 4 byte data
+ */
+ linked_list_t *dns;
+
+ /**
+ * list of received NBNS server attributes, pointer to 4 byte data
+ */
+ linked_list_t *nbns;
+};
+
+/**
+ * Implementation of attribute_handler_t.handle
+ */
+static bool handle(private_nm_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ linked_list_t *list;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ list = this->dns;
+ break;
+ case INTERNAL_IP4_NBNS:
+ list = this->nbns;
+ break;
+ default:
+ return FALSE;
+ }
+ if (data.len != 4)
+ {
+ return FALSE;
+ }
+ list->insert_last(list, chunk_clone(data).ptr);
+ return TRUE;
+}
+
+/**
+ * convert plain byte ptrs to handy chunk during enumeration
+ */
+static bool filter_chunks(void* null, char **in, chunk_t *out)
+{
+ *out = chunk_create(*in, 4);
+ return TRUE;
+}
+
+/**
+ * Implementation of nm_handler_t.create_enumerator
+ */
+static enumerator_t* create_enumerator(private_nm_handler_t *this,
+ configuration_attribute_type_t type)
+{
+ linked_list_t *list;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ list = this->dns;
+ break;
+ case INTERNAL_IP4_NBNS:
+ list = this->nbns;
+ break;
+ default:
+ return enumerator_create_empty();
+ }
+ return enumerator_create_filter(list->create_enumerator(list),
+ (void*)filter_chunks, NULL, NULL);
+}
+
+/**
+ * Implementation of nm_handler_t.reset
+ */
+static void reset(private_nm_handler_t *this)
+{
+ void *data;
+
+ while (this->dns->remove_last(this->dns, (void**)&data) == SUCCESS)
+ {
+ free(data);
+ }
+ while (this->nbns->remove_last(this->nbns, (void**)&data) == SUCCESS)
+ {
+ free(data);
+ }
+}
+
+/**
+ * Implementation of nm_handler_t.destroy.
+ */
+static void destroy(private_nm_handler_t *this)
+{
+ reset(this);
+ this->dns->destroy(this->dns);
+ this->nbns->destroy(this->nbns);
+ free(this);
+}
+
+/**
+ * See header
+ */
+nm_handler_t *nm_handler_create()
+{
+ private_nm_handler_t *this = malloc_thing(private_nm_handler_t);
+
+ this->public.handler.handle = (bool(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))handle;
+ this->public.handler.release = (void(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))nop;
+ this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator;
+ this->public.reset = (void(*)(nm_handler_t*))reset;
+ this->public.destroy = (void(*)(nm_handler_t*))destroy;
+
+ this->dns = linked_list_create();
+ this->nbns = linked_list_create();
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/nm/nm_handler.h b/src/charon/plugins/nm/nm_handler.h
new file mode 100644
index 000000000..d537bb8de
--- /dev/null
+++ b/src/charon/plugins/nm/nm_handler.h
@@ -0,0 +1,62 @@
+/*
+ * 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 nm_handler nm_handler
+ * @{ @ingroup nm
+ */
+
+#ifndef NM_HANDLER_H_
+#define NM_HANDLER_H_
+
+#include <config/attributes/attribute_handler.h>
+
+typedef struct nm_handler_t nm_handler_t;
+
+/**
+ * Handles DNS/NBNS attributes to pass to NM.
+ */
+struct nm_handler_t {
+
+ /**
+ * Implements attribute handler interface
+ */
+ attribute_handler_t handler;
+
+ /**
+ * Create an enumerator over received attributes of a given kind.
+ *
+ * @param type type of attributes to enumerate
+ * @return enumerator over attribute data (chunk_t)
+ */
+ enumerator_t* (*create_enumerator)(nm_handler_t *this,
+ configuration_attribute_type_t type);
+ /**
+ * Reset state, flush all received attributes.
+ */
+ void (*reset)(nm_handler_t *this);
+
+ /**
+ * Destroy a nm_handler_t.
+ */
+ void (*destroy)(nm_handler_t *this);
+};
+
+/**
+ * Create a nm_handler instance.
+ */
+nm_handler_t *nm_handler_create();
+
+#endif /* NM_HANDLER_ @}*/
diff --git a/src/charon/plugins/nm/nm_plugin.c b/src/charon/plugins/nm/nm_plugin.c
index 1336293f4..1fb46f814 100644
--- a/src/charon/plugins/nm/nm_plugin.c
+++ b/src/charon/plugins/nm/nm_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,13 +11,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "nm_plugin.h"
#include "nm_service.h"
#include "nm_creds.h"
+#include "nm_handler.h"
#include <daemon.h>
#include <processing/jobs/callback_job.h>
@@ -50,6 +49,11 @@ struct private_nm_plugin_t {
* credential set registered at the daemon
*/
nm_creds_t *creds;
+
+ /**
+ * attribute handler regeisterd at the daemon
+ */
+ nm_handler_t *handler;
};
/**
@@ -59,8 +63,6 @@ static job_requeue_t run(private_nm_plugin_t *this)
{
this->loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(this->loop);
- g_main_loop_unref(this->loop);
-
return JOB_REQUEUE_NONE;
}
@@ -71,7 +73,11 @@ static void destroy(private_nm_plugin_t *this)
{
if (this->loop)
{
- g_main_loop_quit(this->loop);
+ if (g_main_loop_is_running(this->loop))
+ {
+ g_main_loop_quit(this->loop);
+ }
+ g_main_loop_unref(this->loop);
}
if (this->plugin)
{
@@ -79,6 +85,8 @@ static void destroy(private_nm_plugin_t *this)
}
charon->credentials->remove_set(charon->credentials, &this->creds->set);
this->creds->destroy(this->creds);
+ charon->attributes->remove_handler(charon->attributes, &this->handler->handler);
+ this->handler->destroy(this->handler);
free(this);
}
@@ -99,8 +107,10 @@ plugin_t *plugin_create()
}
this->creds = nm_creds_create();
+ this->handler = nm_handler_create();
charon->credentials->add_set(charon->credentials, &this->creds->set);
- this->plugin = nm_strongswan_plugin_new(this->creds);
+ charon->attributes->add_handler(charon->attributes, &this->handler->handler);
+ this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
if (!this->plugin)
{
DBG1(DBG_CFG, "DBUS binding failed");
diff --git a/src/charon/plugins/nm/nm_plugin.h b/src/charon/plugins/nm/nm_plugin.h
index fadcbfb96..18d053e11 100644
--- a/src/charon/plugins/nm/nm_plugin.h
+++ b/src/charon/plugins/nm/nm_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c
index 72744b784..bca4d9e09 100644
--- a/src/charon/plugins/nm/nm_service.c
+++ b/src/charon/plugins/nm/nm_service.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <nm-setting-vpn.h>
@@ -23,6 +21,7 @@
#include <utils/host.h>
#include <utils/identification.h>
#include <config/peer_cfg.h>
+#include <credentials/certificates/x509.h>
#include <stdio.h>
@@ -34,10 +33,16 @@ G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN)
* Private data of NMStrongswanPlugin
*/
typedef struct {
+ /* implements bus listener interface */
listener_t listener;
+ /* IKE_SA we are listening on */
ike_sa_t *ike_sa;
+ /* backref to public plugin */
NMVPNPlugin *plugin;
+ /* credentials to use for authentication */
nm_creds_t *creds;
+ /* attribute handler for DNS/NBNS server information */
+ nm_handler_t *handler;
} NMStrongswanPluginPrivate;
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
@@ -45,6 +50,31 @@ typedef struct {
NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginPrivate))
/**
+ * convert enumerated handler chunks to a UINT_ARRAY GValue
+ */
+static GValue* handler_to_val(nm_handler_t *handler,
+ configuration_attribute_type_t type)
+{
+ GValue *val;
+ GArray *array;
+ enumerator_t *enumerator;
+ chunk_t chunk;
+
+ enumerator = handler->create_enumerator(handler, type);
+ array = g_array_new (FALSE, TRUE, sizeof (guint32));
+ while (enumerator->enumerate(enumerator, &chunk))
+ {
+ g_array_append_val (array, *(u_int32_t*)chunk.ptr);
+ }
+ enumerator->destroy(enumerator);
+ val = g_slice_new0 (GValue);
+ g_value_init (val, DBUS_TYPE_G_UINT_ARRAY);
+ g_value_set_boxed (val, array);
+
+ return val;
+}
+
+/**
* signal IPv4 config to NM, set connection as established
*/
static void signal_ipv4_config(NMVPNPlugin *plugin,
@@ -53,10 +83,12 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
GValue *val;
GHashTable *config;
host_t *me, *other;
+ nm_handler_t *handler;
config = g_hash_table_new(g_str_hash, g_str_equal);
me = ike_sa->get_my_host(ike_sa);
other = ike_sa->get_other_host(ike_sa);
+ handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;
/* NM requires a tundev, but netkey does not use one. Passing an invalid
* iface makes NM complain, but it accepts it without fiddling on eth0. */
@@ -75,6 +107,14 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
g_value_set_uint(val, me->get_address(me).len * 8);
g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
+ val = handler_to_val(handler, INTERNAL_IP4_DNS);
+ g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_DNS, val);
+
+ val = handler_to_val(handler, INTERNAL_IP4_NBNS);
+ g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_NBNS, val);
+
+ handler->reset(handler);
+
nm_vpn_plugin_set_ip4_config(plugin, config);
}
@@ -83,6 +123,10 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
*/
static void signal_failure(NMVPNPlugin *plugin)
{
+ nm_handler_t *handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;
+
+ handler->reset(handler);
+
/* TODO: NM does not handle this failure!? */
nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED);
@@ -151,9 +195,10 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
child_cfg_t *child_cfg;
traffic_selector_t *ts;
ike_sa_t *ike_sa;
- auth_info_t *auth;
+ auth_cfg_t *auth;
auth_class_t auth_class = AUTH_CLASS_EAP;
certificate_t *cert = NULL;
+ x509_t *x509;
bool agent = FALSE;
/**
@@ -201,7 +246,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
creds = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds;
creds->clear(creds);
- /* gateway cert */
+ /* gateway/CA cert */
str = nm_setting_vpn_get_data_item(settings, "certificate");
if (str)
{
@@ -215,7 +260,21 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
"Loading gateway certificate failed.");
return FALSE;
}
- gateway = cert->get_subject(cert);
+ x509 = (x509_t*)cert;
+ if (x509->get_flags(x509) & X509_CA)
+ { /* If the user configured a CA certificate, we use the IP/DNS
+ * of the gateway as its identity. This identity will be used for
+ * certificate lookup and requires the configured IP/DNS to be
+ * included in the gateway certificate. */
+ gateway = identification_create_from_string((char*)address);
+ DBG1(DBG_CFG, "using CA certificate, gateway identity '%Y'", gateway);
+ }
+ else
+ { /* For a gateway certificate, we use the cert subject as identity. */
+ gateway = cert->get_subject(cert);
+ gateway = gateway->clone(gateway);
+ DBG1(DBG_CFG, "using gateway certificate, identity '%Y'", gateway);
+ }
if (auth_class == AUTH_CLASS_EAP)
{
@@ -223,8 +282,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
str = nm_setting_vpn_get_data_item(settings, "user");
if (str)
{
- user = identification_create_from_encoding(ID_KEY_ID,
- chunk_create(str, strlen(str)));
+ user = identification_create_from_string((char*)str);
str = nm_setting_vpn_get_secret(settings, "password");
creds->set_username_password(creds, user, (char*)str);
}
@@ -240,12 +298,13 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
private_key_t *private = NULL;
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, str, BUILD_END);
+ BUILD_FROM_FILE, str, BUILD_END);
if (!cert)
{
g_set_error(err, NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
"Loading peer certificate failed.");
+ gateway->destroy(gateway);
return FALSE;
}
/* try agent */
@@ -304,6 +363,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
else
{
DESTROY_IF(cert);
+ gateway->destroy(gateway);
return FALSE;
}
}
@@ -313,6 +373,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
{
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
"Configuration parameters missing.");
+ gateway->destroy(gateway);
return FALSE;
}
@@ -322,15 +383,21 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", (char*)address);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg,
- user, gateway->clone(gateway),
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
36000, 0, /* rekey 10h, reauth none */
600, 600, /* jitter, over 10min */
TRUE, 0, /* mobike, DPD */
virtual ? host_create_from_string("0.0.0.0", 0) : NULL,
NULL, FALSE, NULL, NULL); /* pool, mediation */
- auth = peer_cfg->get_auth(peer_cfg);
- auth->add_item(auth, AUTHN_AUTH_CLASS, &auth_class);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_class);
+ auth->add(auth, AUTH_RULE_IDENTITY, user);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY, gateway);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+
child_cfg = child_cfg_create(CONFIG_NAME,
10800, 10200, /* lifetime 3h, rekey 2h50min */
300, /* jitter 5min */
@@ -358,7 +425,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
{
peer_cfg->destroy(peer_cfg);
}
- if (ike_sa->initiate(ike_sa, child_cfg) != SUCCESS)
+ if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
{
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
@@ -489,7 +556,8 @@ static void nm_strongswan_plugin_class_init(
/**
* Object constructor
*/
-NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds)
+NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds,
+ nm_handler_t *handler)
{
NMStrongswanPlugin *plugin = (NMStrongswanPlugin *)g_object_new (
NM_TYPE_STRONGSWAN_PLUGIN,
@@ -498,6 +566,7 @@ NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds)
if (plugin)
{
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds = creds;
+ NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler = handler;
}
return plugin;
}
diff --git a/src/charon/plugins/nm/nm_service.h b/src/charon/plugins/nm/nm_service.h
index bc6ebcf99..b00000b6f 100644
--- a/src/charon/plugins/nm/nm_service.h
+++ b/src/charon/plugins/nm/nm_service.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -28,6 +26,7 @@
#include <nm-vpn-plugin.h>
#include "nm_creds.h"
+#include "nm_handler.h"
#define NM_TYPE_STRONGSWAN_PLUGIN (nm_strongswan_plugin_get_type ())
#define NM_STRONGSWAN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPlugin))
@@ -50,6 +49,7 @@ typedef struct {
GType nm_strongswan_plugin_get_type(void);
-NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds);
+NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds,
+ nm_handler_t *handler);
#endif /** NM_SERVICE_H_ @}*/
diff --git a/src/charon/plugins/resolv_conf/Makefile.am b/src/charon/plugins/resolv_conf/Makefile.am
new file mode 100644
index 000000000..917964f93
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/Makefile.am
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic \
+ -DRESOLV_CONF=\"${resolv_conf}\"
+
+plugin_LTLIBRARIES = libstrongswan-resolv-conf.la
+libstrongswan_resolv_conf_la_SOURCES = \
+ resolv_conf_plugin.h resolv_conf_plugin.c \
+ resolv_conf_handler.h resolv_conf_handler.c
+libstrongswan_resolv_conf_la_LDFLAGS = -module
+
+
diff --git a/src/charon/plugins/resolv_conf/Makefile.in b/src/charon/plugins/resolv_conf/Makefile.in
new file mode 100644
index 000000000..91ddae582
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/Makefile.in
@@ -0,0 +1,513 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/charon/plugins/resolv_conf
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_resolv_conf_la_LIBADD =
+am_libstrongswan_resolv_conf_la_OBJECTS = resolv_conf_plugin.lo \
+ resolv_conf_handler.lo
+libstrongswan_resolv_conf_la_OBJECTS = \
+ $(am_libstrongswan_resolv_conf_la_OBJECTS)
+libstrongswan_resolv_conf_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_resolv_conf_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_resolv_conf_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_resolv_conf_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic \
+ -DRESOLV_CONF=\"${resolv_conf}\"
+
+plugin_LTLIBRARIES = libstrongswan-resolv-conf.la
+libstrongswan_resolv_conf_la_SOURCES = \
+ resolv_conf_plugin.h resolv_conf_plugin.c \
+ resolv_conf_handler.h resolv_conf_handler.c
+
+libstrongswan_resolv_conf_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/resolv_conf/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/charon/plugins/resolv_conf/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-resolv-conf.la: $(libstrongswan_resolv_conf_la_OBJECTS) $(libstrongswan_resolv_conf_la_DEPENDENCIES)
+ $(libstrongswan_resolv_conf_la_LINK) -rpath $(plugindir) $(libstrongswan_resolv_conf_la_OBJECTS) $(libstrongswan_resolv_conf_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resolv_conf_handler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resolv_conf_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/charon/plugins/resolv_conf/resolv_conf_handler.c b/src/charon/plugins/resolv_conf/resolv_conf_handler.c
new file mode 100644
index 000000000..19e3b3275
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/resolv_conf_handler.c
@@ -0,0 +1,192 @@
+/*
+ * 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 "resolv_conf_handler.h"
+
+#include <unistd.h>
+
+#include <daemon.h>
+#include <utils/mutex.h>
+
+typedef struct private_resolv_conf_handler_t private_resolv_conf_handler_t;
+
+/**
+ * Private data of an resolv_conf_handler_t object.
+ */
+struct private_resolv_conf_handler_t {
+
+ /**
+ * Public resolv_conf_handler_t interface.
+ */
+ resolv_conf_handler_t public;
+
+ /**
+ * resolv.conf file to use
+ */
+ char *file;
+
+ /**
+ * Mutex to access file exclusively
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Implementation of attribute_handler_t.handle
+ */
+static bool handle(private_resolv_conf_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ FILE *in, *out;
+ char buf[1024];
+ host_t *addr;
+ int family;
+ size_t len;
+ bool handled = FALSE;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ family = AF_INET;
+ break;
+ case INTERNAL_IP6_DNS:
+ family = AF_INET6;
+ break;
+ default:
+ return FALSE;
+ }
+
+ this->mutex->lock(this->mutex);
+
+ in = fopen(this->file, "r");
+ /* allows us to stream from in to out */
+ unlink(this->file);
+ out = fopen(this->file, "w");
+ if (out)
+ {
+ addr = host_create_from_chunk(family, data, 0);
+ fprintf(out, "nameserver %H # by strongSwan, from %Y\n",
+ addr, ike_sa->get_other_id(ike_sa));
+ DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file);
+ addr->destroy(addr);
+ 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(in);
+ }
+ fclose(out);
+ }
+
+ if (!handled)
+ {
+ DBG1(DBG_IKE, "adding DNS server failed", this->file);
+ }
+ this->mutex->unlock(this->mutex);
+ return handled;
+}
+
+/**
+ * Implementation of attribute_handler_t.release
+ */
+static void release(private_resolv_conf_handler_t *this, ike_sa_t *ike_sa,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ FILE *in, *out;
+ char line[1024], matcher[512], *pos;
+ 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;
+ }
+
+ this->mutex->lock(this->mutex);
+
+ 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)
+ {
+ addr = host_create_from_chunk(family, data, 0);
+ snprintf(matcher, sizeof(matcher),
+ "nameserver %H # by strongSwan, from %Y\n",
+ addr, ike_sa->get_other_id(ike_sa));
+
+ /* copy all, but matching line */
+ while ((pos = fgets(line, sizeof(line), in)))
+ {
+ if (strneq(line, matcher, strlen(matcher)))
+ {
+ DBG1(DBG_IKE, "removing DNS server %H from %s",
+ addr, this->file);
+ }
+ else
+ {
+ fputs(line, out);
+ }
+ }
+ addr->destroy(addr);
+ fclose(out);
+ }
+ fclose(in);
+ }
+
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of resolv_conf_handler_t.destroy.
+ */
+static void destroy(private_resolv_conf_handler_t *this)
+{
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+resolv_conf_handler_t *resolv_conf_handler_create()
+{
+ private_resolv_conf_handler_t *this = malloc_thing(private_resolv_conf_handler_t);
+
+ this->public.handler.handle = (bool(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))handle;
+ this->public.handler.release = (void(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))release;
+ this->public.destroy = (void(*)(resolv_conf_handler_t*))destroy;
+
+ this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->file = lib->settings->get_str(lib->settings,
+ "charon.plugins.resolv-conf.file", RESOLV_CONF);
+
+ return &this->public;
+}
+
diff --git a/src/charon/plugins/resolv_conf/resolv_conf_handler.h b/src/charon/plugins/resolv_conf/resolv_conf_handler.h
new file mode 100644
index 000000000..2635bb802
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/resolv_conf_handler.h
@@ -0,0 +1,49 @@
+/*
+ * 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 resolv_conf_handler resolv_conf_handler
+ * @{ @ingroup resolv_conf
+ */
+
+#ifndef RESOLV_CONF_HANDLER_H_
+#define RESOLV_CONF_HANDLER_H_
+
+#include <config/attributes/attribute_handler.h>
+
+typedef struct resolv_conf_handler_t resolv_conf_handler_t;
+
+/**
+ * Handle DNS configuration attributes by mangling a resolv.conf file.
+ */
+struct resolv_conf_handler_t {
+
+ /**
+ * Implements the attribute_handler_t interface
+ */
+ attribute_handler_t handler;
+
+ /**
+ * Destroy a resolv_conf_handler_t.
+ */
+ void (*destroy)(resolv_conf_handler_t *this);
+};
+
+/**
+ * Create a resolv_conf_handler instance.
+ */
+resolv_conf_handler_t *resolv_conf_handler_create();
+
+#endif /* RESOLV_CONF_HANDLER_ @}*/
diff --git a/src/charon/plugins/resolv_conf/resolv_conf_plugin.c b/src/charon/plugins/resolv_conf/resolv_conf_plugin.c
new file mode 100644
index 000000000..ff9d96eb3
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/resolv_conf_plugin.c
@@ -0,0 +1,64 @@
+/*
+ * 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 "resolv_conf_plugin.h"
+#include "resolv_conf_handler.h"
+
+#include <daemon.h>
+
+typedef struct private_resolv_conf_plugin_t private_resolv_conf_plugin_t;
+
+/**
+ * private data of resolv_conf plugin
+ */
+struct private_resolv_conf_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ resolv_conf_plugin_t public;
+
+ /**
+ * The registerd DNS attribute handler
+ */
+ resolv_conf_handler_t *handler;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_resolv_conf_plugin_t *this)
+{
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
+ this->handler->destroy(this->handler);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_resolv_conf_plugin_t *this = malloc_thing(private_resolv_conf_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ this->handler = resolv_conf_handler_create();
+ charon->attributes->add_handler(charon->attributes, &this->handler->handler);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/resolv_conf/resolv_conf_plugin.h b/src/charon/plugins/resolv_conf/resolv_conf_plugin.h
new file mode 100644
index 000000000..f5943d9a3
--- /dev/null
+++ b/src/charon/plugins/resolv_conf/resolv_conf_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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 resolv_conf resolv_conf
+ * @ingroup cplugins
+ *
+ * @defgroup resolv_conf_plugin resolv_conf_plugin
+ * @{ @ingroup resolv_conf
+ */
+
+#ifndef RESOLV_CONF_PLUGIN_H_
+#define RESOLV_CONF_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct resolv_conf_plugin_t resolv_conf_plugin_t;
+
+/**
+ * Plugin that writes received DNS servers in a resolv.conf file.
+ */
+struct resolv_conf_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a resolv_conf_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** RESOLV_CONF_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/smp/Makefile.in b/src/charon/plugins/smp/Makefile.in
index 428da0ec9..f06321ba7 100644
--- a/src/charon/plugins/smp/Makefile.in
+++ b/src/charon/plugins/smp/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -223,8 +232,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -318,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/smp/smp.c b/src/charon/plugins/smp/smp.c
index 237e9d86a..562add06d 100644
--- a/src/charon/plugins/smp/smp.c
+++ b/src/charon/plugins/smp/smp.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: smp.c 4446 2008-10-15 12:24:44Z martin $
*/
#include <stdlib.h>
@@ -109,7 +107,7 @@ static void write_id(xmlTextWriterPtr writer, char *element, identification_t *i
break;
}
xmlTextWriterWriteAttribute(writer, "type", type);
- xmlTextWriterWriteFormatString(writer, "%D", id);
+ xmlTextWriterWriteFormatString(writer, "%Y", id);
break;
}
default:
@@ -294,8 +292,9 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
/* <configlist> */
xmlTextWriterStartElement(writer, "configlist");
- enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
- while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
{
enumerator_t *children;
child_cfg_t *child_cfg;
@@ -310,8 +309,8 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
/* <peerconfig> */
xmlTextWriterStartElement(writer, "peerconfig");
xmlTextWriterWriteElement(writer, "name", peer_cfg->get_name(peer_cfg));
- write_id(writer, "local", peer_cfg->get_my_id(peer_cfg));
- write_id(writer, "remote", peer_cfg->get_other_id(peer_cfg));
+
+ /* TODO: write auth_cfgs */
/* <ikeconfig> */
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
diff --git a/src/charon/plugins/smp/smp.h b/src/charon/plugins/smp/smp.h
index 1f45befa6..5ec9f3bf8 100644
--- a/src/charon/plugins/smp/smp.h
+++ b/src/charon/plugins/smp/smp.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: smp.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/sql/Makefile.in b/src/charon/plugins/sql/Makefile.in
index 3673af659..0848ea0dd 100644
--- a/src/charon/plugins/sql/Makefile.in
+++ b/src/charon/plugins/sql/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -96,6 +96,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -118,6 +119,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -129,6 +133,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -142,6 +147,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -202,6 +209,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -213,6 +221,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -239,8 +248,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -370,7 +379,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/sql/pool.c b/src/charon/plugins/sql/pool.c
index 9761e88e9..7d393b6f7 100644
--- a/src/charon/plugins/sql/pool.c
+++ b/src/charon/plugins/sql/pool.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -24,6 +22,7 @@
#include <debug.h>
#include <library.h>
#include <utils/host.h>
+#include <utils/identification.h>
/**
* global database handle
@@ -401,11 +400,6 @@ static enumerator_t *create_lease_query(char *filter)
{
id = identification_create_from_string(value);
}
- if (!id)
- {
- fprintf(stderr, "invalid 'id' in filter string.\n");
- exit(-1);
- }
break;
case FIL_ADDR:
if (value)
@@ -567,7 +561,7 @@ static void leases(char *filter, bool utc)
printf(" ");
}
}
- printf("%D\n", identity);
+ printf("%Y\n", identity);
DESTROY_IF(address);
identity->destroy(identity);
}
diff --git a/src/charon/plugins/sql/sql_attribute.c b/src/charon/plugins/sql/sql_attribute.c
index 826aa8318..95d0d30d4 100644
--- a/src/charon/plugins/sql/sql_attribute.c
+++ b/src/charon/plugins/sql/sql_attribute.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "sql_attribute.h"
@@ -179,7 +177,7 @@ static host_t *get_address(private_sql_attribute_t *this, char *name,
*/
static host_t* acquire_address(private_sql_attribute_t *this,
char *name, identification_t *id,
- auth_info_t *auth, host_t *requested)
+ host_t *requested)
{
enumerator_t *enumerator;
u_int pool, timeout, identity;
@@ -263,8 +261,9 @@ sql_attribute_t *sql_attribute_create(database_t *db)
private_sql_attribute_t *this = malloc_thing(private_sql_attribute_t);
time_t now = time(NULL);
- this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
+ this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
this->public.destroy = (void(*)(sql_attribute_t*))destroy;
this->db = db;
diff --git a/src/charon/plugins/sql/sql_attribute.h b/src/charon/plugins/sql/sql_attribute.h
index 57db4617e..23700dea9 100644
--- a/src/charon/plugins/sql/sql_attribute.h
+++ b/src/charon/plugins/sql/sql_attribute.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/sql/sql_config.c b/src/charon/plugins/sql/sql_config.c
index d530f9fde..3e5efce34 100644
--- a/src/charon/plugins/sql/sql_config.c
+++ b/src/charon/plugins/sql/sql_config.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_config.c 4860 2009-02-11 13:09:52Z martin $
*/
#include <string.h>
@@ -267,7 +265,7 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
peer_cfg_t *peer_cfg, *mediated_cfg;
ike_cfg_t *ike;
host_t *vip = NULL;
- auth_info_t *auth;
+ auth_cfg_t *auth;
local_id = identification_create_from_encoding(l_type, l_data);
remote_id = identification_create_from_encoding(r_type, r_data);
@@ -291,20 +289,26 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
if (ike)
{
peer_cfg = peer_cfg_create(
- name, 2, ike, local_id, remote_id, cert_policy, uniqueid,
+ name, 2, ike, cert_policy, uniqueid,
keyingtries, rekeytime, reauthtime, jitter, overtime,
mobike, dpd_delay, vip, pool,
mediation, mediated_cfg, peer_id);
- auth = peer_cfg->get_auth(peer_cfg);
- auth->add_item(auth, AUTHN_AUTH_CLASS, &auth_method);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
+ auth->add(auth, AUTH_RULE_IDENTITY, local_id->clone(local_id));
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_IDENTITY, remote_id->clone(remote_id));
if (eap_type)
{
- auth->add_item(auth, AUTHN_EAP_TYPE, &eap_type);
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+ auth->add(auth, AUTH_RULE_EAP_TYPE, eap_type);
if (eap_vendor)
{
- auth->add_item(auth, AUTHN_EAP_VENDOR, &eap_vendor);
+ auth->add(auth, AUTH_RULE_EAP_VENDOR, eap_vendor);
}
}
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
add_child_cfgs(this, peer_cfg, id);
return peer_cfg;
}
diff --git a/src/charon/plugins/sql/sql_config.h b/src/charon/plugins/sql/sql_config.h
index bfcd7a7c1..abc6ef382 100644
--- a/src/charon/plugins/sql/sql_config.h
+++ b/src/charon/plugins/sql/sql_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_config.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/sql/sql_cred.c b/src/charon/plugins/sql/sql_cred.c
index 7313b7eb8..f8b7a35c1 100644
--- a/src/charon/plugins/sql/sql_cred.c
+++ b/src/charon/plugins/sql/sql_cred.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_cred.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/charon/plugins/sql/sql_cred.h b/src/charon/plugins/sql/sql_cred.h
index a614f0cba..2a9a96df1 100644
--- a/src/charon/plugins/sql/sql_cred.h
+++ b/src/charon/plugins/sql/sql_cred.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_cred.h 3594 2008-03-13 14:53:57Z martin $
*/
/**
diff --git a/src/charon/plugins/sql/sql_logger.c b/src/charon/plugins/sql/sql_logger.c
index 4cbaaa3e6..20d42662b 100644
--- a/src/charon/plugins/sql/sql_logger.c
+++ b/src/charon/plugins/sql/sql_logger.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_logger.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/charon/plugins/sql/sql_logger.h b/src/charon/plugins/sql/sql_logger.h
index 3346430a1..3636c2293 100644
--- a/src/charon/plugins/sql/sql_logger.h
+++ b/src/charon/plugins/sql/sql_logger.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_logger.h 3594 2008-03-13 14:53:57Z martin $
*/
/**
diff --git a/src/charon/plugins/sql/sql_plugin.c b/src/charon/plugins/sql/sql_plugin.c
index 24680ba5e..e5a4afd1d 100644
--- a/src/charon/plugins/sql/sql_plugin.c
+++ b/src/charon/plugins/sql/sql_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_plugin.c 4711 2008-11-27 14:33:41Z martin $
*/
#include "sql_plugin.h"
diff --git a/src/charon/plugins/sql/sql_plugin.h b/src/charon/plugins/sql/sql_plugin.h
index d4f2d29f2..8de04a891 100644
--- a/src/charon/plugins/sql/sql_plugin.h
+++ b/src/charon/plugins/sql/sql_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sql_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am
index 7a341102b..fb58ba62b 100644
--- a/src/charon/plugins/stroke/Makefile.am
+++ b/src/charon/plugins/stroke/Makefile.am
@@ -1,7 +1,10 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+AM_CFLAGS = \
+-rdynamic \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\"
plugin_LTLIBRARIES = libstrongswan-stroke.la
diff --git a/src/charon/plugins/stroke/Makefile.in b/src/charon/plugins/stroke/Makefile.in
index 645ae2a48..f246286a0 100644
--- a/src/charon/plugins/stroke/Makefile.in
+++ b/src/charon/plugins/stroke/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -90,6 +90,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -112,6 +113,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -123,6 +127,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -136,6 +141,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -196,6 +203,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -207,12 +215,17 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
+AM_CFLAGS = \
+-rdynamic \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\"
+
plugin_LTLIBRARIES = libstrongswan-stroke.la
libstrongswan_stroke_la_SOURCES = stroke_plugin.h stroke_plugin.c \
stroke_socket.h stroke_socket.c \
@@ -233,8 +246,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -336,7 +349,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/stroke/stroke_attribute.c b/src/charon/plugins/stroke/stroke_attribute.c
index f850b5320..a7925ce3e 100644
--- a/src/charon/plugins/stroke/stroke_attribute.c
+++ b/src/charon/plugins/stroke/stroke_attribute.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_attribute.h"
@@ -191,7 +189,7 @@ int host2offset(pool_t *pool, host_t *addr)
*/
static host_t* acquire_address(private_stroke_attribute_t *this,
char *name, identification_t *id,
- auth_info_t *auth, host_t *requested)
+ host_t *requested)
{
pool_t *pool;
uintptr_t offset = 0;
@@ -208,8 +206,9 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
this->mutex->unlock(this->mutex);
return requested->clone(requested);
}
-
- if (requested->get_family(requested) !=
+
+ if (!requested->is_anyaddr(requested) &&
+ requested->get_family(requested) !=
pool->base->get_family(pool->base))
{
DBG1(DBG_CFG, "IP pool address family mismatch");
@@ -223,7 +222,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
id = pool->ids->get(pool->ids, id);
if (id)
{
- DBG1(DBG_CFG, "reassigning offline lease to %D", id);
+ DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
pool->online->put(pool->online, id, (void*)offset);
break;
}
@@ -233,7 +232,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
offset = (uintptr_t)pool->online->get(pool->online, id);
if (offset && offset == host2offset(pool, requested))
{
- DBG1(DBG_CFG, "reassigning online lease to %D", id);
+ DBG1(DBG_CFG, "reassigning online lease to '%Y'", id);
break;
}
@@ -245,7 +244,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
id = id->clone(id);
pool->ids->put(pool->ids, id, id);
pool->online->put(pool->online, id, (void*)offset);
- DBG1(DBG_CFG, "assigning new lease to %D", id);
+ DBG1(DBG_CFG, "assigning new lease to '%Y'", id);
break;
}
/* no more addresses, replace the first found offline lease */
@@ -257,7 +256,7 @@ static host_t* acquire_address(private_stroke_attribute_t *this,
{
/* destroy reference to old ID */
old_id = pool->ids->remove(pool->ids, old_id);
- DBG1(DBG_CFG, "reassigning existing offline lease of %D to %D",
+ DBG1(DBG_CFG, "reassigning existing offline lease by '%Y' to '%Y'",
old_id, id);
if (old_id)
{
@@ -305,7 +304,7 @@ static bool release_address(private_stroke_attribute_t *this,
id = pool->ids->get(pool->ids, id);
if (id)
{
- DBG1(DBG_CFG, "lease %H of %D went offline", address, id);
+ DBG1(DBG_CFG, "lease %H by '%Y' went offline", address, id);
pool->offline->put(pool->offline, id, (void*)offset);
found = TRUE;
}
@@ -530,8 +529,9 @@ stroke_attribute_t *stroke_attribute_create()
{
private_stroke_attribute_t *this = malloc_thing(private_stroke_attribute_t);
- this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+ this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,host_t *))acquire_address;
this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
+ this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, identification_t *id))enumerator_create_empty;
this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
this->public.create_pool_enumerator = (enumerator_t*(*)(stroke_attribute_t*))create_pool_enumerator;
diff --git a/src/charon/plugins/stroke/stroke_attribute.h b/src/charon/plugins/stroke/stroke_attribute.h
index 41ab6299b..fc273d1cb 100644
--- a/src/charon/plugins/stroke/stroke_attribute.h
+++ b/src/charon/plugins/stroke/stroke_attribute.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_ca.c b/src/charon/plugins/stroke/stroke_ca.c
index 54356436f..fab06e6c5 100644
--- a/src/charon/plugins/stroke/stroke_ca.c
+++ b/src/charon/plugins/stroke/stroke_ca.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_ca.h"
@@ -398,14 +396,14 @@ static void list(private_stroke_ca_t *this, stroke_msg_t *msg, FILE *out)
first = FALSE;
}
fprintf(out, "\n");
- fprintf(out, " authname: \"%D\"\n", cert->get_subject(cert));
+ fprintf(out, " authname: \"%Y\"\n", cert->get_subject(cert));
/* list authkey and keyid */
if (public)
{
- fprintf(out, " authkey: %D\n",
+ fprintf(out, " authkey: %Y\n",
public->get_id(public, ID_PUBKEY_SHA1));
- fprintf(out, " keyid: %D\n",
+ fprintf(out, " keyid: %Y\n",
public->get_id(public, ID_PUBKEY_INFO_SHA1));
public->destroy(public);
}
diff --git a/src/charon/plugins/stroke/stroke_ca.h b/src/charon/plugins/stroke/stroke_ca.h
index ee759ff4e..c882d7b4e 100644
--- a/src/charon/plugins/stroke/stroke_ca.h
+++ b/src/charon/plugins/stroke/stroke_ca.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_config.c b/src/charon/plugins/stroke/stroke_config.c
index 59c58ca0d..028e71e71 100644
--- a/src/charon/plugins/stroke/stroke_config.c
+++ b/src/charon/plugins/stroke/stroke_config.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_config.h"
@@ -55,90 +53,21 @@ struct private_stroke_config_t {
};
/**
- * data to pass peer_filter
- */
-typedef struct {
- private_stroke_config_t *this;
- identification_t *me;
- identification_t *other;
-} peer_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void peer_data_destroy(peer_data_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
-}
-
-/**
- * filter function for peer configs
- */
-static bool peer_filter(peer_data_t *data, peer_cfg_t **in, peer_cfg_t **out)
-{
- bool match_me = FALSE, match_other = FALSE;
- identification_t *me, *other;
-
- me = (*in)->get_my_id(*in);
- other = (*in)->get_other_id(*in);
-
- /* own ID may have wildcards in data (no IDr payload) or in config */
- match_me = (!data->me || data->me->matches(data->me, me) ||
- me->matches(me, data->me));
- /* others ID has wildcards in config only */
- match_other = (!data->other || data->other->matches(data->other, other));
-
- if (match_me && match_other)
- {
- *out = *in;
- return TRUE;
- }
- return FALSE;
-}
-
-/**
* Implementation of backend_t.create_peer_cfg_enumerator.
*/
static enumerator_t* create_peer_cfg_enumerator(private_stroke_config_t *this,
identification_t *me,
identification_t *other)
{
- peer_data_t *data;
-
- data = malloc_thing(peer_data_t);
- data->this = this;
- data->me = me;
- data->other = other;
-
this->mutex->lock(this->mutex);
- return enumerator_create_filter(this->list->create_enumerator(this->list),
- (void*)peer_filter, data,
- (void*)peer_data_destroy);
-}
-
-/**
- * data to pass ike_filter
- */
-typedef struct {
- private_stroke_config_t *this;
- host_t *me;
- host_t *other;
-} ike_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void ike_data_destroy(ike_data_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
+ return enumerator_create_cleaner(this->list->create_enumerator(this->list),
+ (void*)this->mutex->unlock, this->mutex);
}
/**
* filter function for ike configs
*/
-static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
+static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
{
*out = (*in)->get_ike_cfg(*in);
return TRUE;
@@ -150,17 +79,10 @@ static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
host_t *me, host_t *other)
{
- ike_data_t *data;
-
- data = malloc_thing(ike_data_t);
- data->this = this;
- data->me = me;
- data->other = other;
-
this->mutex->lock(this->mutex);
return enumerator_create_filter(this->list->create_enumerator(this->list),
- (void*)ike_filter, data,
- (void*)ike_data_destroy);
+ (void*)ike_filter, this->mutex,
+ (void*)this->mutex->unlock);
}
/**
@@ -171,34 +93,34 @@ static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *nam
enumerator_t *e1, *e2;
peer_cfg_t *current, *found = NULL;
child_cfg_t *child;
-
+
this->mutex->lock(this->mutex);
e1 = this->list->create_enumerator(this->list);
while (e1->enumerate(e1, &current))
{
- /* compare peer_cfgs name first */
- if (streq(current->get_name(current), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- /* compare all child_cfg names otherwise */
- e2 = current->create_child_cfg_enumerator(current);
- while (e2->enumerate(e2, &child))
- {
- if (streq(child->get_name(child), name))
- {
- found = current;
- found->get_ref(found);
- break;
- }
- }
- e2->destroy(e2);
- if (found)
- {
- break;
- }
+ /* compare peer_cfgs name first */
+ if (streq(current->get_name(current), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ /* compare all child_cfg names otherwise */
+ e2 = current->create_child_cfg_enumerator(current);
+ while (e2->enumerate(e2, &child))
+ {
+ if (streq(child->get_name(child), name))
+ {
+ found = current;
+ found->get_ref(found);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (found)
+ {
+ break;
+ }
}
e1->destroy(e1);
this->mutex->unlock(this->mutex);
@@ -206,22 +128,6 @@ static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *nam
}
/**
- * check if a certificate has an ID
- */
-static identification_t *update_peerid(certificate_t *cert, identification_t *id)
-{
- if (id->get_type(id) == ID_ANY || !cert->has_subject(cert, id))
- {
- DBG1(DBG_CFG, " peerid %D not confirmed by certificate, "
- "defaulting to subject DN", id);
- id->destroy(id);
- id = cert->get_subject(cert);
- return id->clone(id);
- }
- return id;
-}
-
-/**
* parse a proposal string, either into ike_cfg or child_cfg
*/
static void add_proposals(private_stroke_config_t *this, char *string,
@@ -332,45 +238,303 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
return ike_cfg;
}
+
/**
- * build a peer_cfg from a stroke msg
+ * Add CRL constraint to config
*/
-static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
- stroke_msg_t *msg, ike_cfg_t *ike_cfg,
- identification_t **my_issuer,
- identification_t **other_issuer)
+static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy)
{
- identification_t *me, *other, *peer_id = NULL;
- peer_cfg_t *mediated_by = NULL;
- host_t *vip = NULL;
- certificate_t *cert;
- unique_policy_t unique;
- u_int32_t rekey = 0, reauth = 0, over, jitter;
+ /* CRL/OCSP policy, for remote config only */
+ if (!local)
+ {
+ switch (policy)
+ {
+ case CRL_STRICT_YES:
+ /* if yes, we require a GOOD validation */
+ cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+ break;
+ case CRL_STRICT_IFURI:
+ /* for ifuri, a SKIPPED validation is sufficient */
+ cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_SKIPPED);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/**
+ * build authentication config
+ */
+static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
+ stroke_msg_t *msg, bool local, bool primary)
+{
+ identification_t *identity;
+ certificate_t *certificate;
+ char *auth, *id, *cert, *ca;
+ stroke_end_t *end, *other_end;
+ auth_cfg_t *cfg;
+ char eap_buf[32];
- me = identification_create_from_string(msg->add_conn.me.id ?
- msg->add_conn.me.id : msg->add_conn.me.address);
- if (!me)
+ /* select strings */
+ if (local)
{
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
- return NULL;
+ end = &msg->add_conn.me;
+ other_end = &msg->add_conn.other;
}
- other = identification_create_from_string(msg->add_conn.other.id ?
- msg->add_conn.other.id : msg->add_conn.other.address);
- if (!other)
+ else
{
- DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
- me->destroy(me);
- return NULL;
+ end = &msg->add_conn.other;
+ other_end = &msg->add_conn.me;
+ }
+ if (primary)
+ {
+ auth = end->auth;
+ id = end->id;
+ if (!id)
+ { /* leftid/rightid fallback to address */
+ id = end->address;
+ }
+ cert = end->cert;
+ ca = end->ca;
+ if (ca && streq(ca, "%same"))
+ {
+ ca = other_end->ca;
+ }
+ }
+ else
+ {
+ auth = end->auth2;
+ id = end->id2;
+ if (local && !id)
+ { /* leftid2 falls back to leftid */
+ id = end->id;
+ }
+ cert = end->cert2;
+ ca = end->ca2;
+ if (ca && streq(ca, "%same"))
+ {
+ ca = other_end->ca2;
+ }
+ }
+
+ if (!auth)
+ {
+ if (primary)
+ {
+ if (local)
+ { /* "leftauth" not defined, fall back to deprecated "authby" */
+ switch (msg->add_conn.auth_method)
+ {
+ default:
+ case AUTH_CLASS_PUBKEY:
+ auth = "pubkey";
+ break;
+ case AUTH_CLASS_PSK:
+ auth = "psk";
+ break;
+ case AUTH_CLASS_EAP:
+ auth = "eap";
+ break;
+ }
+ }
+ else
+ { /* "rightauth" not defined, fall back to deprecated "eap" */
+ if (msg->add_conn.eap_type)
+ {
+ if (msg->add_conn.eap_vendor)
+ {
+ snprintf(eap_buf, sizeof(eap_buf), "eap-%d-%d",
+ msg->add_conn.eap_type,
+ msg->add_conn.eap_vendor);
+ }
+ else
+ {
+ snprintf(eap_buf, sizeof(eap_buf), "eap-%d",
+ msg->add_conn.eap_type);
+ }
+ auth = eap_buf;
+ }
+ else
+ { /* not EAP => no constraints for this peer */
+ auth = "any";
+ }
+ }
+ }
+ else
+ { /* no second authentication round, fine */
+ return NULL;
+ }
}
+ cfg = auth_cfg_create();
+
+ /* add identity and peer certifcate */
+ identity = identification_create_from_string(id);
+ if (cert)
+ {
+ certificate = this->cred->load_peer(this->cred, cert);
+ if (certificate)
+ {
+ if (local)
+ {
+ this->ca->check_for_hash_and_url(this->ca, certificate);
+ }
+ cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
+ if (identity->get_type(identity) == ID_ANY ||
+ !certificate->has_subject(certificate, identity))
+ {
+ DBG1(DBG_CFG, " peerid %Y not confirmed by certificate, "
+ "defaulting to subject DN: %Y", identity,
+ certificate->get_subject(certificate));
+ identity->destroy(identity);
+ identity = certificate->get_subject(certificate);
+ identity = identity->clone(identity);
+ }
+ }
+ }
+ cfg->add(cfg, AUTH_RULE_IDENTITY, identity);
+
+ /* CA constraint */
+ if (ca)
+ {
+ identity = identification_create_from_string(ca);
+ certificate = charon->credentials->get_cert(charon->credentials,
+ CERT_X509, KEY_ANY, identity, TRUE);
+ identity->destroy(identity);
+ if (certificate)
+ {
+ cfg->add(cfg, AUTH_RULE_CA_CERT, certificate);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "CA certificate %s not found, discarding CA "
+ "constraint", ca);
+ }
+ }
+
+ /* AC groups */
+ if (end->groups)
+ {
+ enumerator_t *enumerator;
+ char *group;
+
+ enumerator = enumerator_create_token(end->groups, ",", " ");
+ while (enumerator->enumerate(enumerator, &group))
+ {
+ identity = identification_create_from_encoding(ID_IETF_ATTR_STRING,
+ chunk_create(group, strlen(group)));
+ cfg->add(cfg, AUTH_RULE_AC_GROUP, identity);
+ }
+ enumerator->destroy(enumerator);
+ }
+
+ /* authentication metod (class, actually) */
+ if (streq(auth, "pubkey") ||
+ streq(auth, "rsasig") || streq(auth, "rsa") ||
+ streq(auth, "ecdsasig") || streq(auth, "ecdsa"))
+ {
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+ }
+ else if (streq(auth, "psk") || streq(auth, "secret"))
+ {
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+ }
+ else if (strneq(auth, "eap", 3))
+ {
+ enumerator_t *enumerator;
+ char *str;
+ int i = 0, type = 0, vendor;
+
+ cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+
+ /* parse EAP string, format: eap[-type[-vendor]] */
+ enumerator = enumerator_create_token(auth, "-", " ");
+ while (enumerator->enumerate(enumerator, &str))
+ {
+ switch (i)
+ {
+ case 1:
+ type = eap_type_from_string(str);
+ if (!type)
+ {
+ type = atoi(str);
+ if (!type)
+ {
+ DBG1(DBG_CFG, "unknown EAP method: %s", str);
+ break;
+ }
+ }
+ cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+ break;
+ case 2:
+ if (type)
+ {
+ vendor = atoi(str);
+ if (vendor)
+ {
+ cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "unknown EAP vendor: %s", str);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ i++;
+ }
+ enumerator->destroy(enumerator);
+
+ if (msg->add_conn.eap_identity)
+ {
+ if (streq(msg->add_conn.eap_identity, "%identity"))
+ {
+ identity = identification_create_from_encoding(ID_ANY,
+ chunk_empty);
+ }
+ else
+ {
+ identity = identification_create_from_string(
+ msg->add_conn.eap_identity);
+ }
+ cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, identity);
+ }
+ }
+ else
+ {
+ if (!streq(auth, "any"))
+ {
+ DBG1(DBG_CFG, "authentication method %s unknown, fallback to any",
+ auth);
+ }
+ build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+ }
+ return cfg;
+}
+
+/**
+ * build a peer_cfg from a stroke msg
+ */
+static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
+ stroke_msg_t *msg, ike_cfg_t *ike_cfg)
+{
+ identification_t *peer_id = NULL;
+ peer_cfg_t *mediated_by = NULL;
+ host_t *vip = NULL;
+ unique_policy_t unique;
+ u_int32_t rekey = 0, reauth = 0, over, jitter;
+ peer_cfg_t *peer_cfg;
+ auth_cfg_t *auth_cfg;
#ifdef ME
if (msg->add_conn.ikeme.mediation && msg->add_conn.ikeme.mediated_by)
{
DBG1(DBG_CFG, "a mediation connection cannot be a"
" mediated connection at the same time, aborting");
- me->destroy(me);
- other->destroy(other);
return NULL;
}
@@ -388,8 +552,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
{
DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
msg->add_conn.ikeme.mediated_by);
- me->destroy(me);
- other->destroy(other);
return NULL;
}
@@ -399,56 +561,19 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
"no mediation connection, aborting",
msg->add_conn.ikeme.mediated_by, msg->add_conn.name);
mediated_by->destroy(mediated_by);
- me->destroy(me);
- other->destroy(other);
return NULL;
}
- }
-
- if (msg->add_conn.ikeme.peerid)
- {
- peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
- if (!peer_id)
- {
- DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.ikeme.peerid);
- mediated_by->destroy(mediated_by);
- me->destroy(me);
- other->destroy(other);
- return NULL;
- }
- }
- else
- {
- /* no peer ID supplied, assume right ID */
- peer_id = other->clone(other);
- }
-#endif /* ME */
-
- if (msg->add_conn.me.cert)
- {
- cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert);
- if (cert)
+ if (msg->add_conn.ikeme.peerid)
{
- identification_t *issuer = cert->get_issuer(cert);
-
- *my_issuer = issuer->clone(issuer);
- this->ca->check_for_hash_and_url(this->ca, cert);
- me = update_peerid(cert, me);
- cert->destroy(cert);
+ peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
}
- }
- if (msg->add_conn.other.cert)
- {
- cert = this->cred->load_peer(this->cred, msg->add_conn.other.cert);
- if (cert)
+ else if (msg->add_conn.other.id)
{
- identification_t *issuer = cert->get_issuer(cert);
-
- *other_issuer = issuer->clone(issuer);
- other = update_peerid(cert, other);
- cert->destroy(cert);
+ peer_id = identification_create_from_string(msg->add_conn.other.id);
}
}
+#endif /* ME */
+
jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
over = msg->add_conn.rekey.margin;
if (msg->add_conn.rekey.reauth)
@@ -512,179 +637,45 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
/* other.sourceip is managed in stroke_attributes. If it is set, we define
* the pool name as the connection name, which the attribute provider
* uses to serve pool addresses. */
- return peer_cfg_create(msg->add_conn.name,
- msg->add_conn.ikev2 ? 2 : 1, ike_cfg, me, other,
+ peer_cfg = peer_cfg_create(msg->add_conn.name,
+ msg->add_conn.ikev2 ? 2 : 1, ike_cfg,
msg->add_conn.me.sendcert, unique,
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
msg->add_conn.mobike, msg->add_conn.dpd.delay,
vip, msg->add_conn.other.sourceip_size ?
msg->add_conn.name : msg->add_conn.other.sourceip,
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
-}
-
-/**
- * fill in auth_info from stroke message
- */
-static void build_auth_info(private_stroke_config_t *this,
- stroke_msg_t *msg, auth_info_t *auth,
- identification_t *my_ca,
- identification_t *other_ca)
-{
- identification_t *id;
- bool my_ca_same = FALSE;
- bool other_ca_same = FALSE;
- cert_validation_t valid;
-
- switch (msg->add_conn.crl_policy)
- {
- case CRL_STRICT_YES:
- valid = VALIDATION_GOOD;
- auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
- break;
- case CRL_STRICT_IFURI:
- valid = VALIDATION_SKIPPED;
- auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
- break;
- default:
- break;
- }
- if (msg->add_conn.me.ca)
+ /* build leftauth= */
+ auth_cfg = build_auth_cfg(this, msg, TRUE, TRUE);
+ if (auth_cfg)
{
- if (my_ca)
- {
- my_ca->destroy(my_ca);
- my_ca = NULL;
- }
- if (streq(msg->add_conn.me.ca, "%same"))
- {
- my_ca_same = TRUE;
- }
- else
- {
- my_ca = identification_create_from_string(msg->add_conn.me.ca);
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
}
-
- if (msg->add_conn.other.ca)
- {
- if (other_ca)
- {
- other_ca->destroy(other_ca);
- other_ca = NULL;
- }
- if (streq(msg->add_conn.other.ca, "%same"))
- {
- other_ca_same = TRUE;
- }
- else
- {
- other_ca = identification_create_from_string(msg->add_conn.other.ca);
- }
- }
-
- if (other_ca_same && my_ca)
- {
- other_ca = my_ca->clone(my_ca);
- }
- else if (my_ca_same && other_ca)
- {
- my_ca = other_ca->clone(other_ca);
- }
-
- if (other_ca)
- {
- DBG2(DBG_CFG, " other ca: %D", other_ca);
- certificate_t *cert = charon->credentials->get_cert(charon->credentials,
- CERT_X509, KEY_ANY, other_ca, TRUE);
- if (cert)
- {
- auth->add_item(auth, AUTHZ_CA_CERT, cert);
- cert->destroy(cert);
- }
- else
- {
- auth->add_item(auth, AUTHZ_CA_CERT_NAME, other_ca);
- }
- other_ca->destroy(other_ca);
+ else
+ { /* we require at least one config on our side */
+ peer_cfg->destroy(peer_cfg);
+ return NULL;
}
-
- if (my_ca)
+ /* build leftauth2= */
+ auth_cfg = build_auth_cfg(this, msg, TRUE, FALSE);
+ if (auth_cfg)
{
- DBG2(DBG_CFG, " my ca: %D", my_ca);
- certificate_t *cert = charon->credentials->get_cert(charon->credentials,
- CERT_X509, KEY_ANY, my_ca, TRUE);
- if (cert)
- {
- auth->add_item(auth, AUTHN_CA_CERT, cert);
- cert->destroy(cert);
- }
- else
- {
- auth->add_item(auth, AUTHN_CA_CERT_NAME, my_ca);
- }
- my_ca->destroy(my_ca);
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
}
- auth->add_item(auth, AUTHN_AUTH_CLASS, &msg->add_conn.auth_method);
- if (msg->add_conn.eap_type)
+ /* build rightauth= */
+ auth_cfg = build_auth_cfg(this, msg, FALSE, TRUE);
+ if (auth_cfg)
{
- auth->add_item(auth, AUTHN_EAP_TYPE, &msg->add_conn.eap_type);
- if (msg->add_conn.eap_vendor)
- {
- auth->add_item(auth, AUTHN_EAP_VENDOR, &msg->add_conn.eap_vendor);
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
}
-
- if (msg->add_conn.eap_identity)
+ /* build rightauth2= */
+ auth_cfg = build_auth_cfg(this, msg, FALSE, FALSE);
+ if (auth_cfg)
{
- if (streq(msg->add_conn.eap_identity, "%identity"))
- {
- id = identification_create_from_encoding(ID_ANY, chunk_empty);
- }
- else
- {
- id = identification_create_from_encoding(ID_EAP, chunk_create(
- msg->add_conn.eap_identity,
- strlen(msg->add_conn.eap_identity)));
- }
- auth->add_item(auth, AUTHN_EAP_IDENTITY, id);
- id->destroy(id);
- }
-
- if (msg->add_conn.other.groups)
- {
- chunk_t line = { msg->add_conn.other.groups,
- strlen(msg->add_conn.other.groups) };
-
- while (eat_whitespace(&line))
- {
- chunk_t group;
-
- /* extract the next comma-separated group attribute */
- if (!extract_token(&group, ',', &line))
- {
- group = line;
- line.len = 0;
- }
-
- /* remove any trailing spaces */
- while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
- {
- group.len--;
- }
-
- /* add the group attribute to the list */
- if (group.len > 0)
- {
- identification_t *ac_group;
-
- ac_group = identification_create_from_encoding(
- ID_IETF_ATTR_STRING, group);
- auth->add_item(auth, AUTHZ_AC_GROUP, ac_group);
- ac_group->destroy(ac_group);
- }
- }
+ peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
}
+ return peer_cfg;
}
/**
@@ -799,7 +790,6 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
ike_cfg_t *ike_cfg, *existing_ike;
peer_cfg_t *peer_cfg, *existing;
child_cfg_t *child_cfg;
- identification_t *my_issuer = NULL, *other_issuer = NULL;
enumerator_t *enumerator;
bool use_existing = FALSE;
@@ -808,15 +798,13 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
{
return;
}
- peer_cfg = build_peer_cfg(this, msg, ike_cfg, &my_issuer, &other_issuer);
+ peer_cfg = build_peer_cfg(this, msg, ike_cfg);
if (!peer_cfg)
{
ike_cfg->destroy(ike_cfg);
return;
}
- build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg),
- my_issuer, other_issuer);
enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
while (enumerator->enumerate(enumerator, &existing))
{
@@ -850,9 +838,7 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
else
{
/* add config to backend */
- DBG1(DBG_CFG, "added configuration '%s': %s[%D]...%s[%D]", msg->add_conn.name,
- ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
- ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+ DBG1(DBG_CFG, "added configuration '%s'", msg->add_conn.name);
this->mutex->lock(this->mutex);
this->list->insert_last(this->list, peer_cfg);
this->mutex->unlock(this->mutex);
@@ -867,34 +853,50 @@ static void del(private_stroke_config_t *this, stroke_msg_t *msg)
enumerator_t *enumerator, *children;
peer_cfg_t *peer;
child_cfg_t *child;
+ bool deleted = FALSE;
this->mutex->lock(this->mutex);
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, (void**)&peer))
{
- /* remove peer config with such a name */
- if (streq(peer->get_name(peer), msg->del_conn.name))
- {
- this->list->remove_at(this->list, enumerator);
- peer->destroy(peer);
- continue;
- }
+ bool keep = FALSE;
+
/* remove any child with such a name */
children = peer->create_child_cfg_enumerator(peer);
while (children->enumerate(children, &child))
{
if (streq(child->get_name(child), msg->del_conn.name))
{
- peer->remove_child_cfg(peer, enumerator);
+ peer->remove_child_cfg(peer, children);
child->destroy(child);
+ deleted = TRUE;
+ }
+ else
+ {
+ keep = TRUE;
}
}
children->destroy(children);
+
+ /* if peer config matches, or has no children anymore, remove it */
+ if (!keep || streq(peer->get_name(peer), msg->del_conn.name))
+ {
+ this->list->remove_at(this->list, enumerator);
+ peer->destroy(peer);
+ deleted = TRUE;
+ }
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
- DBG1(DBG_CFG, "deleted connection '%s'", msg->del_conn.name);
+ if (deleted)
+ {
+ DBG1(DBG_CFG, "deleted connection '%s'", msg->del_conn.name);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "connection '%s' not found", msg->del_conn.name);
+ }
}
/**
diff --git a/src/charon/plugins/stroke/stroke_config.h b/src/charon/plugins/stroke/stroke_config.h
index 12eb11a8f..270795e4a 100644
--- a/src/charon/plugins/stroke/stroke_config.h
+++ b/src/charon/plugins/stroke/stroke_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c
index 08d50519c..c572117a2 100644
--- a/src/charon/plugins/stroke/stroke_control.c
+++ b/src/charon/plugins/stroke/stroke_control.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_control.h"
@@ -145,11 +143,13 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
{
char *string, *pos = NULL, *name = NULL;
u_int32_t id = 0;
- bool child;
+ bool child, all = FALSE;
int len;
ike_sa_t *ike_sa;
enumerator_t *enumerator;
+ linked_list_t *ike_list, *child_list;
stroke_log_info_t info;
+ uintptr_t del;
string = msg->terminate.name;
@@ -185,19 +185,44 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
name = string;
}
else
- { /* is name[123] or name{23} */
- string[len-1] = '\0';
- id = atoi(pos + 1);
- if (id == 0)
- {
- DBG1(DBG_CFG, "error parsing string");
- return;
+ {
+ if (*(pos + 1) == '*')
+ { /* is name[*] */
+ all = TRUE;
+ *pos = '\0';
+ name = string;
+ }
+ else
+ { /* is name[123] or name{23} */
+ id = atoi(pos + 1);
+ if (id == 0)
+ {
+ DBG1(DBG_CFG, "error parsing string");
+ return;
+ }
}
}
info.out = out;
info.level = msg->output_verbosity;
+ if (id)
+ {
+ if (child)
+ {
+ charon->controller->terminate_child(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ }
+ else
+ {
+ charon->controller->terminate_ike(charon->controller, id,
+ (controller_cb_t)stroke_log, &info);
+ }
+ return;
+ }
+
+ ike_list = linked_list_create();
+ child_list = linked_list_create();
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
while (enumerator->enumerate(enumerator, &ike_sa))
{
@@ -209,35 +234,58 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
children = ike_sa->create_child_sa_iterator(ike_sa);
while (children->iterate(children, (void**)&child_sa))
{
- if ((name && streq(name, child_sa->get_name(child_sa))) ||
- (id && id == child_sa->get_reqid(child_sa)))
+ if (streq(name, child_sa->get_name(child_sa)))
{
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- enumerator->destroy(enumerator);
-
- charon->controller->terminate_child(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
+ child_list->insert_last(child_list,
+ (void*)(uintptr_t)child_sa->get_reqid(child_sa));
+ if (!all)
+ {
+ break;
+ }
}
}
children->destroy(children);
+ if (child_list->get_count(child_list) && !all)
+ {
+ break;
+ }
}
- else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
- (id && id == ike_sa->get_unique_id(ike_sa)))
+ else if (streq(name, ike_sa->get_name(ike_sa)))
{
- id = ike_sa->get_unique_id(ike_sa);
- /* unlock manager first */
- enumerator->destroy(enumerator);
-
- charon->controller->terminate_ike(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
+ ike_list->insert_last(ike_list,
+ (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ if (!all)
+ {
+ break;
+ }
}
-
}
enumerator->destroy(enumerator);
- DBG1(DBG_CFG, "no such SA found");
+
+ enumerator = child_list->create_enumerator(child_list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_child(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = ike_list->create_enumerator(ike_list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_ike(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+
+ if (child_list->get_count(child_list) == 0 &&
+ ike_list->get_count(ike_list) == 0)
+ {
+ DBG1(DBG_CFG, "no %s_SA named '%s' found",
+ child ? "CHILD" : "IKE", name);
+ }
+ ike_list->destroy(ike_list);
+ child_list->destroy(child_list);
}
/**
@@ -249,7 +297,7 @@ static void terminate_srcip(private_stroke_control_t *this,
enumerator_t *enumerator;
ike_sa_t *ike_sa;
host_t *start = NULL, *end = NULL, *vip;
- chunk_t chunk_start, chunk_end, chunk_vip;
+ chunk_t chunk_start, chunk_end = chunk_empty, chunk_vip;
if (msg->terminate_srcip.start)
{
@@ -310,13 +358,52 @@ static void terminate_srcip(private_stroke_control_t *this,
}
/**
+ * Implementation of stroke_control_t.purge_ike
+ */
+static void purge_ike(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
+{
+ enumerator_t *enumerator;
+ iterator_t *iterator;
+ ike_sa_t *ike_sa;
+ child_sa_t *child_sa;
+ linked_list_t *list;
+ uintptr_t del;
+ stroke_log_info_t info;
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+
+ list = linked_list_create();
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ iterator = ike_sa->create_child_sa_iterator(ike_sa);
+ if (!iterator->iterate(iterator, (void**)&child_sa))
+ {
+ list->insert_last(list,
+ (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ }
+ iterator->destroy(iterator);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &del))
+ {
+ charon->controller->terminate_ike(charon->controller, del,
+ (controller_cb_t)stroke_log, &info);
+ }
+ enumerator->destroy(enumerator);
+ list->destroy(list);
+}
+
+/**
* Implementation of stroke_control_t.route.
*/
static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
- stroke_log_info_t info;
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
msg->route.name);
@@ -339,10 +426,14 @@ static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
return;
}
- info.out = out;
- info.level = msg->output_verbosity;
- charon->controller->route(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ {
+ fprintf(out, "configuration '%s' routed\n", msg->route.name);
+ }
+ else
+ {
+ fprintf(out, "routing configuration '%s' failed\n", msg->route.name);
+ }
peer_cfg->destroy(peer_cfg);
child_cfg->destroy(child_cfg);
}
@@ -352,41 +443,24 @@ static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
*/
static void unroute(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
- char *name;
- ike_sa_t *ike_sa;
+ child_sa_t *child_sa;
enumerator_t *enumerator;
- stroke_log_info_t info;
+ u_int32_t id;
- name = msg->terminate.name;
-
- info.out = out;
- info.level = msg->output_verbosity;
-
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
- while (enumerator->enumerate(enumerator, &ike_sa))
+ enumerator = charon->traps->create_enumerator(charon->traps);
+ while (enumerator->enumerate(enumerator, NULL, &child_sa))
{
- child_sa_t *child_sa;
- iterator_t *children;
- u_int32_t id;
-
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ if (streq(msg->unroute.name, child_sa->get_name(child_sa)))
{
- if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
- streq(name, child_sa->get_name(child_sa)))
- {
- id = child_sa->get_reqid(child_sa);
- children->destroy(children);
- enumerator->destroy(enumerator);
- charon->controller->unroute(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
- return;
- }
+ id = child_sa->get_reqid(child_sa);
+ enumerator->destroy(enumerator);
+ charon->traps->uninstall(charon->traps, id);
+ fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name);
+ return;
}
- children->destroy(children);
}
enumerator->destroy(enumerator);
- DBG1(DBG_CFG, "no such SA found");
+ fprintf(out, "configuration '%s' not found\n", msg->unroute.name);
}
/**
@@ -407,6 +481,7 @@ stroke_control_t *stroke_control_create()
this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip;
+ this->public.purge_ike = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))purge_ike;
this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
this->public.destroy = (void(*)(stroke_control_t*))destroy;
diff --git a/src/charon/plugins/stroke/stroke_control.h b/src/charon/plugins/stroke/stroke_control.h
index 26dc99b94..5a61a90a4 100644
--- a/src/charon/plugins/stroke/stroke_control.h
+++ b/src/charon/plugins/stroke/stroke_control.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -56,6 +54,13 @@ struct stroke_control_t {
void (*terminate_srcip)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
+ * Delete IKE_SAs without a CHILD_SA.
+ *
+ * @param msg stroke message
+ */
+ void (*purge_ike)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
* Route a connection.
*
* @param msg stroke message
@@ -70,9 +75,9 @@ struct stroke_control_t {
void (*unroute)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
- * Destroy a stroke_control instance.
- */
- void (*destroy)(stroke_control_t *this);
+ * Destroy a stroke_control instance.
+ */
+ void (*destroy)(stroke_control_t *this);
};
/**
diff --git a/src/charon/plugins/stroke/stroke_cred.c b/src/charon/plugins/stroke/stroke_cred.c
index 434aec22b..dc73299b8 100644
--- a/src/charon/plugins/stroke/stroke_cred.c
+++ b/src/charon/plugins/stroke/stroke_cred.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <sys/stat.h>
@@ -382,10 +380,18 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, path,
- BUILD_X509_FLAG, X509_CA,
BUILD_END);
if (cert)
{
+ x509_t *x509 = (x509_t*)cert;
+
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ cert->destroy(cert);
+ DBG1(DBG_CFG, " ca certificate must have ca basic constraint set, "
+ "discarded");
+ return NULL;
+ }
return (certificate_t*)add_cert(this, cert);
}
return NULL;
@@ -524,11 +530,32 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
switch (type)
{
case CERT_X509:
- cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_FROM_FILE, file,
- BUILD_X509_FLAG, flag,
- BUILD_END);
+ if (flag & X509_CA)
+ { /* for CA certificates, we strictly require CA
+ * basicconstraints to be set */
+ 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 must have ca "
+ "basic constraint set, discarded");
+ cert->destroy(cert);
+ cert = NULL;
+ }
+ }
+ }
+ 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)
{
add_cert(this, cert);
@@ -568,13 +595,13 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
{
if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
{
- /* CRLs get written to /etc/ipsec.d/crls/authkeyId.crl */
+ /* CRLs get written to /etc/ipsec.d/crls/<authkeyId>.crl */
crl_t *crl = (crl_t*)cert;
cert->get_ref(cert);
if (add_crl(this, crl))
{
- char buf[256];
+ char buf[BUF_LEN];
chunk_t chunk, hex;
identification_t *id;
@@ -585,14 +612,7 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
free(hex.ptr);
chunk = cert->get_encoding(cert);
- if (chunk_write(chunk, buf, 022, TRUE))
- {
- DBG1(DBG_CFG, " written crl to '%s'", buf);
- }
- else
- {
- DBG1(DBG_CFG, " writing crl to '%s' failed", buf);
- }
+ chunk_write(chunk, buf, "crl", 022, TRUE);
free(chunk.ptr);
}
}
@@ -905,26 +925,13 @@ static void load_secrets(private_stroke_cred_t *this)
continue;
}
- if (type == SHARED_EAP)
+ /* NULL terminate the ID string */
+ *(id.ptr + id.len) = '\0';
+ peer_id = identification_create_from_string(id.ptr);
+ if (peer_id->get_type(peer_id) == ID_ANY)
{
- /* we use a special EAP identity type for EAP secrets */
- peer_id = identification_create_from_encoding(ID_EAP, id);
- }
- else
- {
- /* NULL terminate the ID string */
- *(id.ptr + id.len) = '\0';
- peer_id = identification_create_from_string(id.ptr);
- if (peer_id == NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
- goto error;
- }
- if (peer_id->get_type(peer_id) == ID_ANY)
- {
- peer_id->destroy(peer_id);
- continue;
- }
+ peer_id->destroy(peer_id);
+ continue;
}
shared_key->add_owner(shared_key, peer_id);
diff --git a/src/charon/plugins/stroke/stroke_cred.h b/src/charon/plugins/stroke/stroke_cred.h
index fc7121622..8bc042f13 100644
--- a/src/charon/plugins/stroke/stroke_cred.h
+++ b/src/charon/plugins/stroke/stroke_cred.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_list.c b/src/charon/plugins/stroke/stroke_list.c
index 94b3def3a..564a511a1 100644
--- a/src/charon/plugins/stroke/stroke_list.c
+++ b/src/charon/plugins/stroke/stroke_list.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_list.h"
@@ -55,23 +53,6 @@ struct private_stroke_list_t {
};
/**
- * get the authentication class of a config
- */
-auth_class_t get_auth_class(peer_cfg_t *config)
-{
- auth_class_t *class;
- auth_info_t *auth_info;
-
- auth_info = config->get_auth(config);
- if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
- {
- return *class;
- }
- /* fallback to pubkey authentication */
- return AUTH_CLASS_PUBKEY;
-}
-
-/**
* log an IKE_SA to out
*/
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
@@ -91,7 +72,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
fprintf(out, " %V ago", &now, &established);
}
- fprintf(out, ", %H[%D]...%H[%D]\n",
+ fprintf(out, ", %H[%Y]...%H[%Y]\n",
ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa),
ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa));
@@ -110,9 +91,11 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
{
time_t rekey, reauth;
+ peer_cfg_t *peer_cfg;
rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY);
reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH);
+ peer_cfg = ike_sa->get_peer_cfg(ike_sa);
if (rekey)
{
@@ -120,9 +103,24 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
}
if (reauth)
{
- fprintf(out, ", %N reauthentication in %V", auth_class_names,
- get_auth_class(ike_sa->get_peer_cfg(ike_sa)),
- &reauth, &now);
+ bool first = TRUE;
+ enumerator_t *enumerator;
+ auth_cfg_t *auth;
+
+ fprintf(out, ", ");
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, TRUE);
+ while (enumerator->enumerate(enumerator, &auth))
+ {
+ if (!first)
+ {
+ fprintf(out, "+");
+ }
+ first = FALSE;
+ fprintf(out, "%N", auth_class_names,
+ auth->get(auth, AUTH_RULE_AUTH_CLASS));
+ }
+ enumerator->destroy(enumerator);
+ fprintf(out, " reauthentication in %V", &reauth, &now);
}
if (!rekey && !reauth)
{
@@ -195,7 +193,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "%N", encryption_algorithm_names, encr_alg);
if (encr_size)
{
- fprintf(out, "-%d", encr_size);
+ fprintf(out, "_%u", encr_size);
}
}
if (int_alg != AUTH_UNDEFINED)
@@ -203,7 +201,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "/%N", integrity_algorithm_names, int_alg);
if (int_size)
{
- fprintf(out, "-%d", int_size);
+ fprintf(out, "_%u", int_size);
}
}
}
@@ -212,7 +210,14 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
rekey = child_sa->get_lifetime(child_sa, FALSE);
if (rekey)
{
- fprintf(out, "in %V", &now, &rekey);
+ if (now > rekey)
+ {
+ fprintf(out, "active");
+ }
+ else
+ {
+ fprintf(out, "in %V", &now, &rekey);
+ }
}
else
{
@@ -248,6 +253,107 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
}
/**
+ * Log a configs local or remote authentication config to out
+ */
+static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
+{
+ enumerator_t *enumerator, *rules;
+ auth_rule_t rule;
+ auth_cfg_t *auth;
+ auth_class_t auth_class;
+ identification_t *id;
+ certificate_t *cert;
+ cert_validation_t valid;
+ char *name;
+
+ name = peer_cfg->get_name(peer_cfg);
+
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
+ while (enumerator->enumerate(enumerator, &auth))
+ {
+ fprintf(out, "%12s: %s [%Y] uses ", name, local ? "local: " : "remote:",
+ auth->get(auth, AUTH_RULE_IDENTITY));
+
+ auth_class = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
+ if (auth_class != AUTH_CLASS_EAP)
+ {
+ fprintf(out, "%N authentication\n", auth_class_names, auth_class);
+ }
+ else
+ {
+ if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE) == EAP_NAK)
+ {
+ fprintf(out, "EAP authentication");
+ }
+ else
+ {
+ if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
+ {
+ fprintf(out, "EAP_%d-%d authentication",
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
+ }
+ else
+ {
+ fprintf(out, "%N authentication", eap_type_names,
+ (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE));
+ }
+ }
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (id)
+ {
+ fprintf(out, " with EAP identity '%Y'", id);
+ }
+ fprintf(out, "\n");
+ }
+
+ cert = auth->get(auth, AUTH_RULE_CA_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: ca: \"%Y\"\n", name, cert->get_subject(cert));
+ }
+
+ cert = auth->get(auth, AUTH_RULE_IM_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: im-ca: \"%Y\"\n", name, cert->get_subject(cert));
+ }
+
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (cert)
+ {
+ fprintf(out, "%12s: cert: \"%Y\"\n", name,
+ cert->get_subject(cert));
+ }
+
+ valid = (uintptr_t)auth->get(auth, AUTH_RULE_OCSP_VALIDATION);
+ if (valid != VALIDATION_FAILED)
+ {
+ fprintf(out, "%12s: ocsp: status must be GOOD%s\n", name,
+ (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+ }
+
+ valid = (uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION);
+ if (valid != VALIDATION_FAILED)
+ {
+ fprintf(out, "%12s: crl: status must be GOOD%s\n", name,
+ (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+ }
+
+ rules = auth->create_enumerator(auth);
+ while (rules->enumerate(rules, &rule, &id))
+ {
+ if (rule == AUTH_RULE_AC_GROUP)
+ {
+ fprintf(out, "%12s: group: %Y\n", name, id);
+ }
+ }
+ rules->destroy(rules);
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
* Implementation of stroke_list_t.status.
*/
static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
@@ -255,8 +361,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator_t *enumerator, *children;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
+ child_sa_t *child_sa;
ike_sa_t *ike_sa;
- bool found = FALSE;
+ bool first, found = FALSE;
char *name = msg->status.name;
if (all)
@@ -266,10 +373,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
host_t *host;
u_int32_t dpd;
time_t now = time(NULL);
- bool first = TRUE;
u_int size, online, offline;
- fprintf(out, "Performance:\n");
+ fprintf(out, "Status of IKEv2 charon daemon (strongSwan "VERSION"):\n");
fprintf(out, " uptime: %V, since %T\n", &now, &this->uptime, &this->uptime, FALSE);
fprintf(out, " worker threads: %d idle of %d,",
charon->processor->get_idle_threads(charon->processor),
@@ -287,6 +393,7 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator->destroy(enumerator);
fprintf(out, "\n");
+ first = TRUE;
enumerator = this->attribute->create_pool_enumerator(this->attribute);
while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline))
{
@@ -299,7 +406,7 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
first = FALSE;
fprintf(out, "Virtual IP pools (size/online/offline):\n");
}
- fprintf(out, " %s: %lu/%lu/%lu\n", pool, size, online, offline);
+ fprintf(out, " %s: %u/%u/%u\n", pool, size, online, offline);
}
enumerator->destroy(enumerator);
@@ -313,138 +420,42 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
enumerator->destroy(enumerator);
fprintf(out, "Connections:\n");
- enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
- while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+ enumerator = charon->backends->create_peer_cfg_enumerator(
+ charon->backends, NULL, NULL, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
{
- void *ptr;
- certificate_t *cert;
- auth_item_t item;
- auth_info_t *auth;
- enumerator_t *auth_enumerator;
- identification_t *my_ca = NULL, *other_ca = NULL;
- identification_t *eap_identity = NULL;
- u_int32_t *eap_type = NULL;
- bool ac_groups = FALSE;
-
if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
(name && !streq(name, peer_cfg->get_name(peer_cfg))))
{
continue;
}
- /* determine any required CAs, EAP type, EAP identity,
- * and the presence of AC groups
- */
- auth = peer_cfg->get_auth(peer_cfg);
- auth_enumerator = auth->create_item_enumerator(auth);
- while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
- {
- switch (item)
- {
- case AUTHN_EAP_TYPE:
- eap_type = (u_int32_t *)ptr;
- break;
- case AUTHN_EAP_IDENTITY:
- eap_identity = (identification_t *)ptr;
- break;
- case AUTHN_CA_CERT:
- cert = (certificate_t *)ptr;
- my_ca = cert->get_subject(cert);
- break;
- case AUTHN_CA_CERT_NAME:
- my_ca = (identification_t *)ptr;
- break;
- case AUTHZ_CA_CERT:
- cert = (certificate_t *)ptr;
- other_ca = cert->get_subject(cert);
- break;
- case AUTHZ_CA_CERT_NAME:
- other_ca = (identification_t *)ptr;
- break;
- case AUTHZ_AC_GROUP:
- ac_groups = TRUE;
- break;
- default:
- break;
- }
- }
- auth_enumerator->destroy(auth_enumerator);
-
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
- ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
- ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
- if (my_ca || other_ca)
- {
- fprintf(out, "%12s: CAs: ", peer_cfg->get_name(peer_cfg));
- if (my_ca)
- {
- fprintf(out, "\"%D\"...", my_ca);
- }
- else
- {
- fprintf(out, "%%any...");
- }
- if (other_ca)
- {
- fprintf(out, "\"%D\"\n", other_ca);
- }
- else
- {
- fprintf(out, "%%any\n");
- }
- }
-
- if (ac_groups)
- {
- bool first = TRUE;
-
- fprintf(out, "%12s: groups: ", peer_cfg->get_name(peer_cfg));
- auth_enumerator = auth->create_item_enumerator(auth);
- while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
- {
- if (item == AUTHZ_AC_GROUP)
- {
- identification_t *group = (identification_t *)ptr;
-
- fprintf(out, "%s%D", first? "":", ", group);
- first = FALSE;
- }
- }
- auth_enumerator->destroy(auth_enumerator);
- fprintf(out, "\n");
- }
-
- fprintf(out, "%12s: %N ", peer_cfg->get_name(peer_cfg),
- auth_class_names, get_auth_class(peer_cfg));
- if (eap_type)
- {
- fprintf(out, "and %N ", eap_type_names, *eap_type);
- }
- fprintf(out, "authentication");
- if (eap_identity)
- {
- fprintf(out, ", EAP identity: '%D'", eap_identity);
- }
+ fprintf(out, "%12s: %s...%s", peer_cfg->get_name(peer_cfg),
+ ike_cfg->get_my_addr(ike_cfg), ike_cfg->get_other_addr(ike_cfg));
+
dpd = peer_cfg->get_dpd(peer_cfg);
if (dpd)
{
fprintf(out, ", dpddelay=%us", dpd);
}
fprintf(out, "\n");
-
+
+ log_auth_cfgs(out, peer_cfg, TRUE);
+ log_auth_cfgs(out, peer_cfg, FALSE);
+
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
while (children->enumerate(children, &child_cfg))
{
linked_list_t *my_ts, *other_ts;
-
+
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: %#R=== %#R", child_cfg->get_name(child_cfg),
+ fprintf(out, "%12s: child: %#R=== %#R", child_cfg->get_name(child_cfg),
my_ts, other_ts);
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
-
+
if (dpd)
{
fprintf(out, ", dpdaction=%N", action_names,
@@ -456,13 +467,25 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
}
enumerator->destroy(enumerator);
}
+
+ first = TRUE;
+ enumerator = charon->traps->create_enumerator(charon->traps);
+ while (enumerator->enumerate(enumerator, NULL, &child_sa))
+ {
+ if (first)
+ {
+ fprintf(out, "Routed Connections:\n");
+ first = FALSE;
+ }
+ log_child_sa(out, child_sa, all);
+ }
+ enumerator->destroy(enumerator);
fprintf(out, "Security Associations:\n");
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
while (enumerator->enumerate(enumerator, &ike_sa))
{
bool ike_printed = FALSE;
- child_sa_t *child_sa;
iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
@@ -588,8 +611,8 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
key_type_names, public->get_type(public),
public->get_keysize(public) * 8,
private ? ", has private key" : "");
- fprintf(out, " keyid: %D\n", keyid);
- fprintf(out, " subjkey: %D\n", id);
+ fprintf(out, " keyid: %Y\n", keyid);
+ fprintf(out, " subjkey: %Y\n", id);
DESTROY_IF(private);
public->destroy(public);
}
@@ -645,7 +668,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
{
fprintf(out, ", ");
}
- fprintf(out, "%D", altName);
+ fprintf(out, "%Y", altName);
}
if (!first_altName)
{
@@ -653,8 +676,8 @@ static void stroke_list_certs(linked_list_t *list, char *label,
}
enumerator->destroy(enumerator);
- fprintf(out, " subject: \"%D\"\n", cert->get_subject(cert));
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
fprintf(out, " serial: %#B\n", &serial);
/* list validity */
@@ -699,8 +722,8 @@ static void stroke_list_certs(linked_list_t *list, char *label,
key_type_names, public->get_type(public),
public->get_keysize(public) * 8,
private ? ", has private key" : "");
- fprintf(out, " keyid: %D\n", keyid);
- fprintf(out, " subjkey: %D\n", id);
+ fprintf(out, " keyid: %Y\n", keyid);
+ fprintf(out, " subjkey: %Y\n", id);
DESTROY_IF(private);
public->destroy(public);
}
@@ -708,7 +731,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
}
@@ -744,17 +767,17 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
if (entityName)
{
- fprintf(out, " holder: \"%D\"\n", entityName);
+ fprintf(out, " holder: \"%Y\"\n", entityName);
}
if (holderIssuer)
{
- fprintf(out, " hissuer: \"%D\"\n", holderIssuer);
+ fprintf(out, " hissuer: \"%Y\"\n", holderIssuer);
}
if (holderSerial.ptr)
{
fprintf(out, " hserial: %#B\n", &holderSerial);
}
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
fprintf(out, " serial: %#B\n", &serial);
/* list validity */
@@ -778,7 +801,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
enumerator->destroy(enumerator);
@@ -808,7 +831,7 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
}
fprintf(out, "\n");
- fprintf(out, " issuer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
/* list optional crlNumber */
if (serial.ptr)
@@ -851,7 +874,7 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
/* list optional authorityKeyIdentifier */
if (authkey)
{
- fprintf(out, " authkey: %D\n", authkey);
+ fprintf(out, " authkey: %Y\n", authkey);
}
}
enumerator->destroy(enumerator);
@@ -876,7 +899,7 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
first = FALSE;
}
- fprintf(out, " signer: \"%D\"\n", cert->get_issuer(cert));
+ fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert));
}
enumerator->destroy(enumerator);
}
@@ -1019,7 +1042,7 @@ static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool,
{
if (!address || address->ip_equals(address, lease))
{
- fprintf(out, " %15H %s '%D'\n",
+ fprintf(out, " %15H %s '%Y'\n",
lease, on ? "online" : "offline", id);
found++;
}
diff --git a/src/charon/plugins/stroke/stroke_list.h b/src/charon/plugins/stroke/stroke_list.h
index 73a6ff6e4..2430abfbb 100644
--- a/src/charon/plugins/stroke/stroke_list.h
+++ b/src/charon/plugins/stroke/stroke_list.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_plugin.c b/src/charon/plugins/stroke/stroke_plugin.c
index 6933fc074..22c1125a1 100644
--- a/src/charon/plugins/stroke/stroke_plugin.c
+++ b/src/charon/plugins/stroke/stroke_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_plugin.h"
diff --git a/src/charon/plugins/stroke/stroke_plugin.h b/src/charon/plugins/stroke/stroke_plugin.h
index b4c367c6e..6e9d556ad 100644
--- a/src/charon/plugins/stroke/stroke_plugin.h
+++ b/src/charon/plugins/stroke/stroke_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: stroke.h 3589 2008-03-13 14:14:44Z martin $
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_shared_key.c b/src/charon/plugins/stroke/stroke_shared_key.c
index 9c21eb830..8f53f509d 100644
--- a/src/charon/plugins/stroke/stroke_shared_key.c
+++ b/src/charon/plugins/stroke/stroke_shared_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_shared_key.h"
diff --git a/src/charon/plugins/stroke/stroke_shared_key.h b/src/charon/plugins/stroke/stroke_shared_key.h
index b456095ae..224062100 100644
--- a/src/charon/plugins/stroke/stroke_shared_key.h
+++ b/src/charon/plugins/stroke/stroke_shared_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c
index 53edde031..f61171e22 100644
--- a/src/charon/plugins/stroke/stroke_socket.c
+++ b/src/charon/plugins/stroke/stroke_socket.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "stroke_socket.h"
@@ -143,18 +141,28 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->address);
pop_string(msg, &end->subnets);
pop_string(msg, &end->sourceip);
+ pop_string(msg, &end->auth);
+ pop_string(msg, &end->auth2);
pop_string(msg, &end->id);
+ pop_string(msg, &end->id2);
pop_string(msg, &end->cert);
+ pop_string(msg, &end->cert2);
pop_string(msg, &end->ca);
+ pop_string(msg, &end->ca2);
pop_string(msg, &end->groups);
pop_string(msg, &end->updown);
DBG2(DBG_CFG, " %s=%s", label, end->address);
DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
+ DBG2(DBG_CFG, " %sauth=%s", label, end->auth);
+ DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
+ DBG2(DBG_CFG, " %sid2=%s", label, end->id2);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
+ DBG2(DBG_CFG, " %scert2=%s", label, end->cert2);
DBG2(DBG_CFG, " %sca=%s", label, end->ca);
+ DBG2(DBG_CFG, " %sca2=%s", label, end->ca2);
DBG2(DBG_CFG, " %sgroups=%s", label, end->groups);
DBG2(DBG_CFG, " %supdown=%s", label, end->updown);
}
@@ -333,8 +341,15 @@ static void stroke_reread(private_stroke_socket_t *this,
static void stroke_purge(private_stroke_socket_t *this,
stroke_msg_t *msg, FILE *out)
{
- charon->credentials->flush_cache(charon->credentials,
- CERT_X509_OCSP_RESPONSE);
+ if (msg->purge.flags & PURGE_OCSP)
+ {
+ charon->credentials->flush_cache(charon->credentials,
+ CERT_X509_OCSP_RESPONSE);
+ }
+ if (msg->purge.flags & PURGE_IKE)
+ {
+ this->control->purge_ike(this->control, msg, out);
+ }
}
/**
@@ -351,16 +366,16 @@ static void stroke_leases(private_stroke_socket_t *this,
debug_t get_group_from_name(char *type)
{
- if (strcasecmp(type, "any") == 0) return DBG_ANY;
- else if (strcasecmp(type, "mgr") == 0) return DBG_MGR;
- else if (strcasecmp(type, "ike") == 0) return DBG_IKE;
- else if (strcasecmp(type, "chd") == 0) return DBG_CHD;
- else if (strcasecmp(type, "job") == 0) return DBG_JOB;
- else if (strcasecmp(type, "cfg") == 0) return DBG_CFG;
- else if (strcasecmp(type, "knl") == 0) return DBG_KNL;
- else if (strcasecmp(type, "net") == 0) return DBG_NET;
- else if (strcasecmp(type, "enc") == 0) return DBG_ENC;
- else if (strcasecmp(type, "lib") == 0) return DBG_LIB;
+ if (strcaseeq(type, "any")) return DBG_ANY;
+ else if (strcaseeq(type, "mgr")) return DBG_MGR;
+ else if (strcaseeq(type, "ike")) return DBG_IKE;
+ else if (strcaseeq(type, "chd")) return DBG_CHD;
+ else if (strcaseeq(type, "job")) return DBG_JOB;
+ else if (strcaseeq(type, "cfg")) return DBG_CFG;
+ else if (strcaseeq(type, "knl")) return DBG_KNL;
+ else if (strcaseeq(type, "net")) return DBG_NET;
+ else if (strcaseeq(type, "enc")) return DBG_ENC;
+ else if (strcaseeq(type, "lib")) return DBG_LIB;
else return -1;
}
@@ -561,8 +576,11 @@ static job_requeue_t receive(private_stroke_socket_t *this)
*/
static bool open_socket(private_stroke_socket_t *this)
{
- struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
+ struct sockaddr_un socket_addr;
mode_t old;
+
+ socket_addr.sun_family = AF_UNIX;
+ strcpy(socket_addr.sun_path, STROKE_SOCKET);
/* set up unix socket */
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
diff --git a/src/charon/plugins/stroke/stroke_socket.h b/src/charon/plugins/stroke/stroke_socket.h
index 7a772c56c..6073f5133 100644
--- a/src/charon/plugins/stroke/stroke_socket.h
+++ b/src/charon/plugins/stroke/stroke_socket.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/uci/Makefile.in b/src/charon/plugins/uci/Makefile.in
index a29d2d4b1..e599135cb 100644
--- a/src/charon/plugins/uci/Makefile.in
+++ b/src/charon/plugins/uci/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -227,8 +236,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -326,7 +335,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/uci/uci_config.c b/src/charon/plugins/uci/uci_config.c
index c9d54a532..e697e8be6 100644
--- a/src/charon/plugins/uci/uci_config.c
+++ b/src/charon/plugins/uci/uci_config.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -83,24 +81,6 @@ static proposal_t *create_proposal(char *string, protocol_id_t proto)
}
/**
- * create an identity, with fallback to %any
- */
-static identification_t *create_id(char *string)
-{
- identification_t *id = NULL;
-
- if (string)
- {
- id = identification_create_from_string(string);
- }
- if (!id)
- {
- id = identification_create_from_encoding(ID_ANY, chunk_empty);
- }
- return id;
-}
-
-/**
* create an traffic selector, fallback to dynamic
*/
static traffic_selector_t *create_ts(char *string)
@@ -163,8 +143,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
char *remote_id, *remote_addr, *remote_net;
child_cfg_t *child_cfg;
ike_cfg_t *ike_cfg;
- auth_info_t *auth;
- auth_class_t class;
+ auth_cfg_t *auth;
/* defaults */
name = "unnamed";
@@ -187,16 +166,26 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
ike_cfg = ike_cfg_create(FALSE, FALSE, local_addr, remote_addr);
ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
this->peer_cfg = peer_cfg_create(
- name, 2, ike_cfg, create_id(local_id), create_id(remote_id),
- CERT_SEND_IF_ASKED, UNIQUE_NO,
+ name, 2, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
1, create_rekey(ike_rekey), 0, /* keytries, rekey, reauth */
1800, 900, /* jitter, overtime */
TRUE, 60, /* mobike, dpddelay */
NULL, NULL, /* vip, pool */
FALSE, NULL, NULL); /* mediation, med by, peer id */
- auth = this->peer_cfg->get_auth(this->peer_cfg);
- class = AUTH_CLASS_PSK;
- auth->add_item(auth, AUTHN_AUTH_CLASS, &class);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_string(local_id));
+ this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, TRUE);
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+ if (remote_id)
+ {
+ auth->add(auth, AUTH_RULE_IDENTITY,
+ identification_create_from_string(remote_id));
+ }
+ this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
child_cfg = child_cfg_create(name,
create_rekey(esp_rekey) + 300, create_rekey(ike_rekey), 300,
NULL, TRUE, MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
diff --git a/src/charon/plugins/uci/uci_config.h b/src/charon/plugins/uci/uci_config.h
index 67893f771..eac05b1df 100644
--- a/src/charon/plugins/uci/uci_config.h
+++ b/src/charon/plugins/uci/uci_config.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/uci/uci_control.c b/src/charon/plugins/uci/uci_control.c
index 2ffdd2b7b..f74224fa7 100644
--- a/src/charon/plugins/uci/uci_control.c
+++ b/src/charon/plugins/uci/uci_control.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -39,15 +37,15 @@ typedef struct private_uci_control_t private_uci_control_t;
* private data of uci_control_t
*/
struct private_uci_control_t {
-
+
/**
- * Public part
- */
+ * Public part
+ */
uci_control_t public;
-
+
/**
- * Job
- */
+ * Job
+ */
callback_job_t *job;
};
@@ -86,13 +84,14 @@ static void status(private_uci_control_t *this, char *name)
char buf[2048];
FILE *out = NULL;
- configs = charon->backends->create_peer_cfg_enumerator(charon->backends);
- while (configs->enumerate(configs, &peer_cfg))
- {
- if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
- {
- continue;
- }
+ configs = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ NULL, NULL, NULL, NULL);
+ while (configs->enumerate(configs, &peer_cfg))
+ {
+ if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
+ {
+ continue;
+ }
sas = charon->controller->create_ike_sa_enumerator(charon->controller);
while (sas->enumerate(sas, &ike_sa))
{
@@ -108,9 +107,9 @@ static void status(private_uci_control_t *this, char *name)
continue;
}
}
- fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa),
- ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa));
-
+ fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa),
+ ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa));
+
children = ike_sa->create_child_sa_iterator(ike_sa);
while (children->iterate(children, (void**)&child_sa))
{
@@ -118,7 +117,7 @@ static void status(private_uci_control_t *this, char *name)
child_sa->get_traffic_selectors(child_sa, FALSE));
}
children->destroy(children);
- fprintf(out, "\n");
+ fprintf(out, "\n");
}
sas->destroy(sas);
}
@@ -142,7 +141,7 @@ static void initiate(private_uci_control_t *this, char *name)
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
enumerator_t *enumerator;
-
+
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, name);
if (peer_cfg)
{
@@ -174,7 +173,7 @@ static void terminate(private_uci_control_t *this, char *name)
enumerator_t *enumerator;
ike_sa_t *ike_sa;
u_int id;
-
+
enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
while (enumerator->enumerate(enumerator, &ike_sa))
{
@@ -240,7 +239,7 @@ static job_requeue_t receive(private_uci_control_t *this)
char message[128];
int oldstate, len;
FILE *in;
-
+
memset(message, 0, sizeof(message));
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
in = fopen(FIFO_FILE, "r");
@@ -281,9 +280,9 @@ static void destroy(private_uci_control_t *this)
uci_control_t *uci_control_create()
{
private_uci_control_t *this = malloc_thing(private_uci_control_t);
-
+
this->public.destroy = (void(*)(uci_control_t*))destroy;
-
+
unlink(FIFO_FILE);
if (mkfifo(FIFO_FILE, S_IRUSR|S_IWUSR) != 0)
{
diff --git a/src/charon/plugins/uci/uci_control.h b/src/charon/plugins/uci/uci_control.h
index b5db32226..527ed82e7 100644
--- a/src/charon/plugins/uci/uci_control.h
+++ b/src/charon/plugins/uci/uci_control.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/uci/uci_creds.c b/src/charon/plugins/uci/uci_creds.c
index 60f6fc934..05bc6e109 100644
--- a/src/charon/plugins/uci/uci_creds.c
+++ b/src/charon/plugins/uci/uci_creds.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "uci_creds.h"
@@ -81,10 +79,6 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
if (me)
{
local = identification_create_from_string(local_id);
- if (!local)
- {
- continue;
- }
*me = this->me ? this->me->matches(this->me, local)
: ID_MATCH_ANY;
local->destroy(local);
@@ -96,10 +90,6 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
if (other)
{
remote = identification_create_from_string(remote_id);
- if (!remote)
- {
- continue;
- }
*other = this->other ? this->other->matches(this->other, remote)
: ID_MATCH_ANY;
remote->destroy(remote);
diff --git a/src/charon/plugins/uci/uci_creds.h b/src/charon/plugins/uci/uci_creds.h
index f1573a8a3..de50984a9 100644
--- a/src/charon/plugins/uci/uci_creds.h
+++ b/src/charon/plugins/uci/uci_creds.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/uci/uci_parser.c b/src/charon/plugins/uci/uci_parser.c
index 8f4acb938..f994e36f7 100644
--- a/src/charon/plugins/uci/uci_parser.c
+++ b/src/charon/plugins/uci/uci_parser.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "uci_parser.h"
diff --git a/src/charon/plugins/uci/uci_parser.h b/src/charon/plugins/uci/uci_parser.h
index b3e76962b..ef3d7b0f5 100644
--- a/src/charon/plugins/uci/uci_parser.h
+++ b/src/charon/plugins/uci/uci_parser.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/uci/uci_plugin.c b/src/charon/plugins/uci/uci_plugin.c
index fd84b224c..3ab4c92f8 100644
--- a/src/charon/plugins/uci/uci_plugin.c
+++ b/src/charon/plugins/uci/uci_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "uci_plugin.h"
diff --git a/src/charon/plugins/uci/uci_plugin.h b/src/charon/plugins/uci/uci_plugin.h
index d9a888aa1..e7743227c 100644
--- a/src/charon/plugins/uci/uci_plugin.h
+++ b/src/charon/plugins/uci/uci_plugin.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/unit_tester/Makefile.am b/src/charon/plugins/unit_tester/Makefile.am
index 9c86aa69f..50c5e0362 100644
--- a/src/charon/plugins/unit_tester/Makefile.am
+++ b/src/charon/plugins/unit_tester/Makefile.am
@@ -8,7 +8,6 @@ plugin_LTLIBRARIES = libstrongswan-unit-tester.la
libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \
tests/test_enumerator.c \
tests/test_auth_info.c \
- tests/test_fips_prf.c \
tests/test_curl.c \
tests/test_mysql.c \
tests/test_sqlite.c \
@@ -16,11 +15,10 @@ libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \
tests/test_rsa_gen.c \
tests/test_cert.c \
tests/test_med_db.c \
- tests/test_aes.c \
tests/test_chunk.c \
tests/test_pool.c \
tests/test_agent.c \
- tests/test_rng.c
+ tests/test_id.c
libstrongswan_unit_tester_la_LDFLAGS = -module
diff --git a/src/charon/plugins/unit_tester/Makefile.in b/src/charon/plugins/unit_tester/Makefile.in
index 537ec127e..2ee5e48d8 100644
--- a/src/charon/plugins/unit_tester/Makefile.in
+++ b/src/charon/plugins/unit_tester/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -51,10 +51,10 @@ pluginLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(plugin_LTLIBRARIES)
libstrongswan_unit_tester_la_LIBADD =
am_libstrongswan_unit_tester_la_OBJECTS = unit_tester.lo \
- test_enumerator.lo test_auth_info.lo test_fips_prf.lo \
- test_curl.lo test_mysql.lo test_sqlite.lo test_mutex.lo \
- test_rsa_gen.lo test_cert.lo test_med_db.lo test_aes.lo \
- test_chunk.lo test_pool.lo test_agent.lo test_rng.lo
+ test_enumerator.lo test_auth_info.lo test_curl.lo \
+ test_mysql.lo test_sqlite.lo test_mutex.lo test_rsa_gen.lo \
+ test_cert.lo test_med_db.lo test_chunk.lo test_pool.lo \
+ test_agent.lo test_id.lo
libstrongswan_unit_tester_la_OBJECTS = \
$(am_libstrongswan_unit_tester_la_OBJECTS)
libstrongswan_unit_tester_la_LINK = $(LIBTOOL) --tag=CC \
@@ -93,6 +93,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -115,6 +116,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -126,6 +130,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -139,6 +144,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -199,6 +206,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -210,6 +218,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -220,7 +229,6 @@ plugin_LTLIBRARIES = libstrongswan-unit-tester.la
libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \
tests/test_enumerator.c \
tests/test_auth_info.c \
- tests/test_fips_prf.c \
tests/test_curl.c \
tests/test_mysql.c \
tests/test_sqlite.c \
@@ -228,11 +236,10 @@ libstrongswan_unit_tester_la_SOURCES = unit_tester.c unit_tester.h tests.h \
tests/test_rsa_gen.c \
tests/test_cert.c \
tests/test_med_db.c \
- tests/test_aes.c \
tests/test_chunk.c \
tests/test_pool.c \
tests/test_agent.c \
- tests/test_rng.c
+ tests/test_id.c
libstrongswan_unit_tester_la_LDFLAGS = -module
all: all-am
@@ -243,8 +250,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -304,19 +311,17 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_aes.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_agent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth_info.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_cert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_chunk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_curl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_enumerator.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fips_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_id.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_med_db.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mutex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mysql.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_pool.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_rng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_rsa_gen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sqlite.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_tester.Plo@am__quote@
@@ -356,13 +361,6 @@ test_auth_info.lo: tests/test_auth_info.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_auth_info.lo `test -f 'tests/test_auth_info.c' || echo '$(srcdir)/'`tests/test_auth_info.c
-test_fips_prf.lo: tests/test_fips_prf.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_fips_prf.lo -MD -MP -MF $(DEPDIR)/test_fips_prf.Tpo -c -o test_fips_prf.lo `test -f 'tests/test_fips_prf.c' || echo '$(srcdir)/'`tests/test_fips_prf.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_fips_prf.Tpo $(DEPDIR)/test_fips_prf.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_fips_prf.c' object='test_fips_prf.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_fips_prf.lo `test -f 'tests/test_fips_prf.c' || echo '$(srcdir)/'`tests/test_fips_prf.c
-
test_curl.lo: tests/test_curl.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_curl.lo -MD -MP -MF $(DEPDIR)/test_curl.Tpo -c -o test_curl.lo `test -f 'tests/test_curl.c' || echo '$(srcdir)/'`tests/test_curl.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_curl.Tpo $(DEPDIR)/test_curl.Plo
@@ -412,13 +410,6 @@ test_med_db.lo: tests/test_med_db.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_med_db.lo `test -f 'tests/test_med_db.c' || echo '$(srcdir)/'`tests/test_med_db.c
-test_aes.lo: tests/test_aes.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_aes.lo -MD -MP -MF $(DEPDIR)/test_aes.Tpo -c -o test_aes.lo `test -f 'tests/test_aes.c' || echo '$(srcdir)/'`tests/test_aes.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_aes.Tpo $(DEPDIR)/test_aes.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_aes.c' object='test_aes.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_aes.lo `test -f 'tests/test_aes.c' || echo '$(srcdir)/'`tests/test_aes.c
-
test_chunk.lo: tests/test_chunk.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_chunk.lo -MD -MP -MF $(DEPDIR)/test_chunk.Tpo -c -o test_chunk.lo `test -f 'tests/test_chunk.c' || echo '$(srcdir)/'`tests/test_chunk.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_chunk.Tpo $(DEPDIR)/test_chunk.Plo
@@ -440,12 +431,12 @@ test_agent.lo: tests/test_agent.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_agent.lo `test -f 'tests/test_agent.c' || echo '$(srcdir)/'`tests/test_agent.c
-test_rng.lo: tests/test_rng.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_rng.lo -MD -MP -MF $(DEPDIR)/test_rng.Tpo -c -o test_rng.lo `test -f 'tests/test_rng.c' || echo '$(srcdir)/'`tests/test_rng.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_rng.Tpo $(DEPDIR)/test_rng.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_rng.c' object='test_rng.lo' libtool=yes @AMDEPBACKSLASH@
+test_id.lo: tests/test_id.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_id.lo -MD -MP -MF $(DEPDIR)/test_id.Tpo -c -o test_id.lo `test -f 'tests/test_id.c' || echo '$(srcdir)/'`tests/test_id.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_id.Tpo $(DEPDIR)/test_id.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/test_id.c' object='test_id.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_rng.lo `test -f 'tests/test_rng.c' || echo '$(srcdir)/'`tests/test_rng.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_id.lo `test -f 'tests/test_id.c' || echo '$(srcdir)/'`tests/test_id.c
mostlyclean-libtool:
-rm -f *.lo
@@ -458,7 +449,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/unit_tester/tests.h b/src/charon/plugins/unit_tester/tests.h
index 7a5aa5ab8..dcf2a5d18 100644
--- a/src/charon/plugins/unit_tester/tests.h
+++ b/src/charon/plugins/unit_tester/tests.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: tests.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -25,8 +23,7 @@ DEFINE_TEST("simple enumerator", test_enumerate, FALSE)
DEFINE_TEST("nested enumerator", test_enumerate_nested, FALSE)
DEFINE_TEST("filtered enumerator", test_enumerate_filtered, FALSE)
DEFINE_TEST("token enumerator", test_enumerate_token, FALSE)
-DEFINE_TEST("auth info", test_auth_info, FALSE)
-DEFINE_TEST("FIPS PRF", fips_prf_test, FALSE)
+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)
@@ -35,11 +32,9 @@ DEFINE_TEST("RSA key generation", test_rsa_gen, FALSE)
DEFINE_TEST("RSA subjectPublicKeyInfo loading", test_rsa_load_any, FALSE)
DEFINE_TEST("X509 certificate", test_cert_x509, FALSE)
DEFINE_TEST("Mediation database key fetch", test_med_db, FALSE)
-DEFINE_TEST("AES-128 encryption", test_aes128, FALSE)
-DEFINE_TEST("AES-XCBC", test_aes_xcbc, FALSE)
DEFINE_TEST("Base64 converter", test_chunk_base64, FALSE)
DEFINE_TEST("IP pool", test_pool, FALSE)
DEFINE_TEST("SSH agent", test_agent, FALSE)
-DEFINE_TEST("RNG quality", test_rng, FALSE)
+DEFINE_TEST("ID parts", test_id_parts, FALSE)
/** @}*/
diff --git a/src/charon/plugins/unit_tester/tests/test_aes.c b/src/charon/plugins/unit_tester/tests/test_aes.c
deleted file mode 100644
index 06e891d83..000000000
--- a/src/charon/plugins/unit_tester/tests/test_aes.c
+++ /dev/null
@@ -1,467 +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 <daemon.h>
-#include <library.h>
-#include <utils/mutex.h>
-
-#include <unistd.h>
-#include <sched.h>
-#include <pthread.h>
-
-/**
- * run a test using given values
- */
-static bool do_aes_test(u_char *key, int keysize, u_char *iv,
- u_char *plain, u_char *cipher, int len)
-{
- crypter_t *crypter;
- chunk_t enc, dec;
- bool good = TRUE;
-
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, keysize);
- if (!crypter)
- {
- return FALSE;
- }
- crypter->set_key(crypter, chunk_create(key, keysize));
- crypter->encrypt(crypter,
- chunk_create(plain, len), chunk_create(iv, 16), &enc);
- if (!memeq(enc.ptr, cipher, len))
- {
- good = FALSE;
- }
- crypter->decrypt(crypter, enc, chunk_create(iv, 16), &dec);
- if (!memeq(dec.ptr, plain, len))
- {
- good = FALSE;
- }
- free(enc.ptr);
- free(dec.ptr);
- crypter->destroy(crypter);
- return good;
-}
-
-/*******************************************************************************
- * AES-128 test
- ******************************************************************************/
-bool test_aes128()
-{
- /*
- * Test 1 of RFC3602
- * Key : 0x06a9214036b8a15b512e03d534120006
- * IV : 0x3dafba429d9eb430b422da802c9fac41
- * Plaintext : "Single block msg"
- * Ciphertext: 0xe353779c1079aeb82708942dbe77181a
- */
- u_char key1[] = {
- 0x06,0xa9,0x21,0x40,0x36,0xb8,0xa1,0x5b,
- 0x51,0x2e,0x03,0xd5,0x34,0x12,0x00,0x06
- };
- u_char iv1[] = {
- 0x3d,0xaf,0xba,0x42,0x9d,0x9e,0xb4,0x30,
- 0xb4,0x22,0xda,0x80,0x2c,0x9f,0xac,0x41
- };
- u_char plain1[] = {
- 'S','i','n','g','l','e',' ','b','l','o','c','k',' ','m','s','g'
- };
- u_char cipher1[] = {
- 0xe3,0x53,0x77,0x9c,0x10,0x79,0xae,0xb8,
- 0x27,0x08,0x94,0x2d,0xbe,0x77,0x18,0x1a
- };
- if (!do_aes_test(key1, 16, iv1, plain1, cipher1, sizeof(plain1)))
- {
- return FALSE;
- }
-
- /*
- * Test 2 of RFC3602
- * Key : 0xc286696d887c9aa0611bbb3e2025a45a
- * IV : 0x562e17996d093d28ddb3ba695a2e6f58
- * Plaintext : 0x000102030405060708090a0b0c0d0e0f
- * 101112131415161718191a1b1c1d1e1f
- * Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a
- * 7586602d253cfff91b8266bea6d61ab1
- */
- u_char key2[] = {
- 0xc2,0x86,0x69,0x6d,0x88,0x7c,0x9a,0xa0,
- 0x61,0x1b,0xbb,0x3e,0x20,0x25,0xa4,0x5a
- };
- u_char iv2[] = {
- 0x56,0x2e,0x17,0x99,0x6d,0x09,0x3d,0x28,
- 0xdd,0xb3,0xba,0x69,0x5a,0x2e,0x6f,0x58
- };
- u_char plain2[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
- 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
- };
- u_char cipher2[] = {
- 0xd2,0x96,0xcd,0x94,0xc2,0xcc,0xcf,0x8a,
- 0x3a,0x86,0x30,0x28,0xb5,0xe1,0xdc,0x0a,
- 0x75,0x86,0x60,0x2d,0x25,0x3c,0xff,0xf9,
- 0x1b,0x82,0x66,0xbe,0xa6,0xd6,0x1a,0xb1
- };
- if (!do_aes_test(key2, 16, iv2, plain2, cipher2, sizeof(plain2)))
- {
- return FALSE;
- }
-
- /*
- * Test 3 of RFC3603
- * Key : 0x56e47a38c5598974bc46903dba290349
- * IV : 0x8ce82eefbea0da3c44699ed7db51b7d9
- * Plaintext : 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf
- * b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
- * c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
- * d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
- * Ciphertext: 0xc30e32ffedc0774e6aff6af0869f71aa
- * 0f3af07a9a31a9c684db207eb0ef8e4e
- * 35907aa632c3ffdf868bb7b29d3d46ad
- * 83ce9f9a102ee99d49a53e87f4c3da55
- */
- u_char key3[] = {
- 0x56,0xe4,0x7a,0x38,0xc5,0x59,0x89,0x74,
- 0xbc,0x46,0x90,0x3d,0xba,0x29,0x03,0x49
- };
- u_char iv3[] = {
- 0x8c,0xe8,0x2e,0xef,0xbe,0xa0,0xda,0x3c,
- 0x44,0x69,0x9e,0xd7,0xdb,0x51,0xb7,0xd9
- };
- u_char plain3[] = {
- 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
- 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
- 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,
- 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
- 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
- 0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
- 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,
- 0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf
- };
- u_char cipher3[] = {
- 0xc3,0x0e,0x32,0xff,0xed,0xc0,0x77,0x4e,
- 0x6a,0xff,0x6a,0xf0,0x86,0x9f,0x71,0xaa,
- 0x0f,0x3a,0xf0,0x7a,0x9a,0x31,0xa9,0xc6,
- 0x84,0xdb,0x20,0x7e,0xb0,0xef,0x8e,0x4e,
- 0x35,0x90,0x7a,0xa6,0x32,0xc3,0xff,0xdf,
- 0x86,0x8b,0xb7,0xb2,0x9d,0x3d,0x46,0xad,
- 0x83,0xce,0x9f,0x9a,0x10,0x2e,0xe9,0x9d,
- 0x49,0xa5,0x3e,0x87,0xf4,0xc3,0xda,0x55
- };
- if (!do_aes_test(key3, 16, iv3, plain3, cipher3, sizeof(plain3)))
- {
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * run a single xcbc test for prf and signer
- */
-static bool do_xcbc_test(u_int8_t *key, size_t keylen, u_int8_t *mac,
- u_int8_t *plain, size_t len)
-{
- signer_t *signer;
- prf_t *prf;
- u_int8_t res[16];
-
- prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
- if (!prf)
- {
- return FALSE;
- }
- prf->set_key(prf, chunk_create(key, keylen));
- prf->get_bytes(prf, chunk_create(plain, len), res);
- if (!memeq(res, mac, 16))
- {
- DBG1(DBG_CFG, "expected %b\ngot %b", mac, 16, res, 16);
- prf->destroy(prf);
- return FALSE;
- }
- prf->destroy(prf);
-
- signer = lib->crypto->create_signer(lib->crypto, AUTH_AES_XCBC_96);
- if (!signer)
- {
- return FALSE;
- }
- signer->set_key(signer, chunk_create(key, keylen));
- if (!signer->verify_signature(signer, chunk_create(plain, len),
- chunk_create(mac, 12)))
- {
- return FALSE;
- }
- signer->destroy(signer);
- return TRUE;
-}
-
-
-/*******************************************************************************
- * AES_XCBC mac test
- ******************************************************************************/
-bool test_aes_xcbc()
-{
- /* Vectors from RFC 3566 */
-
- /* Test Case #1 : AES-XCBC-MAC-96 with 0-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : <empty string>
- * AES-XCBC-MAC : 75f0251d528ac01c4573dfd584d79f29
- * AES-XCBC-MAC-96: 75f0251d528ac01c4573dfd5
- */
- u_char key1[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain1[] = {
- };
- u_char mac1[] = {
- 0x75,0xf0,0x25,0x1d,0x52,0x8a,0xc0,0x1c,
- 0x45,0x73,0xdf,0xd5,0x84,0xd7,0x9f,0x29
- };
- if (!do_xcbc_test(key1, 16, mac1, plain1, sizeof(plain1)))
- {
- return FALSE;
- }
-
- /*
- * Test Case #2 : AES-XCBC-MAC-96 with 3-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 000102
- * AES-XCBC-MAC : 5b376580ae2f19afe7219ceef172756f
- * AES-XCBC-MAC-96: 5b376580ae2f19afe7219cee
- */
- u_char key2[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain2[] = {
- 0x00,0x01,0x02
- };
- u_char mac2[] = {
- 0x5b,0x37,0x65,0x80,0xae,0x2f,0x19,0xaf,
- 0xe7,0x21,0x9c,0xee,0xf1,0x72,0x75,0x6f
- };
- if (!do_xcbc_test(key2, 16, mac2, plain2, sizeof(plain2)))
- {
- return FALSE;
- }
-
- /* Test Case #3 : AES-XCBC-MAC-96 with 16-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 000102030405060708090a0b0c0d0e0f
- * AES-XCBC-MAC : d2a246fa349b68a79998a4394ff7a263
- * AES-XCBC-MAC-96: d2a246fa349b68a79998a439
- */
- u_char key3[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain3[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char mac3[] = {
- 0xd2,0xa2,0x46,0xfa,0x34,0x9b,0x68,0xa7,
- 0x99,0x98,0xa4,0x39,0x4f,0xf7,0xa2,0x63
- };
- if (!do_xcbc_test(key3, 16, mac3, plain3, sizeof(plain3)))
- {
- return FALSE;
- }
-
- /* Test Case #4 : AES-XCBC-MAC-96 with 20-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 000102030405060708090a0b0c0d0e0f10111213
- * AES-XCBC-MAC : 47f51b4564966215b8985c63055ed308
- * AES-XCBC-MAC-96: 47f51b4564966215b8985c63
- */
- u_char key4[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain4[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13
- };
- u_char mac4[] = {
- 0x47,0xf5,0x1b,0x45,0x64,0x96,0x62,0x15,
- 0xb8,0x98,0x5c,0x63,0x05,0x5e,0xd3,0x08
- };
- if (!do_xcbc_test(key4, 16, mac4, plain4, sizeof(plain4)))
- {
- return FALSE;
- }
-
- /* Test Case #5 : AES-XCBC-MAC-96 with 32-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 000102030405060708090a0b0c0d0e0f10111213141516171819
- * 1a1b1c1d1e1f
- * AES-XCBC-MAC : f54f0ec8d2b9f3d36807734bd5283fd4
- * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
- */
- u_char key5[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain5[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
- 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
- };
- u_char mac5[] = {
- 0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
- 0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
- };
- if (!do_xcbc_test(key5, 16, mac5, plain5, sizeof(plain5)))
- {
- return FALSE;
- }
-
- /* Test Case #7 : AES-XCBC-MAC-96 with 1000-byte input
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 00000000000000000000 ... 00000000000000000000
- * [1000 bytes]
- * AES-XCBC-MAC : f0dafee895db30253761103b5d84528f
- * AES-XCBC-MAC-96: f0dafee895db30253761103b
- */
- u_char key7[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain7[1000];
- memset(plain7, 0, 1000);
- u_char mac7[] = {
- 0xf0,0xda,0xfe,0xe8,0x95,0xdb,0x30,0x25,
- 0x37,0x61,0x10,0x3b,0x5d,0x84,0x52,0x8f
- };
- if (!do_xcbc_test(key7, 16, mac7, plain7, sizeof(plain7)))
- {
- return FALSE;
- }
-
- /* variable key test, RFC4434 */
-
- /* Test Case AES-XCBC-PRF-128 with 20-byte input
- * Key : 00010203040506070809
- * Message : 000102030405060708090a0b0c0d0e0f10111213
- * PRF Output : 0fa087af7d866e7653434e602fdde835
- */
- u_char key8[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,
- };
- u_char plain8[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13
- };
- u_char mac8[] = {
- 0x0f,0xa0,0x87,0xaf,0x7d,0x86,0x6e,0x76,
- 0x53,0x43,0x4e,0x60,0x2f,0xdd,0xe8,0x35
- };
- if (!do_xcbc_test(key8, 10, mac8, plain8, sizeof(plain8)))
- {
- return FALSE;
- }
-
- /* Test Case AES-XCBC-PRF-128 with 20-byte input
- * Key : 000102030405060708090a0b0c0d0e0fedcb
- * Message : 000102030405060708090a0b0c0d0e0f10111213
- * PRF Output : 8cd3c93ae598a9803006ffb67c40e9e4
- */
- u_char key9[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0xed,0xcb
- };
- u_char plain9[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13
- };
- u_char mac9[] = {
- 0x8c,0xd3,0xc9,0x3a,0xe5,0x98,0xa9,0x80,
- 0x30,0x06,0xff,0xb6,0x7c,0x40,0xe9,0xe4
- };
- if (!do_xcbc_test(key9, 18, mac9, plain9, sizeof(plain9)))
- {
- return FALSE;
- }
-
-
- /* Test Case #10 : AES-XCBC-MAC-96 with 32-byte input using append mode
- * Key (K) : 000102030405060708090a0b0c0d0e0f
- * Message (M) : 000102030405060708090a0b0c0d0e0f10111213141516171819
- * 1a1b1c1d1e1f
- * AES-XCBC-MAC : f54f0ec8d2b9f3d36807734bd5283fd4
- * AES-XCBC-MAC-96: f54f0ec8d2b9f3d36807734b
- */
- u_char key10[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
- };
- u_char plain10[] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
- 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
- };
- u_char mac10[] = {
- 0xf5,0x4f,0x0e,0xc8,0xd2,0xb9,0xf3,0xd3,
- 0x68,0x07,0x73,0x4b,0xd5,0x28,0x3f,0xd4
- };
- int i;
- prf_t *prf = lib->crypto->create_prf(lib->crypto, PRF_AES128_XCBC);
- u_char res[16];
- if (!prf)
- {
- return FALSE;
- }
- prf->set_key(prf, chunk_create(key10, sizeof(key10)));
- for (i = 0; i < 4; i++)
- { /* bytes 0 - 3, 1 byte at once */
- prf->get_bytes(prf, chunk_create(plain10 + i, 1), NULL);
- }
- for (i = 4; i < 5; i+=8)
- { /* bytes 4 - 11, at once */
- prf->get_bytes(prf, chunk_create(plain10 + i, 8), NULL);
- }
- for (i = 12; i < 24; i+=4)
- { /* bytes 12 - 23, in blocks of 4 */
- prf->get_bytes(prf, chunk_create(plain10 + i, 4), NULL);
- }
- for (i = 0; i < 4; i++)
- { /* 4 zero blobs */
- prf->get_bytes(prf, chunk_create(NULL, 0), NULL);
- }
- for (i = 24; i < 25; i+=8)
- { /* bytes 24 - 32, at once */
- prf->get_bytes(prf, chunk_create(plain10 + i, 8), res);
- }
- if (!memeq(res, mac10, 16))
- {
- DBG1(DBG_CFG, "expected %b\ngot %b", mac10, 16, res, 16);
- prf->destroy(prf);
- return FALSE;
- }
- prf->destroy(prf);
-
- return TRUE;
-}
-
diff --git a/src/charon/plugins/unit_tester/tests/test_auth_info.c b/src/charon/plugins/unit_tester/tests/test_auth_info.c
index 1719190b1..37bdd1087 100644
--- a/src/charon/plugins/unit_tester/tests/test_auth_info.c
+++ b/src/charon/plugins/unit_tester/tests/test_auth_info.c
@@ -15,7 +15,7 @@
#include <daemon.h>
#include <library.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
char buf[] = {0x01,0x02,0x03,0x04};
@@ -75,14 +75,14 @@ chunk_t certchunk = chunk_from_buf(certbuf);
/*******************************************************************************
* auth info test
******************************************************************************/
-bool test_auth_info()
+bool test_auth_cfg()
{
- auth_info_t *auth = auth_info_create(), *auth2;
+ auth_cfg_t *auth = auth_cfg_create(), *auth2;
certificate_t *c1, *c2;
enumerator_t *enumerator;
int round = 0;
void *value;
- auth_item_t type;
+ auth_rule_t type;
c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, certchunk,
@@ -92,8 +92,9 @@ bool test_auth_info()
return FALSE;
}
- auth->add_item(auth, AUTHN_SUBJECT_CERT, c1);
- if (!auth->get_item(auth, AUTHN_SUBJECT_CERT, (void**)&c2))
+ auth->add(auth, AUTH_RULE_SUBJECT_CERT, c1->get_ref(c1));
+ c2 = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (!c2)
{
return FALSE;
}
@@ -102,11 +103,11 @@ bool test_auth_info()
return FALSE;
}
- enumerator = auth->create_item_enumerator(auth);
+ enumerator = auth->create_enumerator(auth);
while (enumerator->enumerate(enumerator, &type, &value))
{
round++;
- if (round == 1 && type == AUTHN_SUBJECT_CERT && value == c1)
+ if (round == 1 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
{
continue;
}
@@ -114,20 +115,20 @@ bool test_auth_info()
}
enumerator->destroy(enumerator);
- auth2 = auth_info_create();
- auth2->add_item(auth2, AUTHN_CA_CERT, c1);
- auth2->merge(auth2, auth);
+ 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_item_enumerator(auth2);
+ enumerator = auth2->create_enumerator(auth2);
while (enumerator->enumerate(enumerator, &type, &value))
{
round++;
- if (round == 1 && type == AUTHN_CA_CERT && value == c1)
+ if (round == 1 && type == AUTH_RULE_CA_CERT && value == c1)
{
continue;
}
- if (round == 2 && type == AUTHN_SUBJECT_CERT && value == c1)
+ if (round == 2 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
{
continue;
}
diff --git a/src/charon/plugins/unit_tester/tests/test_fips_prf.c b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
deleted file mode 100644
index 29612143e..000000000
--- a/src/charon/plugins/unit_tester/tests/test_fips_prf.c
+++ /dev/null
@@ -1,64 +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 <utils/linked_list.h>
-#include <daemon.h>
-
-/*******************************************************************************
- * fips prf known value test
- ******************************************************************************/
-bool fips_prf_test()
-{
- prf_t *prf;
- u_int8_t key_buf[] = {
- 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
- 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
- 0xeb, 0x5a, 0x38, 0xb6
- };
- u_int8_t seed_buf[] = {
- 0x00
- };
- u_int8_t result_buf[] = {
- 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
- 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
- 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
- 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
- 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
- };
- chunk_t key = chunk_from_buf(key_buf);
- chunk_t seed = chunk_from_buf(seed_buf);
- chunk_t expected = chunk_from_buf(result_buf);
- chunk_t result;
-
- prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
- if (prf == NULL)
- {
- DBG1(DBG_CFG, "FIPS PRF implementation not found");
- return FALSE;
- }
- prf->set_key(prf, key);
- prf->allocate_bytes(prf, seed, &result);
- prf->destroy(prf);
- if (!chunk_equals(result, expected))
- {
- DBG1(DBG_CFG, "FIPS PRF result invalid:\nexpected: %Bresult: %B",
- &expected, &result);
- chunk_free(&result);
- return FALSE;
- }
- chunk_free(&result);
- return TRUE;
-}
-
diff --git a/src/charon/plugins/unit_tester/tests/test_id.c b/src/charon/plugins/unit_tester/tests/test_id.c
new file mode 100644
index 000000000..56dab2421
--- /dev/null
+++ b/src/charon/plugins/unit_tester/tests/test_id.c
@@ -0,0 +1,69 @@
+/*
+ * 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 <daemon.h>
+
+/*******************************************************************************
+ * identification part enumeration test
+ ******************************************************************************/
+bool test_id_parts()
+{
+ identification_t *id;
+ enumerator_t *enumerator;
+ id_part_t part;
+ chunk_t data;
+ int i = 0;
+
+ id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
+
+ enumerator = id->create_part_enumerator(id);
+ while (enumerator->enumerate(enumerator, &part, &data))
+ {
+ switch (i++)
+ {
+ case 0:
+ if (part != ID_PART_RDN_C ||
+ !chunk_equals(data, chunk_create("CH", 2)))
+ {
+ return FALSE;
+ }
+ break;
+ case 1:
+ if (part != ID_PART_RDN_O ||
+ !chunk_equals(data, chunk_create("strongSwan", 10)))
+ {
+ return FALSE;
+ }
+ break;
+ case 2:
+ if (part != ID_PART_RDN_CN ||
+ !chunk_equals(data, chunk_create("tester", 6)))
+ {
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ if (i < 3)
+ {
+ return FALSE;
+ }
+ enumerator->destroy(enumerator);
+ id->destroy(id);
+ return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_med_db.c b/src/charon/plugins/unit_tester/tests/test_med_db.c
index d65eb0cc4..7b4603bd7 100644
--- a/src/charon/plugins/unit_tester/tests/test_med_db.c
+++ b/src/charon/plugins/unit_tester/tests/test_med_db.c
@@ -33,8 +33,8 @@ bool test_med_db()
chunk_t keyid = chunk_from_buf(keyid_buf);
identification_t *id, *found;
enumerator_t *enumerator;
- auth_info_t *auth;
public_key_t *public;
+ auth_cfg_t *auth;
bool good = FALSE;
id = identification_create_from_encoding(ID_KEY_ID, keyid);
diff --git a/src/charon/plugins/unit_tester/tests/test_pool.c b/src/charon/plugins/unit_tester/tests/test_pool.c
index b11f71704..ba5330fd9 100644
--- a/src/charon/plugins/unit_tester/tests/test_pool.c
+++ b/src/charon/plugins/unit_tester/tests/test_pool.c
@@ -25,32 +25,24 @@
static void* testing(void *thread)
{
- int i;
- auth_info_t *auth;
+ int i;
host_t *addr[ALLOCS];
identification_t *id[ALLOCS];
-
- auth = auth_info_create();
-
/* prepare identities */
for (i = 0; i < ALLOCS; i++)
{
char buf[256];
- snprintf(buf, sizeof(buf), "%d-%d@strongswan.org", (int)thread, i);
+ snprintf(buf, sizeof(buf), "%d-%d@strongswan.org", (uintptr_t)thread, i);
id[i] = identification_create_from_string(buf);
- if (!id[i])
- {
- return (void*)FALSE;
- }
}
/* allocate addresses */
for (i = 0; i < ALLOCS; i++)
{
addr[i] = charon->attributes->acquire_address(charon->attributes,
- "test", id[i], auth, NULL);
+ "test", id[i], NULL);
if (!addr[i])
{
return (void*)FALSE;
@@ -69,7 +61,6 @@ static void* testing(void *thread)
addr[i]->destroy(addr[i]);
id[i]->destroy(id[i]);
}
- auth->destroy(auth);
return (void*)TRUE;
}
@@ -79,7 +70,7 @@ static void* testing(void *thread)
******************************************************************************/
bool test_pool()
{
- int i;
+ uintptr_t i;
void *res;
pthread_t thread[THREADS];
diff --git a/src/charon/plugins/unit_tester/tests/test_rng.c b/src/charon/plugins/unit_tester/tests/test_rng.c
deleted file mode 100644
index 60cbf2d36..000000000
--- a/src/charon/plugins/unit_tester/tests/test_rng.c
+++ /dev/null
@@ -1,221 +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 <daemon.h>
-#include <library.h>
-#include <utils/mutex.h>
-
-#include <unistd.h>
-#include <sched.h>
-#include <pthread.h>
-
-static bool test_monobit(chunk_t data)
-{
- int i, j, bits = 0;
-
- for (i = 0; i < data.len; i++)
- {
- for (j = 0; j < 8; j++)
- {
- if (data.ptr[i] & (1<<j))
- {
- bits++;
- }
- }
- }
- DBG1(DBG_CFG, " Monobit: %d/%d bits set", bits, data.len * 8);
- if (bits > 9654 && bits < 10346)
- {
- return TRUE;
- }
- return FALSE;
-}
-
-static bool test_poker(chunk_t data)
-{
- int i, counter[16];
- double sum = 0.0;
-
- memset(counter, 0, sizeof(counter));
-
- for (i = 0; i < data.len; i++)
- {
- counter[data.ptr[i] & 0x0F]++;
- counter[(data.ptr[i] & 0xF0) >> 4]++;
- }
-
- for (i = 0; i < countof(counter); i++)
- {
- sum += (counter[i] * counter[i]) / 5000.0 * 16.0;
- }
- sum -= 5000.0;
- DBG1(DBG_CFG, " Poker: %f", sum);
- if (sum > 1.03 && sum < 57.4)
- {
- return TRUE;
- }
- return FALSE;
-}
-
-static bool test_runs(chunk_t data)
-{
- int i, j, zero_runs[7], one_runs[7], zero = 0, one = 0, longrun = 0;
- bool ok = TRUE;
-
- memset(one_runs, 0, sizeof(zero_runs));
- memset(zero_runs, 0, sizeof(one_runs));
-
- for (i = 0; i < data.len; i++)
- {
- for (j = 0; j < 8; j++)
- {
- if (data.ptr[i] & (1<<j))
- {
- if (one)
- {
- if (++one >= 34)
- {
- longrun++;
- break;
- }
- }
- else
- {
- zero_runs[min(6, zero)]++;
- zero = 0;
- one = 1;
- }
- }
- else
- {
- if (zero)
- {
- if (++zero >= 34)
- {
- longrun++;
- break;
- }
- }
- else
- {
- one_runs[min(6, one)]++;
- one = 0;
- zero = 1;
- }
- }
- }
- }
-
- DBG1(DBG_CFG, " Runs: zero: %d/%d/%d/%d/%d/%d, one: %d/%d/%d/%d/%d/%d, "
- "longruns: %d",
- zero_runs[1], zero_runs[2], zero_runs[3],
- zero_runs[4], zero_runs[5], zero_runs[6],
- one_runs[1], one_runs[2], one_runs[3],
- one_runs[4], one_runs[5], one_runs[6],
- longrun);
-
- if (longrun)
- {
- return FALSE;
- }
-
- for (i = 1; i < countof(zero_runs); i++)
- {
- switch (i)
- {
- case 1:
- ok &= zero_runs[i] > 2267 && zero_runs[i] < 2733;
- ok &= one_runs[i] > 2267 && one_runs[i] < 2733;
- break;
- case 2:
- ok &= zero_runs[i] > 1079 && zero_runs[i] < 1421;
- ok &= one_runs[i] > 1079 && one_runs[i] < 1421;
- break;
- case 3:
- ok &= zero_runs[i] > 502 && zero_runs[i] < 748;
- ok &= one_runs[i] > 502 && one_runs[i] < 748;
- break;
- case 4:
- ok &= zero_runs[i] > 223 && zero_runs[i] < 402;
- ok &= one_runs[i] > 223 && one_runs[i] < 402;
- break;
- case 5:
- ok &= zero_runs[i] > 90 && zero_runs[i] < 223;
- ok &= one_runs[i] > 90 && one_runs[i] < 223;
- break;
- case 6:
- ok &= zero_runs[i] > 90 && zero_runs[i] < 223;
- ok &= one_runs[i] > 90 && one_runs[i] < 223;
- break;
- }
- if (!ok)
- {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static bool test_rng_quality(rng_quality_t quality)
-{
- rng_t *rng;
- chunk_t chunk;
-
- rng = lib->crypto->create_rng(lib->crypto, quality);
- if (!rng)
- {
- return FALSE;
- }
- DBG1(DBG_CFG, "%N", rng_quality_names, quality);
- rng->allocate_bytes(rng, 2500, &chunk);
-
- if (!test_monobit(chunk))
- {
- return FALSE;
- }
- if (!test_poker(chunk))
- {
- return FALSE;
- }
- if (!test_runs(chunk))
- {
- return FALSE;
- }
-
- free(chunk.ptr);
- rng->destroy(rng);
- return TRUE;
-}
-
-/**
- * run a test using given values
- */
-bool test_rng()
-{
- if (!test_rng_quality(RNG_WEAK))
- {
- return FALSE;
- }
- if (!test_rng_quality(RNG_STRONG))
- {
- return FALSE;
- }
- if (!test_rng_quality(RNG_REAL))
- {
- return FALSE;
- }
- return TRUE;
-}
-
diff --git a/src/charon/plugins/unit_tester/tests/test_rsa_gen.c b/src/charon/plugins/unit_tester/tests/test_rsa_gen.c
index f13bb5bbf..1b7af63ee 100644
--- a/src/charon/plugins/unit_tester/tests/test_rsa_gen.c
+++ b/src/charon/plugins/unit_tester/tests/test_rsa_gen.c
@@ -22,7 +22,7 @@
bool test_rsa_gen()
{
char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
- chunk_t data = chunk_from_buf(buf), sig;
+ chunk_t data = chunk_from_buf(buf), sig, crypt, plain;
private_key_t *private;
public_key_t *public;
u_int key_size;
@@ -59,6 +59,24 @@ bool test_rsa_gen()
return FALSE;
}
free(sig.ptr);
+ if (!public->encrypt(public, data, &crypt))
+ {
+ DBG1(DBG_CFG, "encrypting data with RSA failed");
+ return FALSE;
+ }
+ if (!private->decrypt(private, crypt, &plain))
+ {
+ DBG1(DBG_CFG, "decrypting data with RSA failed");
+ return FALSE;
+ }
+ if (!chunk_equals(data, plain))
+ {
+ DBG1(DBG_CFG, "decrpyted data invalid, expected %B, got %B", &
+ data, &plain);
+ return FALSE;
+ }
+ chunk_clear(&crypt);
+ chunk_clear(&plain);
public->destroy(public);
private->destroy(private);
}
diff --git a/src/charon/plugins/unit_tester/unit_tester.c b/src/charon/plugins/unit_tester/unit_tester.c
index 28c6b4c11..c9651e601 100644
--- a/src/charon/plugins/unit_tester/unit_tester.c
+++ b/src/charon/plugins/unit_tester/unit_tester.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: unit_tester.c 3491 2008-02-22 14:04:00Z martin $
*/
#include "unit_tester.h"
diff --git a/src/charon/plugins/unit_tester/unit_tester.h b/src/charon/plugins/unit_tester/unit_tester.h
index 760b0389b..33b13313d 100644
--- a/src/charon/plugins/unit_tester/unit_tester.h
+++ b/src/charon/plugins/unit_tester/unit_tester.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: unit_tester.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/plugins/updown/Makefile.in b/src/charon/plugins/updown/Makefile.in
index 15bc7b95c..d0aac79f9 100644
--- a/src/charon/plugins/updown/Makefile.in
+++ b/src/charon/plugins/updown/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/charon/plugins/updown/updown_listener.c b/src/charon/plugins/updown/updown_listener.c
index 7dfb874cb..a6be35690 100644
--- a/src/charon/plugins/updown/updown_listener.c
+++ b/src/charon/plugins/updown/updown_listener.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -188,14 +186,14 @@ static void updown(private_updown_listener_t *this, ike_sa_t *ike_sa,
"PLUTO_INTERFACE='%s' "
"PLUTO_REQID='%u' "
"PLUTO_ME='%H' "
- "PLUTO_MY_ID='%D' "
+ "PLUTO_MY_ID='%Y' "
"PLUTO_MY_CLIENT='%s/%s' "
"PLUTO_MY_CLIENT_NET='%s' "
"PLUTO_MY_CLIENT_MASK='%s' "
"PLUTO_MY_PORT='%u' "
"PLUTO_MY_PROTOCOL='%u' "
"PLUTO_PEER='%H' "
- "PLUTO_PEER_ID='%D' "
+ "PLUTO_PEER_ID='%Y' "
"PLUTO_PEER_CLIENT='%s/%s' "
"PLUTO_PEER_CLIENT_NET='%s' "
"PLUTO_PEER_CLIENT_MASK='%s' "
diff --git a/src/charon/plugins/updown/updown_listener.h b/src/charon/plugins/updown/updown_listener.h
index 0d09a4cea..cc59f61c6 100644
--- a/src/charon/plugins/updown/updown_listener.h
+++ b/src/charon/plugins/updown/updown_listener.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/plugins/updown/updown_plugin.c b/src/charon/plugins/updown/updown_plugin.c
index 2e5884222..4f0483fac 100644
--- a/src/charon/plugins/updown/updown_plugin.c
+++ b/src/charon/plugins/updown/updown_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "updown_plugin.h"
diff --git a/src/charon/plugins/updown/updown_plugin.h b/src/charon/plugins/updown/updown_plugin.h
index 99779d04e..2873b499d 100644
--- a/src/charon/plugins/updown/updown_plugin.h
+++ b/src/charon/plugins/updown/updown_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/processing/jobs/acquire_job.c b/src/charon/processing/jobs/acquire_job.c
index 50cebd88a..90b221b84 100644
--- a/src/charon/processing/jobs/acquire_job.c
+++ b/src/charon/processing/jobs/acquire_job.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: acquire_job.c 4535 2008-10-31 01:43:23Z andreas $
*/
#include "acquire_job.h"
@@ -35,12 +33,12 @@ struct private_acquire_job_t {
* reqid of the child to rekey
*/
u_int32_t reqid;
-
+
/**
* acquired source traffic selector
*/
traffic_selector_t *src_ts;
-
+
/**
* acquired destination traffic selector
*/
@@ -62,24 +60,8 @@ static void destroy(private_acquire_job_t *this)
*/
static void execute(private_acquire_job_t *this)
{
- ike_sa_t *ike_sa = NULL;
-
- if (this->reqid)
- {
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
- }
- if (ike_sa == NULL)
- {
- DBG1(DBG_JOB, "acquire job found no CHILD_SA with reqid {%d}",
- this->reqid);
- }
- else
- {
- ike_sa->acquire(ike_sa, this->reqid);
-
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- }
+ charon->traps->acquire(charon->traps, this->reqid,
+ this->src_ts, this->dst_ts);
destroy(this);
}
@@ -92,14 +74,13 @@ acquire_job_t *acquire_job_create(u_int32_t reqid,
{
private_acquire_job_t *this = malloc_thing(private_acquire_job_t);
- /* interface functions */
this->public.job_interface.execute = (void (*) (job_t *)) execute;
this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
- /* private variables */
this->reqid = reqid;
this->src_ts = src_ts;
this->dst_ts = dst_ts;
return &this->public;
}
+
diff --git a/src/charon/processing/jobs/acquire_job.h b/src/charon/processing/jobs/acquire_job.h
index feea5c72a..a78e5274d 100644
--- a/src/charon/processing/jobs/acquire_job.h
+++ b/src/charon/processing/jobs/acquire_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: acquire_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -44,9 +42,7 @@ struct acquire_job_t {
/**
* Creates a job of type ACQUIRE.
*
- * We use the reqid to find the routed CHILD_SA.
- *
- * @param reqid reqid of the CHILD_SA to acquire
+ * @param reqid reqid of the trapped CHILD_SA to acquire
* @param src_ts source traffic selector
* @param dst_ts destination traffic selector
* @return acquire_job_t object
diff --git a/src/charon/processing/jobs/callback_job.c b/src/charon/processing/jobs/callback_job.c
index f0cebd473..82b4643eb 100644
--- a/src/charon/processing/jobs/callback_job.c
+++ b/src/charon/processing/jobs/callback_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: callback_job.c 4579 2008-11-05 11:29:56Z martin $
*/
#include "callback_job.h"
diff --git a/src/charon/processing/jobs/callback_job.h b/src/charon/processing/jobs/callback_job.h
index 012bb271c..2bb209cb7 100644
--- a/src/charon/processing/jobs/callback_job.h
+++ b/src/charon/processing/jobs/callback_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: callback_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/delete_child_sa_job.c b/src/charon/processing/jobs/delete_child_sa_job.c
index 26f538d67..206f07617 100644
--- a/src/charon/processing/jobs/delete_child_sa_job.c
+++ b/src/charon/processing/jobs/delete_child_sa_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_child_sa_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "delete_child_sa_job.h"
diff --git a/src/charon/processing/jobs/delete_child_sa_job.h b/src/charon/processing/jobs/delete_child_sa_job.h
index a17c86b22..9bf6ee423 100644
--- a/src/charon/processing/jobs/delete_child_sa_job.h
+++ b/src/charon/processing/jobs/delete_child_sa_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_child_sa_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/delete_ike_sa_job.c b/src/charon/processing/jobs/delete_ike_sa_job.c
index c37e4e389..6d4639fad 100644
--- a/src/charon/processing/jobs/delete_ike_sa_job.c
+++ b/src/charon/processing/jobs/delete_ike_sa_job.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_ike_sa_job.c 4722 2008-11-28 15:44:25Z martin $
*/
#include "delete_ike_sa_job.h"
diff --git a/src/charon/processing/jobs/delete_ike_sa_job.h b/src/charon/processing/jobs/delete_ike_sa_job.h
index fcb712e43..8209977f9 100644
--- a/src/charon/processing/jobs/delete_ike_sa_job.h
+++ b/src/charon/processing/jobs/delete_ike_sa_job.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: delete_ike_sa_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/initiate_mediation_job.c b/src/charon/processing/jobs/initiate_mediation_job.c
index 4d4fd8dc6..157d84341 100644
--- a/src/charon/processing/jobs/initiate_mediation_job.c
+++ b/src/charon/processing/jobs/initiate_mediation_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: initiate_mediation_job.c 4625 2008-11-11 13:12:05Z tobias $
*/
#include "initiate_mediation_job.h"
@@ -75,6 +73,8 @@ static void initiate(private_initiate_mediation_job_t *this)
{
ike_sa_t *mediated_sa, *mediation_sa;
peer_cfg_t *mediated_cfg, *mediation_cfg;
+ enumerator_t *enumerator;
+ auth_cfg_t *auth_cfg;
mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
this->mediated_sa_id);
@@ -88,8 +88,20 @@ static void initiate(private_initiate_mediation_job_t *this)
mediation_cfg = mediated_cfg->get_mediated_by(mediated_cfg);
mediation_cfg->get_ref(mediation_cfg);
+ enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
+ TRUE);
+ if (!enumerator->enumerate(enumerator, &auth_cfg) ||
+ auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY) == NULL)
+ {
+ mediated_cfg->destroy(mediated_cfg);
+ mediation_cfg->destroy(mediation_cfg);
+ enumerator->destroy(enumerator);
+ destroy(this);
+ return;
+ }
+
if (charon->connect_manager->check_and_register(charon->connect_manager,
- mediation_cfg->get_my_id(mediation_cfg),
+ auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY),
mediated_cfg->get_peer_id(mediated_cfg),
this->mediated_sa_id))
{
diff --git a/src/charon/processing/jobs/initiate_mediation_job.h b/src/charon/processing/jobs/initiate_mediation_job.h
index 17f5e4d18..084e1b9fd 100644
--- a/src/charon/processing/jobs/initiate_mediation_job.h
+++ b/src/charon/processing/jobs/initiate_mediation_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: initiate_mediation_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/job.h b/src/charon/processing/jobs/job.h
index e0a2d1df7..acc88b124 100644
--- a/src/charon/processing/jobs/job.h
+++ b/src/charon/processing/jobs/job.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/mediation_job.c b/src/charon/processing/jobs/mediation_job.c
index c177d8db3..cf522faff 100644
--- a/src/charon/processing/jobs/mediation_job.c
+++ b/src/charon/processing/jobs/mediation_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mediation_job.c 3666 2008-03-26 18:40:19Z tobias $
*/
#include "mediation_job.h"
@@ -101,7 +99,7 @@ static void execute(private_mediation_job_t *this)
/* send callback to a peer */
if (target_sa->callback(target_sa, this->source) != SUCCESS)
{
- DBG1(DBG_JOB, "callback for '%D' to '%D' failed",
+ DBG1(DBG_JOB, "callback for '%Y' to '%Y' failed",
this->source, this->target);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, target_sa);
destroy(this);
@@ -114,7 +112,7 @@ static void execute(private_mediation_job_t *this)
if (target_sa->relay(target_sa, this->source, this->connect_id,
this->connect_key, this->endpoints, this->response) != SUCCESS)
{
- DBG1(DBG_JOB, "mediation between '%D' and '%D' failed",
+ DBG1(DBG_JOB, "mediation between '%Y' and '%Y' failed",
this->source, this->target);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, target_sa);
/* FIXME: notify the initiator */
@@ -127,13 +125,13 @@ static void execute(private_mediation_job_t *this)
}
else
{
- DBG1(DBG_JOB, "mediation between '%D' and '%D' failed: "
+ DBG1(DBG_JOB, "mediation between '%Y' and '%Y' failed: "
"SA not found", this->source, this->target);
}
}
else
{
- DBG1(DBG_JOB, "mediation between '%D' and '%D' failed: "
+ DBG1(DBG_JOB, "mediation between '%Y' and '%Y' failed: "
"peer is not online anymore", this->source, this->target);
}
destroy(this);
diff --git a/src/charon/processing/jobs/mediation_job.h b/src/charon/processing/jobs/mediation_job.h
index 08e37915f..583ea8230 100644
--- a/src/charon/processing/jobs/mediation_job.h
+++ b/src/charon/processing/jobs/mediation_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mediation_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/migrate_job.c b/src/charon/processing/jobs/migrate_job.c
index 47ff658f1..a57d0478b 100644
--- a/src/charon/processing/jobs/migrate_job.c
+++ b/src/charon/processing/jobs/migrate_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: migrate_job.c 4677 2008-11-19 15:31:27Z martin $
*/
#include "migrate_job.h"
diff --git a/src/charon/processing/jobs/migrate_job.h b/src/charon/processing/jobs/migrate_job.h
index 9f39b9730..672a09b0a 100644
--- a/src/charon/processing/jobs/migrate_job.h
+++ b/src/charon/processing/jobs/migrate_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: migrate_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/process_message_job.c b/src/charon/processing/jobs/process_message_job.c
index 33bcae6f0..1f0b3e287 100644
--- a/src/charon/processing/jobs/process_message_job.c
+++ b/src/charon/processing/jobs/process_message_job.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: process_message_job.c 3666 2008-03-26 18:40:19Z tobias $
*/
#include "process_message_job.h"
diff --git a/src/charon/processing/jobs/process_message_job.h b/src/charon/processing/jobs/process_message_job.h
index 0aae4c24e..b01d388f9 100644
--- a/src/charon/processing/jobs/process_message_job.h
+++ b/src/charon/processing/jobs/process_message_job.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: process_message_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/rekey_child_sa_job.c b/src/charon/processing/jobs/rekey_child_sa_job.c
index 42bf79d26..17fcf641b 100644
--- a/src/charon/processing/jobs/rekey_child_sa_job.c
+++ b/src/charon/processing/jobs/rekey_child_sa_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: rekey_child_sa_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "rekey_child_sa_job.h"
diff --git a/src/charon/processing/jobs/rekey_child_sa_job.h b/src/charon/processing/jobs/rekey_child_sa_job.h
index 14e4af5e1..2e2eef361 100644
--- a/src/charon/processing/jobs/rekey_child_sa_job.h
+++ b/src/charon/processing/jobs/rekey_child_sa_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: rekey_child_sa_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/rekey_ike_sa_job.c b/src/charon/processing/jobs/rekey_ike_sa_job.c
index 38aa41c27..1ceb1e144 100644
--- a/src/charon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/charon/processing/jobs/rekey_ike_sa_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: rekey_ike_sa_job.c 3793 2008-04-11 08:14:48Z martin $
*/
#include "rekey_ike_sa_job.h"
diff --git a/src/charon/processing/jobs/rekey_ike_sa_job.h b/src/charon/processing/jobs/rekey_ike_sa_job.h
index c03711d73..0d830e134 100644
--- a/src/charon/processing/jobs/rekey_ike_sa_job.h
+++ b/src/charon/processing/jobs/rekey_ike_sa_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: rekey_ike_sa_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/retransmit_job.c b/src/charon/processing/jobs/retransmit_job.c
index 89858786e..122cad853 100644
--- a/src/charon/processing/jobs/retransmit_job.c
+++ b/src/charon/processing/jobs/retransmit_job.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: retransmit_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "retransmit_job.h"
diff --git a/src/charon/processing/jobs/retransmit_job.h b/src/charon/processing/jobs/retransmit_job.h
index a20369a1b..4c9bea1c8 100644
--- a/src/charon/processing/jobs/retransmit_job.h
+++ b/src/charon/processing/jobs/retransmit_job.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: retransmit_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/roam_job.c b/src/charon/processing/jobs/roam_job.c
index 0b323ae8b..c01f83248 100644
--- a/src/charon/processing/jobs/roam_job.c
+++ b/src/charon/processing/jobs/roam_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: roam_job.c 3804 2008-04-14 11:37:46Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/processing/jobs/roam_job.h b/src/charon/processing/jobs/roam_job.h
index 6c0cbc2b7..7bb1227f5 100644
--- a/src/charon/processing/jobs/roam_job.h
+++ b/src/charon/processing/jobs/roam_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: roam_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/send_dpd_job.c b/src/charon/processing/jobs/send_dpd_job.c
index a7d0cf3f3..c6e81a56f 100644
--- a/src/charon/processing/jobs/send_dpd_job.c
+++ b/src/charon/processing/jobs/send_dpd_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: send_dpd_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/processing/jobs/send_dpd_job.h b/src/charon/processing/jobs/send_dpd_job.h
index 2b6b5fee3..91556a9d1 100644
--- a/src/charon/processing/jobs/send_dpd_job.h
+++ b/src/charon/processing/jobs/send_dpd_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: send_dpd_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/send_keepalive_job.c b/src/charon/processing/jobs/send_keepalive_job.c
index 82f6a5f55..5d3cfb530 100644
--- a/src/charon/processing/jobs/send_keepalive_job.c
+++ b/src/charon/processing/jobs/send_keepalive_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: send_keepalive_job.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/processing/jobs/send_keepalive_job.h b/src/charon/processing/jobs/send_keepalive_job.h
index 7b3fe9f60..f92e6217a 100644
--- a/src/charon/processing/jobs/send_keepalive_job.h
+++ b/src/charon/processing/jobs/send_keepalive_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: send_keepalive_job.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/jobs/update_sa_job.c b/src/charon/processing/jobs/update_sa_job.c
index acf263d25..5e6c83942 100644
--- a/src/charon/processing/jobs/update_sa_job.c
+++ b/src/charon/processing/jobs/update_sa_job.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <stdlib.h>
diff --git a/src/charon/processing/jobs/update_sa_job.h b/src/charon/processing/jobs/update_sa_job.h
index 79b89bbe3..93262d46f 100644
--- a/src/charon/processing/jobs/update_sa_job.h
+++ b/src/charon/processing/jobs/update_sa_job.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/processing/processor.c b/src/charon/processing/processor.c
index 68916937b..eb1db331b 100644
--- a/src/charon/processing/processor.c
+++ b/src/charon/processing/processor.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: processor.c 4802 2008-12-12 15:57:12Z martin $
*/
#include <stdlib.h>
diff --git a/src/charon/processing/processor.h b/src/charon/processing/processor.h
index 6ab643b1f..e56e69382 100644
--- a/src/charon/processing/processor.h
+++ b/src/charon/processing/processor.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: processor.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c
index 593a51f0b..b3633f263 100644
--- a/src/charon/processing/scheduler.c
+++ b/src/charon/processing/scheduler.c
@@ -13,13 +13,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: scheduler.c 4799 2008-12-12 09:16:31Z martin $
*/
#include <stdlib.h>
#include <pthread.h>
-#include <sys/time.h>
#include "scheduler.h"
@@ -41,7 +38,7 @@ struct event_t {
* Time to fire the event.
*/
timeval_t time;
-
+
/**
* Every event has its assigned job.
*/
@@ -63,16 +60,17 @@ typedef struct private_scheduler_t private_scheduler_t;
* Private data of a scheduler_t object.
*/
struct private_scheduler_t {
+
/**
* Public part of a scheduler_t object.
*/
scheduler_t public;
-
+
/**
* Job which queues scheduled jobs to the processor.
*/
callback_job_t *job;
-
+
/**
* The heap in which the events are stored.
*/
@@ -87,12 +85,12 @@ struct private_scheduler_t {
* The number of scheduled events.
*/
u_int event_count;
-
+
/**
* Exclusive access to list
*/
mutex_t *mutex;
-
+
/**
* Condvar to wait for next job.
*/
@@ -100,16 +98,27 @@ struct private_scheduler_t {
};
/**
- * Returns the difference of two timeval structs in milliseconds
+ * Comparse two timevals, return >0 if a > b, <0 if a < b and =0 if equal
*/
-static long time_difference(timeval_t *end, timeval_t *start)
+static int timeval_cmp(timeval_t *a, timeval_t *b)
{
- time_t s;
- suseconds_t us;
-
- s = end->tv_sec - start->tv_sec;
- us = end->tv_usec - start->tv_usec;
- return (s * 1000 + us/1000);
+ if (a->tv_sec > b->tv_sec)
+ {
+ return 1;
+ }
+ if (a->tv_sec < b->tv_sec)
+ {
+ return -1;
+ }
+ if (a->tv_usec > b->tv_usec)
+ {
+ return 1;
+ }
+ if (a->tv_usec < b->tv_usec)
+ {
+ return -1;
+ }
+ return 0;
}
/**
@@ -146,20 +155,21 @@ static event_t *remove_event(private_scheduler_t *this)
u_int child = position << 1;
if ((child + 1) <= this->event_count &&
- time_difference(&this->heap[child + 1]->time,
- &this->heap[child]->time) < 0)
+ timeval_cmp(&this->heap[child + 1]->time,
+ &this->heap[child]->time) < 0)
{
/* the "right" child is smaller */
child++;
}
- if (time_difference(&top->time, &this->heap[child]->time) <= 0)
+ if (timeval_cmp(&top->time, &this->heap[child]->time) <= 0)
{
- /* the top event fires before the smaller of the two children, stop */
+ /* the top event fires before the smaller of the two children,
+ * stop */
break;
}
- /* exchange with the smaller child */
+ /* swap with the smaller child */
this->heap[position] = this->heap[child];
position = child;
}
@@ -175,7 +185,6 @@ static job_requeue_t schedule(private_scheduler_t * this)
{
timeval_t now;
event_t *event;
- long difference;
int oldstate;
bool timed = FALSE;
@@ -185,8 +194,7 @@ static job_requeue_t schedule(private_scheduler_t * this)
if ((event = peek_event(this)) != NULL)
{
- difference = time_difference(&now, &event->time);
- if (difference >= 0)
+ if (timeval_cmp(&now, &event->time) >= 0)
{
remove_event(this);
this->mutex->unlock(this->mutex);
@@ -195,7 +203,16 @@ static job_requeue_t schedule(private_scheduler_t * this)
free(event);
return JOB_REQUEUE_DIRECT;
}
- DBG2(DBG_JOB, "next event in %ldms, waiting", -difference);
+ timersub(&event->time, &now, &now);
+ if (now.tv_sec)
+ {
+ DBG2(DBG_JOB, "next event in %ds %dms, waiting",
+ now.tv_sec, now.tv_usec/1000);
+ }
+ else
+ {
+ DBG2(DBG_JOB, "next event in %dms, waiting", now.tv_usec/1000);
+ }
timed = TRUE;
}
pthread_cleanup_push((void*)this->mutex->unlock, this->mutex);
@@ -228,25 +245,16 @@ static u_int get_job_load(private_scheduler_t *this)
}
/**
- * Implements scheduler_t.schedule_job.
+ * Implements scheduler_t.schedule_job_tv.
*/
-static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t time)
+static void schedule_job_tv(private_scheduler_t *this, job_t *job, timeval_t tv)
{
- timeval_t now;
event_t *event;
u_int position;
- time_t s;
- suseconds_t us;
event = malloc_thing(event_t);
event->job = job;
-
- /* calculate absolute time */
- s = time / 1000;
- us = (time - s * 1000) * 1000;
- gettimeofday(&now, NULL);
- event->time.tv_usec = (now.tv_usec + us) % 1000000;
- event->time.tv_sec = now.tv_sec + (now.tv_usec + us)/1000000 + s;
+ event->time = tv;
this->mutex->lock(this->mutex);
@@ -255,14 +263,15 @@ static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t time)
{
/* double the size of the heap */
this->heap_size <<= 1;
- this->heap = (event_t**)realloc(this->heap, (this->heap_size + 1) * sizeof(event_t*));
+ this->heap = (event_t**)realloc(this->heap,
+ (this->heap_size + 1) * sizeof(event_t*));
}
/* "put" the event to the bottom */
position = this->event_count;
/* then bubble it up */
- while (position > 1 && time_difference(&this->heap[position >> 1]->time,
- &event->time) > 0)
+ while (position > 1 && timeval_cmp(&this->heap[position >> 1]->time,
+ &event->time) > 0)
{
/* parent has to be fired after the new event, move up */
this->heap[position] = this->heap[position >> 1];
@@ -275,6 +284,35 @@ static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t time)
}
/**
+ * Implements scheduler_t.schedule_job.
+ */
+static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t s)
+{
+ timeval_t tv;
+
+ gettimeofday(&tv, NULL);
+ tv.tv_sec += s;
+
+ schedule_job_tv(this, job, tv);
+}
+
+/**
+ * Implements scheduler_t.schedule_job_ms.
+ */
+static void schedule_job_ms(private_scheduler_t *this, job_t *job, u_int32_t ms)
+{
+ timeval_t tv, add;
+
+ gettimeofday(&tv, NULL);
+ add.tv_sec = ms / 1000;
+ add.tv_usec = (ms % 1000) * 1000;
+
+ timeradd(&tv, &add, &tv);
+
+ schedule_job_tv(this, job, tv);
+}
+
+/**
* Implementation of scheduler_t.destroy.
*/
static void destroy(private_scheduler_t *this)
@@ -299,7 +337,9 @@ scheduler_t * scheduler_create()
private_scheduler_t *this = malloc_thing(private_scheduler_t);
this->public.get_job_load = (u_int (*) (scheduler_t *this)) get_job_load;
- this->public.schedule_job = (void (*) (scheduler_t *this, job_t *job, u_int32_t ms)) schedule_job;
+ this->public.schedule_job = (void (*) (scheduler_t *this, job_t *job, u_int32_t s)) schedule_job;
+ this->public.schedule_job_ms = (void (*) (scheduler_t *this, job_t *job, u_int32_t ms)) schedule_job_ms;
+ this->public.schedule_job_tv = (void (*) (scheduler_t *this, job_t *job, timeval_t tv)) schedule_job_tv;
this->public.destroy = (void(*)(scheduler_t*)) destroy;
/* Note: the root of the heap is at index 1 */
diff --git a/src/charon/processing/scheduler.h b/src/charon/processing/scheduler.h
index c3e177727..502f70b33 100644
--- a/src/charon/processing/scheduler.h
+++ b/src/charon/processing/scheduler.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -12,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: scheduler.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -26,25 +25,86 @@
typedef struct scheduler_t scheduler_t;
+#include <sys/time.h>
+
#include <library.h>
#include <processing/jobs/job.h>
/**
- * The scheduler queues and executes timed events.
+ * The scheduler queues timed events which are then passed to the processor.
+ *
+ * The scheduler is implemented as a heap. A heap is a special kind of tree-
+ * based data structure that satisfies the following property: if B is a child
+ * node of A, then key(A) >= (or <=) key(B). So either the element with the
+ * greatest (max-heap) or the smallest (min-heap) key is the root of the heap.
+ * We use a min-heap whith the key being the absolute unix time at which an
+ * event is scheduled. So the root is always the event that will fire next.
+ *
+ * An earlier implementation of the scheduler used a sorted linked list to store
+ * the events. That had the advantage that removing the next event was extremely
+ * fast, also, adding an event scheduled before or after all other events was
+ * equally fast (all in O(1)). The problem was, though, that adding an event
+ * in-between got slower, as the number of events grew larger (O(n)).
+ * For each connection there could be several events: IKE-rekey, NAT-keepalive,
+ * retransmissions, expire (half-open), and others. So a gateway that probably
+ * has to handle thousands of concurrent connnections has to be able to queue a
+ * large number of events as fast as possible. Locking makes this even worse, to
+ * provide thread-safety, no events can be processed, while an event is queued,
+ * so making the insertion fast is even more important.
+ *
+ * That's the advantage of the heap. Adding an element to the heap can be
+ * achieved in O(log n) - on the other hand, removing the root node also
+ * requires O(log n) operations. Consider 10000 queued events. Inserting a new
+ * event in the list implementation required up to 10000 comparisons. In the
+ * heap implementation, the worst case is about 13.3 comparisons. That's a
+ * drastic improvement.
*
- * The scheduler stores timed events and passes them to the processor.
+ * The implementation itself uses a binary tree mapped to a one-based array to
+ * store the elements. This reduces storage overhead and simplifies navigation:
+ * the children of the node at position n are at position 2n and 2n+1 (likewise
+ * the parent node of the node at position n is at position [n/2]). Thus,
+ * navigating up and down the tree is reduced to simple index computations.
+ *
+ * Adding an element to the heap works as follows: The heap is always filled
+ * from left to right, until a row is full, then the next row is filled. Mapped
+ * to an array this gets as simple as putting the new element to the first free
+ * position. In a one-based array that position equals the number of elements
+ * currently stored in the heap. Then the heap property has to be restored, i.e.
+ * the new element has to be "bubbled up" the tree until the parent node's key
+ * is smaller or the element got the new root of the tree.
+ *
+ * Removing the next event from the heap works similarly. The event itself is
+ * the root node and stored at position 1 of the array. After removing it, the
+ * root has to be replaced and the heap property has to be restored. This is
+ * done by moving the bottom element (last row, rightmost element) to the root
+ * and then "seep it down" by swapping it with child nodes until none of the
+ * children has a smaller key or it is again a leaf node.
*/
-struct scheduler_t {
-
+struct scheduler_t {
+
/**
- * Adds a event to the queue, using a relative time offset.
+ * Adds a event to the queue, using a relative time offset in s.
*
- * Schedules a job for execution using a relative time offset.
+ * @param job job to schedule
+ * @param time relative time to schedule job, in s
+ */
+ void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t s);
+
+ /**
+ * Adds a event to the queue, using a relative time offset in ms.
+ *
+ * @param job job to schedule
+ * @param time relative time to schedule job, in ms
+ */
+ void (*schedule_job_ms) (scheduler_t *this, job_t *job, u_int32_t ms);
+
+ /**
+ * Adds a event to the queue, using an absolut time.
*
- * @param job job to schedule
- * @param time relative to to schedule job (in ms)
+ * @param job job to schedule
+ * @param time absolut time to schedule job
*/
- void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t time);
+ void (*schedule_job_tv) (scheduler_t *this, job_t *job, timeval_t tv);
/**
* Returns number of jobs scheduled.
@@ -61,7 +121,7 @@ struct scheduler_t {
/**
* Create a scheduler.
- *
+ *
* @return scheduler_t object
*/
scheduler_t *scheduler_create(void);
diff --git a/src/charon/sa/authenticators/authenticator.c b/src/charon/sa/authenticators/authenticator.c
index 827c7a69a..ea8a16279 100644
--- a/src/charon/sa/authenticators/authenticator.c
+++ b/src/charon/sa/authenticators/authenticator.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2006-2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: authenticator.c 4276 2008-08-22 10:44:51Z martin $
*/
#include <string.h>
@@ -23,6 +21,7 @@
#include <sa/authenticators/pubkey_authenticator.h>
#include <sa/authenticators/psk_authenticator.h>
#include <sa/authenticators/eap_authenticator.h>
+#include <encoding/payloads/auth_payload.h>
ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
@@ -35,7 +34,8 @@ ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
"ECDSA-521 signature");
ENUM_END(auth_method_names, AUTH_ECDSA_521);
-ENUM(auth_class_names, AUTH_CLASS_PUBKEY, AUTH_CLASS_EAP,
+ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
+ "any",
"public key",
"pre-shared key",
"EAP",
@@ -44,17 +44,23 @@ ENUM(auth_class_names, AUTH_CLASS_PUBKEY, AUTH_CLASS_EAP,
/**
* Described in header.
*/
-authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
- auth_class_t class)
+authenticator_t *authenticator_create_builder(ike_sa_t *ike_sa, auth_cfg_t *cfg,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init)
{
- switch (class)
+ switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
{
+ case AUTH_CLASS_ANY:
+ /* defaults to PUBKEY */
case AUTH_CLASS_PUBKEY:
- return (authenticator_t*)pubkey_authenticator_create(ike_sa);
+ return (authenticator_t*)pubkey_authenticator_create_builder(ike_sa,
+ received_nonce, sent_init);
case AUTH_CLASS_PSK:
- return (authenticator_t*)psk_authenticator_create(ike_sa);
+ return (authenticator_t*)psk_authenticator_create_builder(ike_sa,
+ received_nonce, sent_init);
case AUTH_CLASS_EAP:
- return (authenticator_t*)eap_authenticator_create(ike_sa);
+ return (authenticator_t*)eap_authenticator_create_builder(ike_sa,
+ received_nonce, sent_nonce, received_init, sent_init);
default:
return NULL;
}
@@ -63,19 +69,32 @@ authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
/**
* Described in header.
*/
-authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,
- auth_method_t method)
+authenticator_t *authenticator_create_verifier(
+ ike_sa_t *ike_sa, message_t *message,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init)
{
- switch (method)
+ auth_payload_t *auth_payload;
+
+ auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+ if (auth_payload == NULL)
+ {
+ return (authenticator_t*)eap_authenticator_create_verifier(ike_sa,
+ received_nonce, sent_nonce, received_init, sent_init);
+ }
+ switch (auth_payload->get_auth_method(auth_payload))
{
case AUTH_RSA:
case AUTH_ECDSA_256:
case AUTH_ECDSA_384:
case AUTH_ECDSA_521:
- return (authenticator_t*)pubkey_authenticator_create(ike_sa);
+ return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa,
+ sent_nonce, received_init);
case AUTH_PSK:
- return (authenticator_t*)psk_authenticator_create(ike_sa);
+ return (authenticator_t*)psk_authenticator_create_verifier(ike_sa,
+ sent_nonce, received_init);
default:
return NULL;
}
}
+
diff --git a/src/charon/sa/authenticators/authenticator.h b/src/charon/sa/authenticators/authenticator.h
index 345cc7deb..c60881629 100644
--- a/src/charon/sa/authenticators/authenticator.h
+++ b/src/charon/sa/authenticators/authenticator.h
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: authenticator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -30,9 +28,8 @@ typedef enum auth_class_t auth_class_t;
typedef struct authenticator_t authenticator_t;
#include <library.h>
+#include <config/auth_cfg.h>
#include <sa/ike_sa.h>
-#include <config/peer_cfg.h>
-#include <encoding/payloads/auth_payload.h>
/**
* Method to use for authentication, as defined in IKEv2.
@@ -84,6 +81,8 @@ extern enum_name_t *auth_method_names;
* certificate finally dictates wich method is used.
*/
enum auth_class_t {
+ /** any class acceptable */
+ AUTH_CLASS_ANY = 0,
/** authentication using public keys (RSA, ECDSA) */
AUTH_CLASS_PUBKEY = 1,
/** authentication using a pre-shared secrets */
@@ -100,66 +99,70 @@ extern enum_name_t *auth_class_names;
/**
* Authenticator interface implemented by the various authenticators.
*
- * Currently the following two AUTH methods are supported:
- * - shared key message integrity code
- * - RSA digital signature
- * - EAP using the EAP framework and one of the EAP plugins
- * - ECDSA is supported using OpenSSL
+ * An authenticator implementation handles AUTH and EAP payloads. Received
+ * messages are passed to the process() method, to send authentication data
+ * the message is passed to the build() method.
*/
struct authenticator_t {
/**
- * Verify a received authentication payload.
+ * Process an incoming message using the authenticator.
*
- * @param ike_sa_init binary representation of received ike_sa_init
- * @param my_nonce the sent nonce
- * @param auth_payload authentication payload to verify
+ * @param message message containing authentication payloads
* @return
- * - SUCCESS,
- * - FAILED if verification failed
- * - INVALID_ARG if auth_method does not match
- * - NOT_FOUND if credentials not found
+ * - SUCCESS if authentication successful
+ * - FAILED if authentication failed
+ * - NEED_MORE if another exchange required
*/
- status_t (*verify) (authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload);
-
+ status_t (*process)(authenticator_t *this, message_t *message);
+
/**
- * Build an authentication payload to send to the other peer.
+ * Attach authentication data to an outgoing message.
*
- * @param ike_sa_init binary representation of sent ike_sa_init
- * @param other_nonce the received nonce
- * @param auth_payload the resulting authentication payload
+ * @param message message to add authentication data to
* @return
- * - SUCCESS,
- * - NOT_FOUND if credentials not found
+ * - SUCCESS if authentication successful
+ * - FAILED if authentication failed
+ * - NEED_MORE if another exchange required
*/
- status_t (*build) (authenticator_t *this, chunk_t ike_sa_init,
- chunk_t other_nonce, auth_payload_t **auth_payload);
-
+ status_t (*build)(authenticator_t *this, message_t *message);
+
/**
- * Destroys a authenticator_t object.
+ * Destroy authenticator instance.
*/
void (*destroy) (authenticator_t *this);
};
/**
- * Creates an authenticator for the specified auth class (as configured).
+ * Create an authenticator to build signatures.
*
- * @param ike_sa associated ike_sa
- * @param class class of authentication to use
- * @return authenticator_t object
+ * @param ike_sa associated ike_sa
+ * @param cfg authentication configuration
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return authenticator, NULL if not supported
*/
-authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
- auth_class_t class);
+authenticator_t *authenticator_create_builder(
+ ike_sa_t *ike_sa, auth_cfg_t *cfg,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init);
/**
- * Creates an authenticator for method (as received in payload).
+ * Create an authenticator to verify signatures.
*
- * @param ike_sa associated ike_sa
- * @param method method as found in payload
- * @return authenticator_t object
+ * @param ike_sa associated ike_sa
+ * @param message message containing authentication data
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return authenticator, NULL if not supported
*/
-authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,
- auth_method_t method);
+authenticator_t *authenticator_create_verifier(
+ ike_sa_t *ike_sa, message_t *message,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init);
#endif /** AUTHENTICATOR_H_ @}*/
diff --git a/src/charon/sa/authenticators/eap/eap_manager.c b/src/charon/sa/authenticators/eap/eap_manager.c
index c1c2d6fce..b8316036e 100644
--- a/src/charon/sa/authenticators/eap/eap_manager.c
+++ b/src/charon/sa/authenticators/eap/eap_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_manager.c 4579 2008-11-05 11:29:56Z martin $
*/
#include "eap_manager.h"
@@ -65,9 +63,9 @@ struct private_eap_manager_t {
linked_list_t *methods;
/**
- * mutex to lock methods
+ * rwlock to lock methods
*/
- mutex_t *mutex;
+ rwlock_t *lock;
};
/**
@@ -84,9 +82,9 @@ static void add_method(private_eap_manager_t *this, eap_type_t type,
entry->role = role;
entry->constructor = constructor;
- this->mutex->lock(this->mutex);
+ this->lock->write_lock(this->lock);
this->methods->insert_last(this->methods, entry);
- this->mutex->unlock(this->mutex);
+ this->lock->unlock(this->lock);
}
/**
@@ -97,7 +95,7 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
enumerator_t *enumerator;
eap_entry_t *entry;
- this->mutex->lock(this->mutex);
+ this->lock->write_lock(this->lock);
enumerator = this->methods->create_enumerator(this->methods);
while (enumerator->enumerate(enumerator, &entry))
{
@@ -108,7 +106,7 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
}
}
enumerator->destroy(enumerator);
- this->mutex->unlock(this->mutex);
+ this->lock->unlock(this->lock);
}
/**
@@ -123,7 +121,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
eap_entry_t *entry;
eap_method_t *method = NULL;
- this->mutex->lock(this->mutex);
+ this->lock->read_lock(this->lock);
enumerator = this->methods->create_enumerator(this->methods);
while (enumerator->enumerate(enumerator, &entry))
{
@@ -138,7 +136,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
}
}
enumerator->destroy(enumerator);
- this->mutex->unlock(this->mutex);
+ this->lock->unlock(this->lock);
return method;
}
@@ -148,7 +146,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
static void destroy(private_eap_manager_t *this)
{
this->methods->destroy_function(this->methods, free);
- this->mutex->destroy(this->mutex);
+ this->lock->destroy(this->lock);
free(this);
}
@@ -165,7 +163,7 @@ eap_manager_t *eap_manager_create()
this->public.destroy = (void(*)(eap_manager_t*))destroy;
this->methods = linked_list_create();
- this->mutex = mutex_create(MUTEX_DEFAULT);
+ this->lock = rwlock_create(RWLOCK_DEFAULT);
return &this->public;
}
diff --git a/src/charon/sa/authenticators/eap/eap_manager.h b/src/charon/sa/authenticators/eap/eap_manager.h
index db5535a81..667c54a8e 100644
--- a/src/charon/sa/authenticators/eap/eap_manager.h
+++ b/src/charon/sa/authenticators/eap/eap_manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c
index 2e4307eb4..1d1900301 100644
--- a/src/charon/sa/authenticators/eap/eap_method.c
+++ b/src/charon/sa/authenticators/eap/eap_method.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_method.c 4997 2009-03-24 10:24:58Z martin $
*/
#include "eap_method.h"
@@ -36,6 +34,36 @@ ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
"EAP_EXPERIMENTAL");
ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
+/*
+ * See header
+ */
+eap_type_t eap_type_from_string(char *name)
+{
+ int i;
+ static struct {
+ char *name;
+ eap_type_t type;
+ } types[] = {
+ {"identity", EAP_IDENTITY},
+ {"md5", EAP_MD5},
+ {"otp", EAP_OTP},
+ {"gtc", EAP_GTC},
+ {"sim", EAP_SIM},
+ {"aka", EAP_AKA},
+ {"mschapv2", EAP_MSCHAPV2},
+ {"radius", EAP_RADIUS},
+ };
+
+ for (i = 0; i < countof(types); i++)
+ {
+ if (strcaseeq(name, types[i].name))
+ {
+ return types[i].type;
+ }
+ }
+ return 0;
+}
+
ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
"EAP_REQUEST",
"EAP_RESPONSE",
@@ -48,3 +76,6 @@ ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_PEER",
);
+
+
+
diff --git a/src/charon/sa/authenticators/eap/eap_method.h b/src/charon/sa/authenticators/eap/eap_method.h
index 6f3da1ba7..578b89e96 100644
--- a/src/charon/sa/authenticators/eap/eap_method.h
+++ b/src/charon/sa/authenticators/eap/eap_method.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_method.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -69,6 +67,14 @@ enum eap_type_t {
extern enum_name_t *eap_type_names;
/**
+ * Lookup the EAP method type from a string.
+ *
+ * @param name EAP method name (such as "md5", "aka")
+ * @return method type, 0 if unkown
+ */
+eap_type_t eap_type_from_string(char *name);
+
+/**
* EAP code, type of an EAP message
*/
enum eap_code_t {
@@ -83,7 +89,6 @@ enum eap_code_t {
*/
extern enum_name_t *eap_code_names;
-
/**
* Interface of an EAP method for server and client side.
*
diff --git a/src/charon/sa/authenticators/eap/sim_manager.c b/src/charon/sa/authenticators/eap/sim_manager.c
index e6817ca20..51cd4fb3f 100644
--- a/src/charon/sa/authenticators/eap/sim_manager.c
+++ b/src/charon/sa/authenticators/eap/sim_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "sim_manager.h"
diff --git a/src/charon/sa/authenticators/eap/sim_manager.h b/src/charon/sa/authenticators/eap/sim_manager.h
index 69a2e4df9..3c6d66dfe 100644
--- a/src/charon/sa/authenticators/eap/sim_manager.h
+++ b/src/charon/sa/authenticators/eap/sim_manager.h
@@ -39,7 +39,7 @@ struct sim_card_t {
* The returned identity owned by the sim_card and not destroyed outside.
* The SIM card may return ID_ANY if it does not support/use an IMSI.
*
- * @return identity of type ID_EAP/ID_ANY
+ * @return identity
*/
identification_t* (*get_imsi)(sim_card_t *this);
@@ -63,7 +63,7 @@ struct sim_provider_t {
/**
* Get a single triplet to authenticate a EAP client.
*
- * @param imsi client identity of type ID_EAP
+ * @param imsi client identity
* @param rand RAND output buffer, fixed size 16 bytes
* @param sres SRES output buffer, fixed size 4 byte
* @param kc KC output buffer, fixed size 8 bytes
diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c
index 7b97fe56c..2abdf7a02 100644
--- a/src/charon/sa/authenticators/eap_authenticator.c
+++ b/src/charon/sa/authenticators/eap_authenticator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,17 +11,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_authenticator.c 5037 2009-03-26 13:58:17Z andreas $
*/
-#include <string.h>
-
#include "eap_authenticator.h"
#include <daemon.h>
-#include <config/peer_cfg.h>
#include <sa/authenticators/eap/eap_method.h>
+#include <encoding/payloads/auth_payload.h>
+#include <encoding/payloads/eap_payload.h>
typedef struct private_eap_authenticator_t private_eap_authenticator_t;
@@ -41,9 +38,24 @@ struct private_eap_authenticator_t {
ike_sa_t *ike_sa;
/**
- * Role of this authenticator, PEER or SERVER
+ * others nonce to include in AUTH calculation
+ */
+ chunk_t received_nonce;
+
+ /**
+ * our nonce to include in AUTH calculation
+ */
+ chunk_t sent_nonce;
+
+ /**
+ * others IKE_SA_INIT message data to include in AUTH calculation
+ */
+ chunk_t received_init;
+
+ /**
+ * our IKE_SA_INIT message data to include in AUTH calculation
*/
- eap_role_t role;
+ chunk_t sent_init;
/**
* Current EAP method processing
@@ -56,442 +68,514 @@ struct private_eap_authenticator_t {
chunk_t msk;
/**
- * should we do a EAP-Identity exchange as server?
+ * EAP authentication method completed successfully
*/
- bool do_eap_identity;
+ bool eap_complete;
/**
- * saved EAP type if we do eap_identity
+ * authentication payload verified successfully
*/
- eap_type_t type;
+ bool auth_complete;
/**
- * saved vendor id if we do eap_identity
+ * generated EAP payload
*/
- u_int32_t vendor;
+ eap_payload_t *eap_payload;
+
+ /**
+ * EAP identity of peer
+ */
+ identification_t *eap_identity;
};
+
/**
- * Implementation of authenticator_t.verify.
+ * load an EAP method
*/
-static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload)
+static eap_method_t *load_method(private_eap_authenticator_t *this,
+ eap_type_t type, u_int32_t vendor, eap_role_t role)
{
- chunk_t auth_data, recv_auth_data;
- identification_t *other_id;
- keymat_t *keymat;
-
- other_id = this->ike_sa->get_other_id(this->ike_sa);
- keymat = this->ike_sa->get_keymat(this->ike_sa);
-
- auth_data = keymat->get_psk_sig(keymat, TRUE, ike_sa_init, my_nonce,
- this->msk, other_id);
+ identification_t *server, *peer;
- recv_auth_data = auth_payload->get_data(auth_payload);
- if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
+ if (role == EAP_SERVER)
{
- DBG1(DBG_IKE, "verification of AUTH payload created from EAP MSK failed");
- chunk_free(&auth_data);
- return FAILED;
+ server = this->ike_sa->get_my_id(this->ike_sa);
+ peer = this->ike_sa->get_other_id(this->ike_sa);
}
- chunk_free(&auth_data);
-
- DBG1(DBG_IKE, "authentication of '%D' with %N successful",
- other_id, auth_class_names, AUTH_CLASS_EAP);
- return SUCCESS;
-}
-
-/**
- * Implementation of authenticator_t.build.
- */
-static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t other_nonce, auth_payload_t **auth_payload)
-{
- identification_t *my_id;
- chunk_t auth_data;
- keymat_t *keymat;
-
- my_id = this->ike_sa->get_my_id(this->ike_sa);
- keymat = this->ike_sa->get_keymat(this->ike_sa);
-
- DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
- my_id, auth_class_names, AUTH_CLASS_EAP);
-
- auth_data = keymat->get_psk_sig(keymat, FALSE, ike_sa_init, other_nonce,
- this->msk, my_id);
-
- *auth_payload = auth_payload_create();
- (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
- (*auth_payload)->set_data(*auth_payload, auth_data);
- chunk_free(&auth_data);
-
- return SUCCESS;
+ else
+ {
+ server = this->ike_sa->get_other_id(this->ike_sa);
+ peer = this->ike_sa->get_my_id(this->ike_sa);
+ }
+ if (this->eap_identity)
+ {
+ peer = this->eap_identity;
+ }
+ return charon->eap->create_instance(charon->eap, type, vendor,
+ role, server, peer);
}
/**
- * get the peers identity to use in the EAP method
+ * Initiate EAP conversation as server
*/
-static identification_t *get_peer_id(private_eap_authenticator_t *this)
+static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
+ bool do_identity)
{
+ auth_cfg_t *auth;
+ eap_type_t type;
identification_t *id;
- peer_cfg_t *config;
- auth_info_t *auth;
+ u_int32_t vendor;
+ eap_payload_t *out;
+
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
- id = this->ike_sa->get_eap_identity(this->ike_sa);
- if (!id)
+ /* initiate EAP-Identity exchange if required */
+ if (!this->eap_identity && do_identity)
{
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- auth = config->get_auth(config);
- if (!auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id) ||
- id->get_type(id) == ID_ANY)
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (id)
{
- if (this->role == EAP_PEER)
+ this->method = load_method(this, EAP_IDENTITY, 0, EAP_SERVER);
+ if (this->method)
{
- id = this->ike_sa->get_my_id(this->ike_sa);
- }
- else
- {
- id = this->ike_sa->get_other_id(this->ike_sa);
+ if (this->method->initiate(this->method, &out) == NEED_MORE)
+ {
+ DBG1(DBG_IKE, "initiating EAP-Identity request");
+ return out;
+ }
+ this->method->destroy(this->method);
}
+ DBG1(DBG_IKE, "EAP-Identity request configured, but not supported");
}
}
- if (id->get_type(id) == ID_EAP)
+ /* invoke real EAP method */
+ type = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE);
+ vendor = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR);
+ this->method = load_method(this, type, vendor, EAP_SERVER);
+ if (this->method &&
+ this->method->initiate(this->method, &out) == NEED_MORE)
{
- return id->clone(id);
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "initiating EAP vendor type %d-%d", type, vendor);
+
+ }
+ else
+ {
+ DBG1(DBG_IKE, "initiating %N", eap_type_names, type);
+ }
+ return out;
}
- return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
-}
-
-/**
- * get the servers identity to use in the EAP method
- */
-static identification_t *get_server_id(private_eap_authenticator_t *this)
-{
- identification_t *id;
-
- if (this->role == EAP_SERVER)
+ if (vendor)
{
- id = this->ike_sa->get_my_id(this->ike_sa);
+ DBG1(DBG_IKE, "initiating EAP vendor type %d-%d failed", type, vendor);
}
else
{
- id = this->ike_sa->get_other_id(this->ike_sa);
+ DBG1(DBG_IKE, "initiating %N failed", eap_type_names, type);
}
- if (id->get_type(id) == ID_EAP)
- {
- return id->clone(id);
- }
- return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
-}
-
-/**
- * load an EAP method using the correct identities
- */
-static eap_method_t *load_method(private_eap_authenticator_t *this,
- eap_type_t type, u_int32_t vendor, eap_role_t role)
-{
- identification_t *server, *peer;
- eap_method_t *method;
-
- server = get_server_id(this);
- peer = get_peer_id(this);
- method = charon->eap->create_instance(charon->eap, type, vendor, role,
- server, peer);
- server->destroy(server);
- peer->destroy(peer);
- return method;
+ return eap_payload_create_code(EAP_FAILURE, 0);
}
/**
- * Implementation of eap_authenticator_t.initiate
+ * Handle EAP exchange as server
*/
-static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
- u_int32_t vendor, eap_payload_t **out)
+static eap_payload_t* server_process_eap(private_eap_authenticator_t *this,
+ eap_payload_t *in)
{
- /* if initiate() is called, role is always server */
- this->role = EAP_SERVER;
-
- if (this->do_eap_identity)
- { /* do an EAP-Identity request first */
- this->type = type;
- this->vendor = vendor;
- vendor = 0;
- type = EAP_IDENTITY;
- }
+ eap_type_t type, received_type;
+ u_int32_t vendor, received_vendor;
+ eap_payload_t *out;
+ auth_cfg_t *cfg;
- if (type == 0)
+ if (in->get_code(in) != EAP_RESPONSE)
{
- DBG1(DBG_IKE,
- "client requested EAP authentication, but configuration forbids it");
- *out = eap_payload_create_code(EAP_FAILURE, 0);
- return FAILED;
+ DBG1(DBG_IKE, "received %N, sending %N",
+ eap_code_names, in->get_code(in), eap_code_names, EAP_FAILURE);
+ return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
}
- if (vendor)
- {
- DBG1(DBG_IKE, "requesting vendor specific EAP method %d-%d",
- type, vendor);
- }
- else
- {
- DBG1(DBG_IKE, "requesting EAP method %N", eap_type_names, type);
- }
- this->method = load_method(this, type, vendor, this->role);
- if (this->method == NULL)
+ type = this->method->get_type(this->method, &vendor);
+ received_type = in->get_type(in, &received_vendor);
+ if (type != received_type || vendor != received_vendor)
{
- if (vendor == 0 && type == EAP_IDENTITY)
+ if (received_vendor == 0 && received_type == EAP_NAK)
{
- DBG1(DBG_IKE, "skipping %N, no implementation found",
- eap_type_names, type);
- this->do_eap_identity = FALSE;
- return initiate(this, this->type, this->vendor, out);
+ DBG1(DBG_IKE, "received %N, sending %N",
+ eap_type_names, EAP_NAK, eap_code_names, EAP_FAILURE);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received invalid EAP response, sending %N",
+ eap_code_names, EAP_FAILURE);
}
- DBG1(DBG_IKE, "configured EAP server method not supported, sending %N",
- eap_code_names, EAP_FAILURE);
- *out = eap_payload_create_code(EAP_FAILURE, 0);
- return FAILED;
+ return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
}
- if (this->method->initiate(this->method, out) != NEED_MORE)
+
+ switch (this->method->process(this->method, in, &out))
{
- DBG1(DBG_IKE, "failed to initiate EAP exchange, sending %N",
- eap_code_names, EAP_FAILURE);
- *out = eap_payload_create_code(EAP_FAILURE, 0);
- return FAILED;
+ case NEED_MORE:
+ return out;
+ case SUCCESS:
+ if (type == EAP_IDENTITY)
+ {
+ chunk_t data;
+ char buf[256];
+
+ if (this->method->get_msk(this->method, &data) == SUCCESS)
+ {
+ snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
+ this->eap_identity = identification_create_from_string(buf);
+ DBG1(DBG_IKE, "received EAP identity '%Y'",
+ this->eap_identity);
+ }
+ /* restart EAP exchange, but with real method */
+ this->method->destroy(this->method);
+ return server_initiate_eap(this, FALSE);
+ }
+ if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
+ {
+ this->msk = chunk_clone(this->msk);
+ }
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, "
+ "%sMSK established", type, vendor,
+ this->msk.ptr ? "" : "no ");
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established",
+ eap_type_names, type, this->msk.ptr ? "" : "no ");
+ }
+ this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED,
+ TRUE);
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+ if (vendor)
+ {
+ cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+ }
+ this->eap_complete = TRUE;
+ return eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in));
+ case FAILED:
+ default:
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed for "
+ "peer %Y", type, vendor,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N failed for peer %Y",
+ eap_type_names, type,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
+ return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
}
- return NEED_MORE;
}
/**
* Processing method for a peer
*/
-static status_t process_peer(private_eap_authenticator_t *this,
- eap_payload_t *in, eap_payload_t **out)
+static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
+ eap_payload_t *in)
{
eap_type_t type;
u_int32_t vendor;
+ auth_cfg_t *auth;
+ eap_payload_t *out;
+ identification_t *id;
type = in->get_type(in, &vendor);
if (!vendor && type == EAP_IDENTITY)
{
- eap_method_t *method;
+ DESTROY_IF(this->eap_identity);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (!id || id->get_type(id) == ID_ANY)
+ {
+ id = this->ike_sa->get_my_id(this->ike_sa);
+ }
+ DBG1(DBG_IKE, "server requested %N, sending '%Y'",
+ eap_type_names, type, id);
+ this->eap_identity = id->clone(id);
- method = load_method(this, type, 0, EAP_PEER);
- if (method == NULL || method->process(method, in, out) != SUCCESS)
+ this->method = load_method(this, type, vendor, EAP_PEER);
+ if (this->method)
{
- DBG1(DBG_IKE, "EAP server requested %N, but unable to process",
- eap_type_names, type);
- DESTROY_IF(method);
- return FAILED;
+ if (this->method->process(this->method, in, &out) == SUCCESS)
+ {
+ this->method->destroy(this->method);
+ this->method = NULL;
+ return out;
+ }
+ this->method->destroy(this->method);
+ this->method = NULL;
}
- DBG1(DBG_IKE, "EAP server requested %N", eap_type_names, type);
- method->destroy(method);
- return NEED_MORE;
+ DBG1(DBG_IKE, "%N not supported, sending EAP_NAK",
+ eap_type_names, type);
+ return eap_payload_create_nak(in->get_identifier(in));
}
-
- /* create an eap_method for the first call */
if (this->method == NULL)
{
if (vendor)
{
- DBG1(DBG_IKE, "EAP server requested vendor specific EAP method %d-%d",
+ DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d",
type, vendor);
}
else
{
- DBG1(DBG_IKE, "EAP server requested %N authentication",
+ DBG1(DBG_IKE, "server requested %N authentication",
eap_type_names, type);
}
this->method = load_method(this, type, vendor, EAP_PEER);
- if (this->method == NULL)
+ if (!this->method)
{
- DBG1(DBG_IKE, "EAP server requested unsupported "
- "EAP method, sending EAP_NAK");
- *out = eap_payload_create_nak(in->get_identifier(in));
- return NEED_MORE;
+ DBG1(DBG_IKE, "EAP method not supported, sending EAP_NAK");
+ return eap_payload_create_nak(in->get_identifier(in));
}
}
type = this->method->get_type(this->method, &vendor);
- switch (this->method->process(this->method, in, out))
+ if (this->method->process(this->method, in, &out) == NEED_MORE)
+ { /* client methods should never return SUCCESS */
+ return out;
+ }
+
+ if (vendor)
{
- case NEED_MORE:
- return NEED_MORE;
- case SUCCESS:
- if (vendor)
- {
- DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded",
- type, vendor);
- }
- else
- {
- DBG1(DBG_IKE, "EAP method %N succeeded", eap_type_names, type);
- }
- return SUCCESS;
- case FAILED:
- default:
- if (vendor)
- {
- DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed",
- type, vendor);
- }
- else
- {
- DBG1(DBG_IKE, "EAP method %N failed",
- eap_type_names, type);
- }
- return FAILED;
+ DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
}
+ return NULL;
}
/**
- * handle an EAP-Identity response on the server
+ * Verify AUTH payload
*/
-static status_t process_eap_identity(private_eap_authenticator_t *this,
- eap_payload_t **out)
+static bool verify_auth(private_eap_authenticator_t *this, message_t *message,
+ chunk_t nonce, chunk_t init)
{
- chunk_t data;
- identification_t *id;
-
- if (this->method->get_msk(this->method, &data) == SUCCESS)
+ auth_payload_t *auth_payload;
+ chunk_t auth_data, recv_auth_data;
+ identification_t *other_id;
+ auth_cfg_t *auth;
+ keymat_t *keymat;
+
+ auth_payload = (auth_payload_t*)message->get_payload(message,
+ AUTHENTICATION);
+ if (!auth_payload)
{
- id = identification_create_from_encoding(ID_EAP, data);
- DBG1(DBG_IKE, "using EAP identity '%D'", id);
- this->ike_sa->set_eap_identity(this->ike_sa, id);
+ DBG1(DBG_IKE, "AUTH payload missing");
+ return FALSE;
}
- /* restart EAP exchange, but with real method */
- this->method->destroy(this->method);
- this->method = NULL;
- this->do_eap_identity = FALSE;
- return initiate(this, this->type, this->vendor, out);
+ other_id = this->ike_sa->get_other_id(this->ike_sa);
+ keymat = this->ike_sa->get_keymat(this->ike_sa);
+ auth_data = keymat->get_psk_sig(keymat, TRUE, init, nonce,
+ this->msk, other_id);
+ recv_auth_data = auth_payload->get_data(auth_payload);
+ if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
+ {
+ DBG1(DBG_IKE, "verification of AUTH payload with%s EAP MSK failed",
+ this->msk.ptr ? "" : "out");
+ chunk_free(&auth_data);
+ return FALSE;
+ }
+ chunk_free(&auth_data);
+
+ DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
+ other_id, auth_class_names, AUTH_CLASS_EAP);
+ this->auth_complete = TRUE;
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+ return TRUE;
+}
+
+/**
+ * Build AUTH payload
+ */
+static void build_auth(private_eap_authenticator_t *this, message_t *message,
+ chunk_t nonce, chunk_t init)
+{
+ auth_payload_t *auth_payload;
+ identification_t *my_id;
+ chunk_t auth_data;
+ keymat_t *keymat;
+
+ my_id = this->ike_sa->get_my_id(this->ike_sa);
+ keymat = this->ike_sa->get_keymat(this->ike_sa);
+
+ DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
+ my_id, auth_class_names, AUTH_CLASS_EAP);
+
+ auth_data = keymat->get_psk_sig(keymat, FALSE, init, nonce, this->msk, my_id);
+ auth_payload = auth_payload_create();
+ auth_payload->set_auth_method(auth_payload, AUTH_PSK);
+ auth_payload->set_data(auth_payload, auth_data);
+ message->add_payload(message, (payload_t*)auth_payload);
+ chunk_free(&auth_data);
}
/**
- * Processing method for a server
+ * Implementation of authenticator_t.process for a server
*/
static status_t process_server(private_eap_authenticator_t *this,
- eap_payload_t *in, eap_payload_t **out)
+ message_t *message)
{
- eap_type_t type;
- u_int32_t vendor;
+ eap_payload_t *eap_payload;
- type = this->method->get_type(this->method, &vendor);
+ if (this->eap_complete)
+ {
+ if (!verify_auth(this, message, this->sent_nonce, this->received_init))
+ {
+ return FAILED;
+ }
+ return NEED_MORE;
+ }
- switch (this->method->process(this->method, in, out))
+ if (!this->method)
{
- case NEED_MORE:
- return NEED_MORE;
- case SUCCESS:
- if (this->do_eap_identity)
- {
- return process_eap_identity(this, out);
- }
- if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
- {
- this->msk = chunk_clone(this->msk);
- }
- if (vendor)
- {
- DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded, "
- "%sMSK established", type, vendor,
- this->msk.ptr ? "" : "no ");
- }
- else
- {
- DBG1(DBG_IKE, "EAP method %N succeded, %sMSK established",
- eap_type_names, type, this->msk.ptr ? "" : "no ");
- }
- *out = eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in));
- return SUCCESS;
- case FAILED:
- default:
- if (vendor)
- {
- DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed for "
- "peer %D", type, vendor,
- this->ike_sa->get_other_id(this->ike_sa));
- }
- else
- {
- DBG1(DBG_IKE, "EAP method %N failed for peer '%D'",
- eap_type_names, type,
- this->ike_sa->get_other_id(this->ike_sa));
- }
- *out = eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
+ this->eap_payload = server_initiate_eap(this, TRUE);
+ }
+ else
+ {
+ eap_payload = (eap_payload_t*)message->get_payload(message,
+ EXTENSIBLE_AUTHENTICATION);
+ if (!eap_payload)
+ {
return FAILED;
+ }
+ this->eap_payload = server_process_eap(this, eap_payload);
}
+ return NEED_MORE;
}
/**
- * Implementation of eap_authenticator_t.process
+ * Implementation of authenticator_t.build for a server
*/
-static status_t process(private_eap_authenticator_t *this, eap_payload_t *in,
- eap_payload_t **out)
+static status_t build_server(private_eap_authenticator_t *this,
+ message_t *message)
{
- eap_code_t code = in->get_code(in);
+ if (this->eap_payload)
+ {
+ eap_code_t code;
+
+ code = this->eap_payload->get_code(this->eap_payload);
+ message->add_payload(message, (payload_t*)this->eap_payload);
+ this->eap_payload = NULL;
+ if (code == EAP_FAILURE)
+ {
+ return FAILED;
+ }
+ return NEED_MORE;
+ }
+ if (this->eap_complete && this->auth_complete)
+ {
+ build_auth(this, message, this->received_nonce, this->sent_init);
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+/**
+ * Implementation of authenticator_t.process for a client
+ */
+static status_t process_client(private_eap_authenticator_t *this,
+ message_t *message)
+{
+ eap_payload_t *eap_payload;
- switch (this->role)
+ if (this->eap_complete)
{
- case EAP_SERVER:
+ if (!verify_auth(this, message, this->sent_nonce, this->received_init))
{
- switch (code)
+ return FAILED;
+ }
+ return SUCCESS;
+ }
+
+ eap_payload = (eap_payload_t*)message->get_payload(message,
+ EXTENSIBLE_AUTHENTICATION);
+ if (eap_payload)
+ {
+ switch (eap_payload->get_code(eap_payload))
+ {
+ case EAP_REQUEST:
{
- case EAP_RESPONSE:
+ this->eap_payload = client_process_eap(this, eap_payload);
+ if (this->eap_payload)
{
- return process_server(this, in, out);
- }
- default:
- {
- DBG1(DBG_IKE, "received %N, sending %N",
- eap_code_names, code, eap_code_names, EAP_FAILURE);
- *out = eap_payload_create_code(EAP_FAILURE,
- in->get_identifier(in));
- return FAILED;
+ return NEED_MORE;
}
+ return FAILED;
}
- }
- case EAP_PEER:
- {
- switch (code)
+ case EAP_SUCCESS:
{
- case EAP_REQUEST:
+ eap_type_t type;
+ u_int32_t vendor;
+ auth_cfg_t *cfg;
+
+ if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
{
- return process_peer(this, in, out);
+ this->msk = chunk_clone(this->msk);
}
- case EAP_SUCCESS:
+ type = this->method->get_type(this->method, &vendor);
+ if (vendor)
{
- if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
- {
- this->msk = chunk_clone(this->msk);
- }
- return SUCCESS;
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, "
+ "%sMSK established", type, vendor,
+ this->msk.ptr ? "" : "no ");
}
- case EAP_FAILURE:
- default:
+ else
{
- DBG1(DBG_IKE, "received %N, EAP authentication failed",
- eap_code_names, code);
- return FAILED;
+ DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established",
+ eap_type_names, type, this->msk.ptr ? "" : "no ");
}
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+ if (vendor)
+ {
+ cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+ }
+ this->eap_complete = TRUE;
+ return NEED_MORE;
+ }
+ case EAP_FAILURE:
+ default:
+ {
+ DBG1(DBG_IKE, "received %N, EAP authentication failed",
+ eap_code_names, eap_payload->get_code(eap_payload));
+ return FAILED;
}
- }
- default:
- {
- return FAILED;
}
}
+ return FAILED;
}
/**
- * Implementation of authenticator_t.is_mutual.
+ * Implementation of authenticator_t.build for a client
*/
-static bool is_mutual(private_eap_authenticator_t *this)
+static status_t build_client(private_eap_authenticator_t *this,
+ message_t *message)
{
- if (this->method)
+ if (this->eap_payload)
{
- return this->method->is_mutual(this->method);
+ message->add_payload(message, (payload_t*)this->eap_payload);
+ this->eap_payload = NULL;
+ return NEED_MORE;
}
- return FALSE;
+ if (this->eap_complete)
+ {
+ build_auth(this, message, this->received_nonce, this->sent_init);
+ return NEED_MORE;
+ }
+ return NEED_MORE;
}
/**
@@ -500,6 +584,8 @@ static bool is_mutual(private_eap_authenticator_t *this)
static void destroy(private_eap_authenticator_t *this)
{
DESTROY_IF(this->method);
+ DESTROY_IF(this->eap_payload);
+ DESTROY_IF(this->eap_identity);
chunk_free(&this->msk);
free(this);
}
@@ -507,46 +593,56 @@ static void destroy(private_eap_authenticator_t *this)
/*
* Described in header.
*/
-eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
+eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init)
{
- peer_cfg_t *config;
- auth_info_t *auth;
- identification_t *id;
private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
- /* public functions */
- this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
- this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
- this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
-
- this->public.is_mutual = (bool(*)(eap_authenticator_t*))is_mutual;
- this->public.initiate = (status_t(*)(eap_authenticator_t*,eap_type_t,u_int32_t,eap_payload_t**))initiate;
- this->public.process = (status_t(*)(eap_authenticator_t*,eap_payload_t*,eap_payload_t**))process;
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build_client;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_client;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
- /* private data */
this->ike_sa = ike_sa;
- this->role = EAP_PEER;
+ this->received_init = received_init;
+ this->received_nonce = received_nonce;
+ this->sent_init = sent_init;
+ this->sent_nonce = sent_nonce;
+ this->msk = chunk_empty;
this->method = NULL;
+ this->eap_payload = NULL;
+ this->eap_complete = FALSE;
+ this->auth_complete = FALSE;
+ this->eap_identity = NULL;
+
+ return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init)
+{
+ private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
+
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))build_server;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_server;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+
+ this->ike_sa = ike_sa;
+ this->received_init = received_init;
+ this->received_nonce = received_nonce;
+ this->sent_init = sent_init;
+ this->sent_nonce = sent_nonce;
this->msk = chunk_empty;
- this->do_eap_identity = FALSE;
- this->type = 0;
- this->vendor = 0;
+ this->method = NULL;
+ this->eap_payload = NULL;
+ this->eap_complete = FALSE;
+ this->auth_complete = FALSE;
+ this->eap_identity = NULL;
- config = ike_sa->get_peer_cfg(ike_sa);
- if (config)
- {
- auth = config->get_auth(config);
- if (auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id))
- {
- if (id->get_type(id) == ID_ANY)
- { /* %any as configured EAP identity runs EAP-Identity first */
- this->do_eap_identity = TRUE;
- }
- else
- {
- ike_sa->set_eap_identity(ike_sa, id->clone(id));
- }
- }
- }
return &this->public;
}
+
diff --git a/src/charon/sa/authenticators/eap_authenticator.h b/src/charon/sa/authenticators/eap_authenticator.h
index 3ee6839fa..b90a6f4df 100644
--- a/src/charon/sa/authenticators/eap_authenticator.h
+++ b/src/charon/sa/authenticators/eap_authenticator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: eap_authenticator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -26,21 +24,13 @@
typedef struct eap_authenticator_t eap_authenticator_t;
#include <sa/authenticators/authenticator.h>
-#include <encoding/payloads/eap_payload.h>
/**
- * Implementation of the authenticator_t interface using AUTH_CLASS_EAP.
+ * Implementation of authenticator_t using EAP authentication.
*
* Authentication using EAP involves the most complex authenticator. It stays
* alive over multiple ike_auth transactions and handles multiple EAP
* messages.
- * EAP authentication must be clearly distinguished between using
- * mutual EAP methods and using methods not providing server authentication.
- * If no mutual authentication is used, the server must prove it's identity
- * by traditional AUTH methods (RSA, psk). Only when the EAP method is mutual,
- * the client should accept an EAP-only authentication.
- * RFC4306 does always use traditional authentiction, EAP only authentication
- * is described in the internet draft draft-eronen-ipsec-ikev2-eap-auth-05.txt.
*
* @verbatim
ike_sa_init
@@ -49,12 +39,12 @@ typedef struct eap_authenticator_t eap_authenticator_t;
followed by multiple ike_auth:
+--------+ +--------+
- | EAP | ID, SA, TS, N(EAP_ONLY) | EAP |
+ | EAP | IDi, [IDr,] SA, TS | EAP |
| client | ---------------------------> | server |
- | | ID, [AUTH,] EAP | | AUTH payload is
- | | <--------------------------- | | only included if
- | | EAP | | authentication
- | | ---------------------------> | | is not mutual.
+ | | ID, AUTH, EAP | |
+ | | <--------------------------- | |
+ | | EAP | |
+ | | ---------------------------> | |
| | EAP | |
| | <--------------------------- | |
| | EAP | |
@@ -74,74 +64,35 @@ struct eap_authenticator_t {
/**
* Implemented authenticator_t interface.
*/
- authenticator_t authenticator_interface;
-
- /**
- * Check if the EAP method was/is mutual and secure.
- *
- * RFC4306 proposes to authenticate the EAP responder (server) by standard
- * IKEv2 methods (RSA, psk). Not all, but some EAP methods
- * provide mutual authentication, which would result in a redundant
- * authentication. If the client supports EAP_ONLY_AUTHENTICATION, and
- * the the server provides mutual authentication, authentication using
- * RSA/PSK may be omitted. If the server did not include a traditional
- * AUTH payload, the client must verify that the server initiated mutual
- * EAP authentication before it can trust the server.
- *
- * @return TRUE, if no AUTH payload required, FALSE otherwise
- */
- bool (*is_mutual) (eap_authenticator_t* this);
-
- /**
- * Initiate the EAP exchange.
- *
- * The server initiates EAP exchanges, so the client never calls
- * this method. If initiate() returns NEED_MORE, the EAP authentication
- * process started. In any case, a payload is created in "out".
- *
- * @param type EAP method to use to authenticate client
- * @param vendor EAP vendor identifier, if type is vendor specific, or 0
- * @param out created initiaal EAP message to send
- * @return
- * - FAILED, if initiation failed
- * - NEED_MORE, if more EAP exchanges reqired
- */
- status_t (*initiate) (eap_authenticator_t* this, eap_type_t type,
- u_int32_t vendor, eap_payload_t **out);
-
- /**
- * Process an EAP message.
- *
- * After receiving an EAP message "in", the peer/server processes
- * the payload and creates a reply/subsequent request.
- * The server side always returns NEED_MORE if another EAP message
- * is expected from the client, SUCCESS if EAP exchange completed and
- * "out" is EAP_SUCCES, or FAILED if the EAP exchange failed with
- * a EAP_FAILURE payload in "out". Anyway, a payload in "out" is always
- * created.
- * The peer (client) side only creates a "out" payload if result is
- * NEED_MORE, a SUCCESS/FAILED is returned whenever a
- * EAP_SUCCESS/EAP_FAILURE message is received in "in".
- * If a SUCCESS is returned (on any side), the EAP authentication was
- * successful and the AUTH payload can be exchanged.
- *
- * @param in received EAP message
- * @param out created EAP message to send
- * @return
- * - FAILED, if authentication/EAP exchange failed
- * - SUCCESS, if authentication completed
- * - NEED_MORE, if more EAP exchanges reqired
- */
- status_t (*process) (eap_authenticator_t* this,
- eap_payload_t *in, eap_payload_t **out);
+ authenticator_t authenticator;
};
/**
- * Creates an authenticator for AUTH_CLASS_EAP.
+ * Create an authenticator to authenticate against an EAP server.
*
- * @param ike_sa associated ike_sa
- * @return eap_authenticator_t object
+ * @param ike_sa associated ike_sa
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return EAP authenticator
+ */
+eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init);
+
+/**
+ * Create an authenticator to authenticate EAP clients.
+ *
+ * @param ike_sa associated ike_sa
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return EAP authenticator
*/
-eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa);
+eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_nonce,
+ chunk_t received_init, chunk_t sent_init);
#endif /** EAP_AUTHENTICATOR_H_ @}*/
diff --git a/src/charon/sa/authenticators/psk_authenticator.c b/src/charon/sa/authenticators/psk_authenticator.c
index ae5a66479..742b67789 100644
--- a/src/charon/sa/authenticators/psk_authenticator.c
+++ b/src/charon/sa/authenticators/psk_authenticator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,17 +12,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: psk_authenticator.c 4495 2008-10-28 16:07:06Z martin $
*/
-#include <string.h>
-
#include "psk_authenticator.h"
#include <daemon.h>
-#include <credentials/auth_info.h>
-
+#include <encoding/payloads/auth_payload.h>
typedef struct private_psk_authenticator_t private_psk_authenticator_t;
@@ -40,22 +35,74 @@ struct private_psk_authenticator_t {
* Assigned IKE_SA
*/
ike_sa_t *ike_sa;
+
+ /**
+ * nonce to include in AUTH calculation
+ */
+ chunk_t nonce;
+
+ /**
+ * IKE_SA_INIT message data to include in AUTH calculation
+ */
+ chunk_t ike_sa_init;
};
+/*
+ * Implementation of authenticator_t.build for builder
+ */
+static status_t build(private_psk_authenticator_t *this, message_t *message)
+{
+ identification_t *my_id, *other_id;
+ auth_payload_t *auth_payload;
+ shared_key_t *key;
+ chunk_t auth_data;
+ keymat_t *keymat;
+
+ keymat = this->ike_sa->get_keymat(this->ike_sa);
+ my_id = this->ike_sa->get_my_id(this->ike_sa);
+ other_id = this->ike_sa->get_other_id(this->ike_sa);
+ DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
+ my_id, auth_method_names, AUTH_PSK);
+ key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
+ my_id, other_id);
+ if (key == NULL)
+ {
+ DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
+ return NOT_FOUND;
+ }
+ auth_data = keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init,
+ this->nonce, key->get_key(key), my_id);
+ key->destroy(key);
+ DBG2(DBG_IKE, "successfully created shared key MAC");
+ auth_payload = auth_payload_create();
+ auth_payload->set_auth_method(auth_payload, AUTH_PSK);
+ auth_payload->set_data(auth_payload, auth_data);
+ chunk_free(&auth_data);
+ message->add_payload(message, (payload_t*)auth_payload);
+
+ return SUCCESS;
+}
+
/**
- * Implementation of authenticator_t.verify.
+ * Implementation of authenticator_t.process for verifier
*/
-static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload)
+static status_t process(private_psk_authenticator_t *this, message_t *message)
{
chunk_t auth_data, recv_auth_data;
identification_t *my_id, *other_id;
+ auth_payload_t *auth_payload;
+ auth_cfg_t *auth;
shared_key_t *key;
enumerator_t *enumerator;
bool authenticated = FALSE;
int keys_found = 0;
keymat_t *keymat;
+ auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+ if (!auth_payload)
+ {
+ return FAILED;
+ }
keymat = this->ike_sa->get_keymat(this->ike_sa);
recv_auth_data = auth_payload->get_data(auth_payload);
my_id = this->ike_sa->get_my_id(this->ike_sa);
@@ -66,11 +113,11 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
{
keys_found++;
- auth_data = keymat->get_psk_sig(keymat, TRUE, ike_sa_init, my_nonce,
- key->get_key(key), other_id);
+ auth_data = keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init,
+ this->nonce, key->get_key(key), other_id);
if (auth_data.len && chunk_equals(auth_data, recv_auth_data))
{
- DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+ DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
other_id, auth_method_names, AUTH_PSK);
authenticated = TRUE;
}
@@ -82,49 +129,26 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
{
if (keys_found == 0)
{
- DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
+ DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
return NOT_FOUND;
}
- DBG1(DBG_IKE, "tried %d shared key%s for '%D' - '%D', but MAC mismatched",
+ DBG1(DBG_IKE, "tried %d shared key%s for '%Y' - '%Y', but MAC mismatched",
keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
return FAILED;
}
+
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
return SUCCESS;
}
/**
- * Implementation of authenticator_t.build.
+ * Implementation of authenticator_t.process for builder
+ * Implementation of authenticator_t.build for verifier
*/
-static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t other_nonce, auth_payload_t **auth_payload)
+static status_t return_failed()
{
- identification_t *my_id, *other_id;
- shared_key_t *key;
- chunk_t auth_data;
- keymat_t *keymat;
-
- keymat = this->ike_sa->get_keymat(this->ike_sa);
- my_id = this->ike_sa->get_my_id(this->ike_sa);
- other_id = this->ike_sa->get_other_id(this->ike_sa);
- DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
- my_id, auth_method_names, AUTH_PSK);
- key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
- my_id, other_id);
- if (key == NULL)
- {
- DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
- return NOT_FOUND;
- }
- auth_data = keymat->get_psk_sig(keymat, FALSE, ike_sa_init, other_nonce,
- key->get_key(key), my_id);
- key->destroy(key);
- DBG2(DBG_IKE, "successfully created shared key MAC");
- *auth_payload = auth_payload_create();
- (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
- (*auth_payload)->set_data(*auth_payload, auth_data);
-
- chunk_free(&auth_data);
- return SUCCESS;
+ return FAILED;
}
/**
@@ -138,17 +162,38 @@ static void destroy(private_psk_authenticator_t *this)
/*
* Described in header.
*/
-psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa)
+psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_init)
{
private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t);
- /* public functions */
- this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
- this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
- this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
- /* private data */
this->ike_sa = ike_sa;
+ this->ike_sa_init = sent_init;
+ this->nonce = received_nonce;
return &this->public;
}
+
+/*
+ * Described in header.
+ */
+psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t sent_nonce, chunk_t received_init)
+{
+ private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t);
+
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))return_failed;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+
+ this->ike_sa = ike_sa;
+ this->ike_sa_init = received_init;
+ this->nonce = sent_nonce;
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/authenticators/psk_authenticator.h b/src/charon/sa/authenticators/psk_authenticator.h
index df65076a4..5bb743d93 100644
--- a/src/charon/sa/authenticators/psk_authenticator.h
+++ b/src/charon/sa/authenticators/psk_authenticator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: psk_authenticator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -28,22 +26,36 @@ typedef struct psk_authenticator_t psk_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
- * Implementation of the authenticator_t interface using AUTH_PSK.
+ * Implementation of authenticator_t using pre-shared keys.
*/
struct psk_authenticator_t {
/**
* Implemented authenticator_t interface.
*/
- authenticator_t authenticator_interface;
+ authenticator_t authenticator;
};
/**
- * Creates an authenticator for AUTH_PSK.
+ * Create an authenticator to build PSK signatures.
*
- * @param ike_sa associated ike_sa
- * @return psk_authenticator_t object
+ * @param ike_sa associated ike_sa
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return PSK authenticator
+ */
+psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_init);
+
+/**
+ * Create an authenticator to verify PSK signatures.
+ *
+ * @param ike_sa associated ike_sa
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @return PSK authenticator
*/
-psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa);
+psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t sent_nonce, chunk_t received_init);
#endif /** PSK_AUTHENTICATOR_H_ @}*/
diff --git a/src/charon/sa/authenticators/pubkey_authenticator.c b/src/charon/sa/authenticators/pubkey_authenticator.c
index c16f3b888..44cabfb94 100644
--- a/src/charon/sa/authenticators/pubkey_authenticator.c
+++ b/src/charon/sa/authenticators/pubkey_authenticator.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,17 +13,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pubkey_authenticator.c 4495 2008-10-28 16:07:06Z martin $
*/
-#include <string.h>
-
#include "pubkey_authenticator.h"
#include <daemon.h>
-#include <credentials/auth_info.h>
-
+#include <encoding/payloads/auth_payload.h>
typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
@@ -41,95 +36,40 @@ struct private_pubkey_authenticator_t {
* Assigned IKE_SA
*/
ike_sa_t *ike_sa;
-};
-
-/**
- * Implementation of authenticator_t.verify.
- */
-static status_t verify(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t my_nonce, auth_payload_t *auth_payload)
-{
- public_key_t *public;
- auth_method_t auth_method;
- chunk_t auth_data, octets;
- identification_t *id;
- auth_info_t *auth, *current_auth;
- enumerator_t *enumerator;
- key_type_t key_type = KEY_ECDSA;
- signature_scheme_t scheme;
- status_t status = FAILED;
- keymat_t *keymat;
- id = this->ike_sa->get_other_id(this->ike_sa);
- auth_method = auth_payload->get_auth_method(auth_payload);
- switch (auth_method)
- {
- case AUTH_RSA:
- /* We are currently fixed to SHA1 hashes.
- * TODO: allow other hash algorithms and note it in "auth" */
- key_type = KEY_RSA;
- scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- break;
- case AUTH_ECDSA_256:
- scheme = SIGN_ECDSA_256;
- break;
- case AUTH_ECDSA_384:
- scheme = SIGN_ECDSA_384;
- break;
- case AUTH_ECDSA_521:
- scheme = SIGN_ECDSA_521;
- break;
- default:
- return INVALID_ARG;
- }
- auth_data = auth_payload->get_data(auth_payload);
- keymat = this->ike_sa->get_keymat(this->ike_sa);
- octets = keymat->get_auth_octets(keymat, TRUE, ike_sa_init, my_nonce, id);
- auth = this->ike_sa->get_other_auth(this->ike_sa);
- enumerator = charon->credentials->create_public_enumerator(
- charon->credentials, key_type, id, auth);
- while (enumerator->enumerate(enumerator, &public, &current_auth))
- {
- if (public->verify(public, scheme, octets, auth_data))
- {
- DBG1(DBG_IKE, "authentication of '%D' with %N successful",
- id, auth_method_names, auth_method);
- status = SUCCESS;
- auth->merge(auth, current_auth);
- break;
- }
- else
- {
- DBG1(DBG_IKE, "signature validation failed, looking for another key");
- }
- }
- enumerator->destroy(enumerator);
- chunk_free(&octets);
- return status;
-}
+ /**
+ * nonce to include in AUTH calculation
+ */
+ chunk_t nonce;
+
+ /**
+ * IKE_SA_INIT message data to include in AUTH calculation
+ */
+ chunk_t ike_sa_init;
+};
/**
- * Implementation of authenticator_t.build.
+ * Implementation of authenticator_t.build for builder
*/
-static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
- chunk_t other_nonce, auth_payload_t **auth_payload)
+static status_t build(private_pubkey_authenticator_t *this, message_t *message)
{
chunk_t octets, auth_data;
status_t status = FAILED;
private_key_t *private;
identification_t *id;
- auth_info_t *auth;
+ auth_cfg_t *auth;
+ auth_payload_t *auth_payload;
auth_method_t auth_method;
signature_scheme_t scheme;
keymat_t *keymat;
id = this->ike_sa->get_my_id(this->ike_sa);
- auth = this->ike_sa->get_my_auth(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
private = charon->credentials->get_private(charon->credentials, KEY_ANY,
id, auth);
if (private == NULL)
{
- DBG1(DBG_IKE, "no private key found for '%D'", id);
+ DBG1(DBG_IKE, "no private key found for '%Y'", id);
return NOT_FOUND;
}
@@ -169,18 +109,18 @@ static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
return status;
}
keymat = this->ike_sa->get_keymat(this->ike_sa);
- octets = keymat->get_auth_octets(keymat, FALSE, ike_sa_init, other_nonce, id);
-
+ octets = keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
+ this->nonce, id);
if (private->sign(private, scheme, octets, &auth_data))
{
- auth_payload_t *payload = auth_payload_create();
- payload->set_auth_method(payload, auth_method);
- payload->set_data(payload, auth_data);
- *auth_payload = payload;
+ 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 '%D' (myself) with %N %s", id,
+ DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id,
auth_method_names, auth_method,
(status == SUCCESS)? "successful":"failed");
chunk_free(&octets);
@@ -190,6 +130,93 @@ static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
}
/**
+ * Implementation of authenticator_t.process for verifier
+ */
+static status_t process(private_pubkey_authenticator_t *this, message_t *message)
+{
+ public_key_t *public;
+ auth_method_t auth_method;
+ auth_payload_t *auth_payload;
+ chunk_t auth_data, octets;
+ identification_t *id;
+ auth_cfg_t *auth, *current_auth;
+ enumerator_t *enumerator;
+ key_type_t key_type = KEY_ECDSA;
+ signature_scheme_t scheme;
+ status_t status = NOT_FOUND;
+ keymat_t *keymat;
+
+ auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+ if (!auth_payload)
+ {
+ return FAILED;
+ }
+ auth_method = auth_payload->get_auth_method(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;
+ case AUTH_ECDSA_256:
+ scheme = SIGN_ECDSA_256;
+ break;
+ case AUTH_ECDSA_384:
+ scheme = SIGN_ECDSA_384;
+ break;
+ case AUTH_ECDSA_521:
+ scheme = SIGN_ECDSA_521;
+ break;
+ default:
+ return INVALID_ARG;
+ }
+ auth_data = auth_payload->get_data(auth_payload);
+ id = this->ike_sa->get_other_id(this->ike_sa);
+ keymat = this->ike_sa->get_keymat(this->ike_sa);
+ octets = keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
+ this->nonce, id);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ enumerator = charon->credentials->create_public_enumerator(
+ charon->credentials, key_type, id, auth);
+ while (enumerator->enumerate(enumerator, &public, &current_auth))
+ {
+ if (public->verify(public, scheme, octets, auth_data))
+ {
+ DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
+ id, auth_method_names, auth_method);
+ status = SUCCESS;
+ auth->merge(auth, current_auth, FALSE);
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ break;
+ }
+ else
+ {
+ status = FAILED;
+ DBG1(DBG_IKE, "signature validation failed, looking for another key");
+ }
+ }
+ enumerator->destroy(enumerator);
+ chunk_free(&octets);
+ if (status == NOT_FOUND)
+ {
+ DBG1(DBG_IKE, "no trusted %N public key found for '%Y'",
+ key_type_names, key_type, id);
+ }
+ return status;
+}
+
+/**
+ * Implementation of authenticator_t.process for builder
+ * Implementation of authenticator_t.build for verifier
+ */
+static status_t return_failed()
+{
+ return FAILED;
+}
+
+/**
* Implementation of authenticator_t.destroy.
*/
static void destroy(private_pubkey_authenticator_t *this)
@@ -200,17 +227,37 @@ static void destroy(private_pubkey_authenticator_t *this)
/*
* Described in header.
*/
-pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa)
+pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_init)
+{
+ private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
+
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+
+ this->ike_sa = ike_sa;
+ this->ike_sa_init = sent_init;
+ this->nonce = received_nonce;
+
+ return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t sent_nonce, chunk_t received_init)
{
private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
- /* public functions */
- this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
- this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
- this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
+ this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+ this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process;
+ this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
- /* private data */
this->ike_sa = ike_sa;
+ this->ike_sa_init = received_init;
+ this->nonce = sent_nonce;
return &this->public;
}
diff --git a/src/charon/sa/authenticators/pubkey_authenticator.h b/src/charon/sa/authenticators/pubkey_authenticator.h
index d2189fa97..e67f020ff 100644
--- a/src/charon/sa/authenticators/pubkey_authenticator.h
+++ b/src/charon/sa/authenticators/pubkey_authenticator.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pubkey_authenticator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -29,22 +27,36 @@ typedef struct pubkey_authenticator_t pubkey_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
- * Implementation of the authenticator_t interface using AUTH_PUBKEY.
+ * Implementation of authenticator_t using public key authenitcation.
*/
struct pubkey_authenticator_t {
/**
* Implemented authenticator_t interface.
*/
- authenticator_t authenticator_interface;
+ authenticator_t authenticator;
};
/**
- * Creates an authenticator for AUTH_PUBKEY.
+ * Create an authenticator to build public key signatures.
*
- * @param ike_sa associated ike_sa
- * @return pubkey_authenticator_t object
+ * @param ike_sa associated ike_sa
+ * @param received_nonce nonce received in IKE_SA_INIT
+ * @param sent_init sent IKE_SA_INIT message data
+ * @return public key authenticator
+ */
+pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa,
+ chunk_t received_nonce, chunk_t sent_init);
+
+/**
+ * Create an authenticator to verify public key signatures.
+ *
+ * @param ike_sa associated ike_sa
+ * @param sent_nonce nonce sent in IKE_SA_INIT
+ * @param received_init received IKE_SA_INIT message data
+ * @return public key authenticator
*/
-pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa);
+pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
+ chunk_t sent_nonce, chunk_t received_init);
#endif /** PUBKEY_AUTHENTICATOR_H_ @}*/
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 022b9149a..9202e972e 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_sa.c 4677 2008-11-19 15:31:27Z martin $
*/
#define _GNU_SOURCE
@@ -412,26 +410,11 @@ static u_int32_t get_lifetime(private_child_sa_t *this, bool hard)
*/
static u_int32_t alloc_spi(private_child_sa_t *this, protocol_id_t protocol)
{
- switch (protocol)
- {
- case PROTO_AH:
- if (charon->kernel_interface->get_spi(charon->kernel_interface,
- this->other_addr, this->my_addr, PROTO_AH,
- this->reqid, &this->my_spi) == SUCCESS)
- {
- return this->my_spi;
- }
- break;
- case PROTO_ESP:
- if (charon->kernel_interface->get_spi(charon->kernel_interface,
- this->other_addr, this->my_addr, PROTO_ESP,
+ if (charon->kernel_interface->get_spi(charon->kernel_interface,
+ this->other_addr, this->my_addr, protocol,
this->reqid, &this->my_spi) == SUCCESS)
- {
- return this->my_spi;
- }
- break;
- default:
- break;
+ {
+ return this->my_spi;
}
return 0;
}
@@ -504,8 +487,14 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
this->mode, this->ipcomp, cpi, this->encap, update);
now = time(NULL);
- this->rekey_time = now + soft;
- this->expire_time = now + hard;
+ if (soft)
+ {
+ this->rekey_time = now + soft;
+ }
+ if (hard)
+ {
+ this->expire_time = now + hard;
+ }
return status;
}
@@ -724,14 +713,14 @@ static void destroy(private_child_sa_t *this)
if (this->my_spi)
{
charon->kernel_interface->del_sa(charon->kernel_interface,
- this->my_addr, this->my_spi, this->protocol,
- this->my_cpi);
+ this->other_addr, this->my_addr, this->my_spi,
+ this->protocol, this->my_cpi);
}
if (this->other_spi)
{
charon->kernel_interface->del_sa(charon->kernel_interface,
- this->other_addr, this->other_spi, this->protocol,
- this->other_cpi);
+ this->my_addr, this->other_addr, this->other_spi,
+ this->protocol, this->other_cpi);
}
if (this->config->install_policy(this->config))
@@ -816,6 +805,8 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->protocol = PROTO_NONE;
this->mode = MODE_TUNNEL;
this->proposal = NULL;
+ this->rekey_time = 0;
+ this->expire_time = 0;
this->config = config;
config->get_ref(config);
diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h
index 70169f515..ec9b36dab 100644
--- a/src/charon/sa/child_sa.h
+++ b/src/charon/sa/child_sa.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_sa.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/connect_manager.c b/src/charon/sa/connect_manager.c
index b9141ffc1..a1b037de4 100644
--- a/src/charon/sa/connect_manager.c
+++ b/src/charon/sa/connect_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: connect_manager.c 4579 2008-11-05 11:29:56Z martin $
*/
#include "connect_manager.h"
@@ -734,11 +732,11 @@ static void build_pairs(check_list_t *checklist)
*/
static status_t process_payloads(message_t *message, check_t *check)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) != NOTIFY)
{
@@ -796,7 +794,7 @@ static status_t process_payloads(message_t *message, check_t *check)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (!check->connect_id.ptr || !check->endpoint || !check->auth.ptr)
{
@@ -904,7 +902,7 @@ static void update_checklist_state(private_connect_manager_t *this, check_list_t
callback_data_t *data = callback_data_create(this, checklist->connect_id);
job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiator_finish, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job(charon->scheduler, job, ME_WAIT_TO_FINISH);
+ charon->scheduler->schedule_job_ms(charon->scheduler, job, ME_WAIT_TO_FINISH);
checklist->is_finishing = TRUE;
}
@@ -1002,7 +1000,7 @@ static void queue_retransmission(private_connect_manager_t *this, check_list_t *
}
DBG2(DBG_IKE, "scheduling retransmission %d of pair '%d' in %dms", retransmission, pair->id, rto);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, rto);
+ charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)job, rto);
}
/**
@@ -1139,7 +1137,7 @@ static void schedule_checks(private_connect_manager_t *this, check_list_t *check
{
callback_data_t *data = callback_data_create(this, checklist->connect_id);
checklist->sender = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job(charon->scheduler, checklist->sender, time);
+ charon->scheduler->schedule_job_ms(charon->scheduler, checklist->sender, time);
}
/**
@@ -1196,8 +1194,8 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
}
else
{
- DBG1(DBG_IKE, "there is no mediated connection waiting between '%D' "
- "and '%D'", checklist->initiator.id, checklist->responder.id);
+ DBG1(DBG_IKE, "there is no mediated connection waiting between '%Y' "
+ "and '%Y'", checklist->initiator.id, checklist->responder.id);
}
}
}
@@ -1396,7 +1394,7 @@ static bool check_and_register(private_connect_manager_t *this,
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
{
- DBG2(DBG_IKE, "registered waiting mediated connection with '%D'", peer_id);
+ DBG2(DBG_IKE, "registered waiting mediated connection with '%Y'", peer_id);
initiated = initiated_create(id, peer_id);
this->initiated->insert_last(this->initiated, initiated);
already_there = FALSE;
@@ -1425,7 +1423,7 @@ static void check_and_initiate(private_connect_manager_t *this, ike_sa_id_t *med
if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS)
{
- DBG2(DBG_IKE, "no waiting mediated connections with '%D'", peer_id);
+ DBG2(DBG_IKE, "no waiting mediated connections with '%Y'", peer_id);
this->mutex->unlock(this->mutex);
return;
}
diff --git a/src/charon/sa/connect_manager.h b/src/charon/sa/connect_manager.h
index c16f87352..b5abc853c 100644
--- a/src/charon/sa/connect_manager.h
+++ b/src/charon/sa/connect_manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: connect_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index bebd74160..6b7fa3582 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa.c 4945 2009-03-16 14:23:36Z martin $
*/
#include <sys/time.h>
@@ -57,10 +55,6 @@
#include <processing/jobs/initiate_mediation_job.h>
#endif
-#ifndef RESOLV_CONF
-#define RESOLV_CONF "/etc/resolv.conf"
-#endif
-
ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING,
"CREATED",
"CONNECTING",
@@ -72,17 +66,18 @@ ENUM(ike_sa_state_names, IKE_CREATED, IKE_DESTROYING,
);
typedef struct private_ike_sa_t private_ike_sa_t;
+typedef struct attribute_entry_t attribute_entry_t;
/**
* Private data of an ike_sa_t object.
*/
struct private_ike_sa_t {
-
+
/**
* Public members
*/
ike_sa_t public;
-
+
/**
* Identifier for the current IKE_SA.
*/
@@ -96,7 +91,7 @@ struct private_ike_sa_t {
/**
* Current state of the IKE_SA
*/
- ike_sa_state_t state;
+ ike_sa_state_t state;
/**
* IKE configuration used to set up this IKE_SA
@@ -109,14 +104,14 @@ struct private_ike_sa_t {
peer_cfg_t *peer_cfg;
/**
- * associated authentication/authorization info for local peer
+ * currently used authentication ruleset, local (as auth_cfg_t)
*/
- auth_info_t *my_auth;
+ auth_cfg_t *my_auth;
/**
- * associated authentication/authorization info for remote peer
+ * currently used authentication constraints, remote (as auth_cfg_t)
*/
- auth_info_t *other_auth;
+ auth_cfg_t *other_auth;
/**
* Selected IKE proposal
@@ -179,7 +174,7 @@ struct private_ike_sa_t {
* set of condition flags currently enabled for this IKE_SA
*/
ike_condition_t conditions;
-
+
/**
* Linked List containing the child sa's of the current IKE_SA.
*/
@@ -201,9 +196,9 @@ struct private_ike_sa_t {
host_t *other_virtual_ip;
/**
- * List of DNS servers installed by us
+ * List of configuration attributes (attribute_entry_t)
*/
- linked_list_t *dns_servers;
+ linked_list_t *attributes;
/**
* list of peers additional addresses, transmitted via MOBIKE
@@ -219,7 +214,7 @@ struct private_ike_sa_t {
* number pending UPDATE_SA_ADDRESS (MOBIKE)
*/
u_int32_t pending_updates;
-
+
/**
* NAT keep alive interval
*/
@@ -234,12 +229,12 @@ struct private_ike_sa_t {
* how many times we have retried so far (keyingtries)
*/
u_int32_t keyingtry;
-
+
/**
* local host address to be used for IKE, set via MIGRATE kernel message
*/
host_t *local_host;
-
+
/**
* remote host address to be used for IKE, set via MIGRATE kernel message
*/
@@ -247,6 +242,18 @@ struct private_ike_sa_t {
};
/**
+ * Entry to maintain install configuration attributes during IKE_SA lifetime
+ */
+struct attribute_entry_t {
+ /** handler used to install this attribute */
+ attribute_handler_t *handler;
+ /** attribute type */
+ configuration_attribute_type_t type;
+ /** attribute data */
+ chunk_t data;
+};
+
+/**
* get the time of the latest traffic processed by the kernel
*/
static time_t get_use_time(private_ike_sa_t* this, bool inbound)
@@ -355,40 +362,23 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
DESTROY_IF(this->peer_cfg);
peer_cfg->get_ref(peer_cfg);
this->peer_cfg = peer_cfg;
-
+
if (this->ike_cfg == NULL)
{
this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
this->ike_cfg->get_ref(this->ike_cfg);
}
- /* apply IDs if they are not already set */
- if (this->my_id->contains_wildcards(this->my_id))
- {
- DESTROY_IF(this->my_id);
- this->my_id = this->peer_cfg->get_my_id(this->peer_cfg);
- this->my_id = this->my_id->clone(this->my_id);
- }
- if (this->other_id->contains_wildcards(this->other_id))
- {
- DESTROY_IF(this->other_id);
- this->other_id = this->peer_cfg->get_other_id(this->peer_cfg);
- this->other_id = this->other_id->clone(this->other_id);
- }
-}
-
-/**
- * Implementation of ike_sa_t.get_my_auth.
- */
-static auth_info_t* get_my_auth(private_ike_sa_t *this)
-{
- return this->my_auth;
}
/**
- * Implementation of ike_sa_t.get_other_auth.
+ * Implementation of ike_sa_t.get_auth_cfg
*/
-static auth_info_t* get_other_auth(private_ike_sa_t *this)
+static auth_cfg_t* get_auth_cfg(private_ike_sa_t *this, bool local)
{
+ if (local)
+ {
+ return this->my_auth;
+ }
return this->other_auth;
}
@@ -460,7 +450,7 @@ static void send_keepalive(private_ike_sa_t *this)
}
job = send_keepalive_job_create(this->ike_sa_id);
charon->scheduler->schedule_job(charon->scheduler, (job_t*)job,
- (this->keepalive_interval - diff) * 1000);
+ this->keepalive_interval - diff);
}
/**
@@ -559,7 +549,7 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
*/
static status_t send_dpd(private_ike_sa_t *this)
{
- send_dpd_job_t *job;
+ job_t *job;
time_t diff, delay;
delay = this->peer_cfg->get_dpd(this->peer_cfg);
@@ -608,9 +598,8 @@ static status_t send_dpd(private_ike_sa_t *this)
}
}
/* recheck in "interval" seconds */
- job = send_dpd_job_create(this->ike_sa_id);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job,
- (delay - diff) * 1000);
+ job = (job_t*)send_dpd_job_create(this->ike_sa_id);
+ charon->scheduler->schedule_job(charon->scheduler, job, delay - diff);
return SUCCESS;
}
@@ -653,8 +642,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
{
this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
- charon->scheduler->schedule_job(charon->scheduler,
- job, t * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, job, t);
DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
}
t = this->peer_cfg->get_reauth_time(this->peer_cfg);
@@ -663,8 +651,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
{
this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler,
- job, t * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, job, t);
DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
}
t = this->peer_cfg->get_over_time(this->peer_cfg);
@@ -686,8 +673,7 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
this->stats[STAT_DELETE] += t;
t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job,
- t * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, job, t);
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
@@ -1117,9 +1103,11 @@ static void resolve_hosts(private_ike_sa_t *this)
}
/**
- * Initiates a CHILD_SA using the appropriate reqid
+ * Implementation of ike_sa_t.initiate
*/
-static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_cfg, u_int32_t reqid)
+static status_t initiate(private_ike_sa_t *this,
+ child_cfg_t *child_cfg, u_int32_t reqid,
+ traffic_selector_t *tsi, traffic_selector_t *tsr)
{
task_t *task;
@@ -1181,7 +1169,7 @@ static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_c
#endif /* ME */
{
/* normal IKE_SA with CHILD_SA */
- task = (task_t*)child_create_create(&this->public, child_cfg);
+ task = (task_t*)child_create_create(&this->public, child_cfg, tsi, tsr);
child_cfg->destroy(child_cfg);
if (reqid)
{
@@ -1205,176 +1193,6 @@ static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_c
}
/**
- * Implementation of ike_sa_t.initiate.
- */
-static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
-{
- return initiate_with_reqid(this, child_cfg, 0);
-}
-
-/**
- * Implementation of ike_sa_t.acquire.
- */
-static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
-{
- child_cfg_t *child_cfg;
- iterator_t *iterator;
- child_sa_t *current, *child_sa = NULL;
-
- switch (this->state)
- {
- case IKE_DELETING:
- DBG1(DBG_IKE, "acquiring CHILD_SA {reqid %d} failed: "
- "IKE_SA is deleting", reqid);
- return FAILED;
- case IKE_PASSIVE:
- /* do not process acquires if passive */
- return FAILED;
- default:
- break;
- }
-
- /* find CHILD_SA */
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current->get_reqid(current) == reqid)
- {
- child_sa = current;
- break;
- }
- }
- iterator->destroy(iterator);
- if (!child_sa)
- {
- DBG1(DBG_IKE, "acquiring CHILD_SA {reqid %d} failed: "
- "CHILD_SA not found", reqid);
- return FAILED;
- }
-
- child_cfg = child_sa->get_config(child_sa);
- child_cfg->get_ref(child_cfg);
-
- return initiate_with_reqid(this, child_cfg, reqid);
-}
-
-/**
- * Implementation of ike_sa_t.route.
- */
-static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
-{
- child_sa_t *child_sa;
- iterator_t *iterator;
- linked_list_t *my_ts, *other_ts;
- host_t *me, *other;
- status_t status;
-
- /* check if not already routed*/
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
- {
- if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
- streq(child_sa->get_name(child_sa), child_cfg->get_name(child_cfg)))
- {
- iterator->destroy(iterator);
- DBG1(DBG_IKE, "routing CHILD_SA failed: already routed");
- return FAILED;
- }
- }
- iterator->destroy(iterator);
-
- switch (this->state)
- {
- case IKE_DELETING:
- case IKE_REKEYING:
- DBG1(DBG_IKE, "routing CHILD_SA failed: IKE_SA is %N",
- ike_sa_state_names, this->state);
- return FAILED;
- case IKE_CREATED:
- case IKE_CONNECTING:
- case IKE_ESTABLISHED:
- case IKE_PASSIVE:
- default:
- break;
- }
-
- resolve_hosts(this);
-
- /* install kernel policies */
- child_sa = child_sa_create(this->my_host, this->other_host,
- child_cfg, 0, FALSE);
- me = this->my_host;
- if (this->my_virtual_ip)
- {
- me = this->my_virtual_ip;
- }
- other = this->other_host;
- if (this->other_virtual_ip)
- {
- other = this->other_virtual_ip;
- }
-
- my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me);
- other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other);
-
- child_sa->set_mode(child_sa, child_cfg->get_mode(child_cfg));
- status = child_sa->add_policies(child_sa, my_ts, other_ts);
-
- my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
- other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
- if (status == SUCCESS)
- {
- this->child_sas->insert_last(this->child_sas, child_sa);
- DBG1(DBG_IKE, "CHILD_SA routed");
- }
- else
- {
- child_sa->destroy(child_sa);
- DBG1(DBG_IKE, "routing CHILD_SA failed");
- }
- return status;
-}
-
-/**
- * Implementation of ike_sa_t.unroute.
- */
-static status_t unroute(private_ike_sa_t *this, u_int32_t reqid)
-{
- iterator_t *iterator;
- child_sa_t *child_sa;
- bool found = FALSE;
-
- /* find CHILD_SA in ROUTED state */
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
- {
- if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
- child_sa->get_reqid(child_sa) == reqid)
- {
- iterator->remove(iterator);
- DBG1(DBG_IKE, "CHILD_SA unrouted");
- child_sa->destroy(child_sa);
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (!found)
- {
- DBG1(DBG_IKE, "unrouting CHILD_SA failed: reqid %d not found", reqid);
- return FAILED;
- }
- /* if we are not established, and we have no more routed childs, remove whole SA */
- if (this->state == IKE_CREATED &&
- this->child_sas->get_count(this->child_sas) == 0)
- {
- return DESTROY_ME;
- }
- return SUCCESS;
-}
-
-/**
* Implementation of ike_sa_t.process_message.
*/
static status_t process_message(private_ike_sa_t *this, message_t *message)
@@ -1448,14 +1266,10 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
else
{
host_t *me, *other;
- private_ike_sa_t *new;
- iterator_t *iterator;
- child_sa_t *child;
- bool has_routed = FALSE;
me = message->get_destination(message);
other = message->get_source(message);
-
+
/* if this IKE_SA is virgin, we check for a config */
if (this->ike_cfg == NULL)
{
@@ -1485,59 +1299,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
update_hosts(this, me, other);
}
}
- status = this->task_manager->process_message(this->task_manager, message);
- if (status != DESTROY_ME)
- {
- if (message->get_exchange_type(message) == IKE_AUTH &&
- this->state == IKE_ESTABLISHED)
- {
- /* purge auth items if SA is up, as they contain certs
- * and other memory wasting elements */
- this->my_auth->purge(this->my_auth);
- this->other_auth->purge(this->other_auth);
- }
- return status;
- }
- /* if IKE_SA gets closed for any reasons, reroute routed children */
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child))
- {
- if (child->get_state(child) == CHILD_ROUTED)
- {
- has_routed = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
- if (!has_routed)
- {
- return status;
- }
- /* move routed children to a new IKE_SA, apply connection info */
- new = (private_ike_sa_t*)charon->ike_sa_manager->checkout_new(
- charon->ike_sa_manager, TRUE);
- set_peer_cfg(new, this->peer_cfg);
- new->other_host->destroy(new->other_host);
- new->other_host = this->other_host->clone(this->other_host);
- if (!has_condition(this, COND_NAT_THERE))
- {
- new->other_host->set_port(new->other_host, IKEV2_UDP_PORT);
- }
- if (this->my_virtual_ip)
- {
- set_virtual_ip(new, TRUE, this->my_virtual_ip);
- }
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child))
- {
- if (child->get_state(child) == CHILD_ROUTED)
- {
- route(new, child->get_config(child));
- }
- }
- iterator->destroy(iterator);
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, &new->public);
- return status;
+ return this->task_manager->process_message(this->task_manager, message);
}
}
@@ -1846,7 +1608,7 @@ static status_t reestablish(private_ike_sa_t *this)
#ifdef ME
if (this->peer_cfg->is_mediation(this->peer_cfg))
{
- status = new->initiate(new, NULL);
+ status = new->initiate(new, NULL, 0, NULL, NULL);
}
else
#endif /* ME */
@@ -1869,10 +1631,11 @@ static status_t reestablish(private_ike_sa_t *this)
DBG1(DBG_IKE, "restarting CHILD_SA %s",
child_cfg->get_name(child_cfg));
child_cfg->get_ref(child_cfg);
- status = new->initiate(new, child_cfg);
+ status = new->initiate(new, child_cfg, 0, NULL, NULL);
break;
case ACTION_ROUTE:
- status = new->route(new, child_cfg);
+ charon->traps->install(charon->traps,
+ this->peer_cfg, child_cfg);
break;
default:
continue;
@@ -1888,13 +1651,15 @@ static status_t reestablish(private_ike_sa_t *this)
if (status == DESTROY_ME)
{
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new);
- return FAILED;
+ status = FAILED;
}
else
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
- return SUCCESS;
+ status = SUCCESS;
}
+ charon->bus->set_sa(charon->bus, &this->public);
+ return status;
}
/**
@@ -1960,8 +1725,8 @@ static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
" in %ds", lifetime, lifetime - reduction);
charon->scheduler->schedule_job(charon->scheduler,
- (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
- (lifetime - reduction) * 1000);
+ (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
+ lifetime - reduction);
}
else
{
@@ -2030,12 +1795,34 @@ static status_t roam(private_ike_sa_t *this, bool address)
}
/**
+ * Implementation of ike_sa_t.add_configuration_attribute
+ */
+static void add_configuration_attribute(private_ike_sa_t *this,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ attribute_entry_t *entry;
+ attribute_handler_t *handler;
+
+ handler = charon->attributes->handle(charon->attributes,
+ &this->public, type, data);
+ if (handler)
+ {
+ entry = malloc_thing(attribute_entry_t);
+ entry->handler = handler;
+ entry->type = type;
+ entry->data = chunk_clone(data);
+
+ this->attributes->insert_last(this->attributes, entry);
+ }
+}
+
+/**
* Implementation of ike_sa_t.inherit.
*/
static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
{
child_sa_t *child_sa;
- host_t *ip;
+ attribute_entry_t *entry;
/* apply hosts and ids */
this->my_host->destroy(this->my_host);
@@ -2059,11 +1846,11 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
other->other_virtual_ip = NULL;
}
- /* ... and DNS servers */
- while (other->dns_servers->remove_last(other->dns_servers,
- (void**)&ip) == SUCCESS)
+ /* ... and configuration attributes */
+ while (other->attributes->remove_last(other->attributes,
+ (void**)&entry) == SUCCESS)
{
- this->dns_servers->insert_first(this->dns_servers, ip);
+ this->attributes->insert_first(this->attributes, entry);
}
/* inherit all conditions */
@@ -2107,158 +1894,36 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
"lifetime reduced to %ds", reauth, delete);
charon->scheduler->schedule_job(charon->scheduler,
- (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
- reauth * 1000);
+ (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth);
charon->scheduler->schedule_job(charon->scheduler,
- (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE),
- delete * 1000);
+ (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete);
}
/* we have to initate here, there may be new tasks to handle */
return this->task_manager->initiate(this->task_manager);
}
/**
- * Implementation of ike_sa_t.remove_dns_server
- */
-static void remove_dns_servers(private_ike_sa_t *this)
-{
- FILE *file;
- struct stat stats;
- chunk_t contents, line, orig_line, token;
- char string[INET6_ADDRSTRLEN];
- host_t *ip;
- iterator_t *iterator;
-
- if (this->dns_servers->get_count(this->dns_servers) == 0)
- {
- /* don't touch anything if we have no nameservers installed */
- return;
- }
-
- file = fopen(RESOLV_CONF, "r");
- if (file == NULL || stat(RESOLV_CONF, &stats) != 0)
- {
- DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s",
- RESOLV_CONF, strerror(errno));
- return;
- }
-
- contents = chunk_alloca((size_t)stats.st_size);
-
- if (fread(contents.ptr, 1, contents.len, file) != contents.len)
- {
- DBG1(DBG_IKE, "unable to read DNS configuration file: %s", strerror(errno));
- fclose(file);
- return;
- }
-
- fclose(file);
- file = fopen(RESOLV_CONF, "w");
- if (file == NULL)
- {
- DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s",
- RESOLV_CONF, strerror(errno));
- return;
- }
-
- iterator = this->dns_servers->create_iterator(this->dns_servers, TRUE);
- while (fetchline(&contents, &line))
- {
- bool found = FALSE;
- orig_line = line;
- if (extract_token(&token, ' ', &line) &&
- strncasecmp(token.ptr, "nameserver", token.len) == 0)
- {
- if (!extract_token(&token, ' ', &line))
- {
- token = line;
- }
- iterator->reset(iterator);
- while (iterator->iterate(iterator, (void**)&ip))
- {
- snprintf(string, sizeof(string), "%H", ip);
- if (strlen(string) == token.len &&
- strncmp(token.ptr, string, token.len) == 0)
- {
- iterator->remove(iterator);
- ip->destroy(ip);
- found = TRUE;
- break;
- }
- }
- }
-
- if (!found)
- {
- /* write line untouched back to file */
- ignore_result(fwrite(orig_line.ptr, orig_line.len, 1, file));
- fprintf(file, "\n");
- }
- }
- iterator->destroy(iterator);
- fclose(file);
-}
-
-/**
- * Implementation of ike_sa_t.add_dns_server
- */
-static void add_dns_server(private_ike_sa_t *this, host_t *dns)
-{
- FILE *file;
- struct stat stats;
- chunk_t contents;
-
- DBG1(DBG_IKE, "installing DNS server %H", dns);
-
- file = fopen(RESOLV_CONF, "a+");
- if (file == NULL || stat(RESOLV_CONF, &stats) != 0)
- {
- DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s",
- RESOLV_CONF, strerror(errno));
- return;
- }
-
- contents = chunk_alloca(stats.st_size);
-
- if (fread(contents.ptr, 1, contents.len, file) != contents.len)
- {
- DBG1(DBG_IKE, "unable to read DNS configuration file: %s", strerror(errno));
- fclose(file);
- return;
- }
-
- fclose(file);
- file = fopen(RESOLV_CONF, "w");
- if (file == NULL)
- {
- DBG1(DBG_IKE, "unable to open DNS configuration file %s: %s",
- RESOLV_CONF, strerror(errno));
- return;
- }
-
- if (fprintf(file, "nameserver %H # added by strongSwan, assigned by %D\n",
- dns, this->other_id) < 0)
- {
- DBG1(DBG_IKE, "unable to write DNS configuration: %s", strerror(errno));
- }
- else
- {
- this->dns_servers->insert_last(this->dns_servers, dns->clone(dns));
- }
- ignore_result(fwrite(contents.ptr, contents.len, 1, file));
-
- fclose(file);
-}
-
-/**
* Implementation of ike_sa_t.destroy.
*/
static void destroy(private_ike_sa_t *this)
{
+ attribute_entry_t *entry;
+
charon->bus->set_sa(charon->bus, &this->public);
set_state(this, IKE_DESTROYING);
+ /* remove attributes first, as we pass the IKE_SA to the handler */
+ while (this->attributes->remove_last(this->attributes,
+ (void**)&entry) == SUCCESS)
+ {
+ charon->attributes->release(charon->attributes, entry->handler,
+ &this->public, entry->type, entry->data);
+ free(entry->data.ptr);
+ free(entry);
+ }
+ this->attributes->destroy(this->attributes);
+
this->child_sas->destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
/* unset SA after here to avoid usage by the listeners */
@@ -2283,10 +1948,6 @@ static void destroy(private_ike_sa_t *this)
}
this->other_virtual_ip->destroy(this->other_virtual_ip);
}
-
- remove_dns_servers(this);
- this->dns_servers->destroy_offset(this->dns_servers,
- offsetof(host_t, destroy));
this->additional_addresses->destroy_offset(this->additional_addresses,
offsetof(host_t, destroy));
#ifdef ME
@@ -2309,9 +1970,9 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->ike_cfg);
DESTROY_IF(this->peer_cfg);
- DESTROY_IF(this->my_auth);
- DESTROY_IF(this->other_auth);
DESTROY_IF(this->proposal);
+ this->my_auth->destroy(this->my_auth);
+ this->other_auth->destroy(this->other_auth);
this->ike_sa_id->destroy(this->ike_sa_id);
free(this);
@@ -2331,16 +1992,12 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.get_name = (char* (*)(ike_sa_t*))get_name;
this->public.get_statistic = (u_int32_t(*)(ike_sa_t*, statistic_t kind))get_statistic;
this->public.process_message = (status_t (*)(ike_sa_t*, message_t*)) process_message;
- this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*)) initiate;
- this->public.route = (status_t (*)(ike_sa_t*,child_cfg_t*)) route;
- this->public.unroute = (status_t (*)(ike_sa_t*,u_int32_t)) unroute;
- this->public.acquire = (status_t (*)(ike_sa_t*,u_int32_t)) acquire;
+ this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*,u_int32_t,traffic_selector_t*,traffic_selector_t*)) initiate;
this->public.get_ike_cfg = (ike_cfg_t* (*)(ike_sa_t*))get_ike_cfg;
this->public.set_ike_cfg = (void (*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
this->public.get_peer_cfg = (peer_cfg_t* (*)(ike_sa_t*))get_peer_cfg;
this->public.set_peer_cfg = (void (*)(ike_sa_t*,peer_cfg_t*))set_peer_cfg;
- this->public.get_my_auth = (auth_info_t*(*)(ike_sa_t*))get_my_auth;
- this->public.get_other_auth = (auth_info_t*(*)(ike_sa_t*))get_other_auth;
+ this->public.get_auth_cfg = (auth_cfg_t*(*)(ike_sa_t*, bool local))get_auth_cfg;
this->public.get_proposal = (proposal_t*(*)(ike_sa_t*))get_proposal;
this->public.set_proposal = (void(*)(ike_sa_t*, proposal_t *proposal))set_proposal;
this->public.get_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id;
@@ -2388,7 +2045,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.get_unique_id = (u_int32_t (*)(ike_sa_t*))get_unique_id;
this->public.set_virtual_ip = (void (*)(ike_sa_t*,bool,host_t*))set_virtual_ip;
this->public.get_virtual_ip = (host_t* (*)(ike_sa_t*,bool))get_virtual_ip;
- this->public.add_dns_server = (void (*)(ike_sa_t*,host_t*))add_dns_server;
+ this->public.add_configuration_attribute = (void(*)(ike_sa_t*, configuration_attribute_type_t type, chunk_t data))add_configuration_attribute;
this->public.set_kmaddress = (void (*)(ike_sa_t*,host_t*,host_t*))set_kmaddress;
#ifdef ME
this->public.act_as_mediation_server = (void (*)(ike_sa_t*)) act_as_mediation_server;
@@ -2421,15 +2078,15 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->stats[STAT_INBOUND] = this->stats[STAT_OUTBOUND] = time(NULL);
this->ike_cfg = NULL;
this->peer_cfg = NULL;
- this->my_auth = auth_info_create();
- this->other_auth = auth_info_create();
+ this->my_auth = auth_cfg_create();
+ this->other_auth = auth_cfg_create();
this->proposal = NULL;
this->task_manager = task_manager_create(&this->public);
this->unique_id = ++unique_id;
this->my_virtual_ip = NULL;
this->other_virtual_ip = NULL;
- this->dns_servers = linked_list_create();
this->additional_addresses = linked_list_create();
+ this->attributes = linked_list_create();
this->nat_detection_dest = chunk_empty;
this->pending_updates = 0;
this->keyingtry = 0;
diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h
index 3ca8d9521..b751bda0c 100644
--- a/src/charon/sa/ike_sa.h
+++ b/src/charon/sa/ike_sa.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2008 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -35,18 +33,19 @@ typedef struct ike_sa_t ike_sa_t;
#include <library.h>
#include <encoding/message.h>
#include <encoding/payloads/proposal_substructure.h>
+#include <encoding/payloads/configuration_attribute.h>
#include <sa/ike_sa_id.h>
#include <sa/child_sa.h>
#include <sa/tasks/task.h>
#include <sa/keymat.h>
#include <config/peer_cfg.h>
#include <config/ike_cfg.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
/**
- * Timeout in milliseconds after that a half open IKE_SA gets deleted.
+ * Timeout in seconds after that a half open IKE_SA gets deleted.
*/
-#define HALF_OPEN_IKE_SA_TIMEOUT 30000
+#define HALF_OPEN_IKE_SA_TIMEOUT 30
/**
* Interval to send keepalives when NATed, in seconds.
@@ -82,6 +81,11 @@ enum ike_extension_t {
* peer supports HTTP cert lookups as specified in RFC4306
*/
EXT_HASH_AND_URL = (1<<2),
+
+ /**
+ * peer supports multiple authentication exchanges, RFC4739
+ */
+ EXT_MULTIPLE_AUTH = (1<<3),
};
/**
@@ -110,7 +114,7 @@ enum ike_condition_t {
COND_NAT_FAKE = (1<<3),
/**
- * peer has ben authenticated using EAP
+ * peer has been authenticated using EAP at least once
*/
COND_EAP_AUTHENTICATED = (1<<4),
@@ -391,18 +395,12 @@ struct ike_sa_t {
void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config);
/**
- * Get authentication/authorization info for local peer.
- *
- * @return auth_info for me
- */
- auth_info_t* (*get_my_auth)(ike_sa_t *this);
-
- /**
- * Get authentication/authorization info for remote peer.
+ * Get the authentication config with rules of the current auth round.
*
- * @return auth_info for me
+ * @param local TRUE for local rules, FALSE for remote constraints
+ * @return current cfg
*/
- auth_info_t* (*get_other_auth)(ike_sa_t *this);
+ auth_cfg_t* (*get_auth_cfg)(ike_sa_t *this, bool local);
/**
* Get the selected proposal of this IKE_SA.
@@ -602,51 +600,21 @@ struct ike_sa_t {
/**
* Initiate a new connection.
*
- * The configs are owned by the IKE_SA after the call.
+ * The configs are owned by the IKE_SA after the call. If the initiate
+ * is triggered by a packet, traffic selectors of the packet can be added
+ * to the CHILD_SA.
*
* @param child_cfg child config to create CHILD from
+ * @param reqid reqid to use for CHILD_SA, 0 assigne uniquely
+ * @param tsi source of triggering packet
+ * @param tsr destination of triggering packet.
* @return
* - SUCCESS if initialization started
* - DESTROY_ME if initialization failed
*/
- status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg);
-
- /**
- * Route a policy in the kernel.
- *
- * Installs the policies in the kernel. If traffic matches,
- * the kernel requests connection setup from the IKE_SA via acquire().
- *
- * @param child_cfg child config to route
- * @return
- * - SUCCESS if routed successfully
- * - FAILED if routing failed
- */
- status_t (*route) (ike_sa_t *this, child_cfg_t *child_cfg);
-
- /**
- * Unroute a policy in the kernel previously routed.
- *
- * @param reqid reqid of CHILD_SA to unroute
- * @return
- * - SUCCESS if route removed
- * - NOT_FOUND if CHILD_SA not found
- * - DESTROY_ME if last CHILD_SA was unrouted
- */
- status_t (*unroute) (ike_sa_t *this, u_int32_t reqid);
-
- /**
- * Acquire connection setup for an installed kernel policy.
- *
- * If an installed policy raises an acquire, the kernel calls
- * this function to establish the CHILD_SA (and maybe the IKE_SA).
- *
- * @param reqid reqid of the CHILD_SA the policy belongs to.
- * @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
- */
- status_t (*acquire) (ike_sa_t *this, u_int32_t reqid);
+ status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg,
+ u_int32_t reqid, traffic_selector_t *tsi,
+ traffic_selector_t *tsr);
/**
* Initiates the deletion of an IKE_SA.
@@ -869,14 +837,18 @@ struct ike_sa_t {
host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
/**
- * Add a DNS server to the system.
+ * Register a configuration attribute to the IKE_SA.
*
- * An IRAS may send a DNS server. To use it, it is installed on the
- * system. The DNS entry has a lifetime until the IKE_SA gets closed.
+ * If an IRAS sends a configuration attribute it is installed and
+ * registered at the IKE_SA. Attributes are inherit()ed and get released
+ * when the IKE_SA is closed.
*
- * @param dns DNS server to install on the system
+ * @param handler handler installed the attribute, use for release()
+ * @param type configuration attribute type
+ * @param data associated attribute data
*/
- void (*add_dns_server) (ike_sa_t *this, host_t *dns);
+ void (*add_configuration_attribute)(ike_sa_t *this,
+ configuration_attribute_type_t type, chunk_t data);
/**
* Set local and remote host addresses to be used for IKE.
@@ -888,7 +860,7 @@ struct ike_sa_t {
* @param remote remote kmaddress
*/
void (*set_kmaddress) (ike_sa_t *this, host_t *local, host_t *remote);
-
+
/**
* Inherit all attributes of other to this after rekeying.
*
diff --git a/src/charon/sa/ike_sa_id.c b/src/charon/sa/ike_sa_id.c
index e012d5944..94c5405f2 100644
--- a/src/charon/sa/ike_sa_id.c
+++ b/src/charon/sa/ike_sa_id.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa_id.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ike_sa_id.h"
diff --git a/src/charon/sa/ike_sa_id.h b/src/charon/sa/ike_sa_id.h
index db36fda95..377e64e8a 100644
--- a/src/charon/sa/ike_sa_id.h
+++ b/src/charon/sa/ike_sa_id.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa_id.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/ike_sa_manager.c b/src/charon/sa/ike_sa_manager.c
index e2aacddd5..efe7c228c 100644
--- a/src/charon/sa/ike_sa_manager.c
+++ b/src/charon/sa/ike_sa_manager.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa_manager.c 5035 2009-03-26 13:18:19Z andreas $
*/
#include <string.h>
@@ -901,25 +899,35 @@ static ike_sa_t* checkout(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id
*/
static ike_sa_t *checkout_new(private_ike_sa_manager_t* this, bool initiator)
{
+ ike_sa_id_t *ike_sa_id;
+ ike_sa_t *ike_sa;
entry_t *entry;
u_int segment;
- entry = entry_create();
if (initiator)
{
- entry->ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
+ ike_sa_id = ike_sa_id_create(get_next_spi(this), 0, TRUE);
}
else
{
- entry->ike_sa_id = ike_sa_id_create(0, get_next_spi(this), FALSE);
+ ike_sa_id = ike_sa_id_create(0, get_next_spi(this), FALSE);
+ }
+ ike_sa = ike_sa_create(ike_sa_id);
+
+ DBG2(DBG_MGR, "created IKE_SA");
+
+ if (!initiator)
+ {
+ ike_sa_id->destroy(ike_sa_id);
+ return ike_sa;
}
- entry->ike_sa = ike_sa_create(entry->ike_sa_id);
- segment = put_entry(this, entry);
+ entry = entry_create();
+ entry->ike_sa_id = ike_sa_id;
+ entry->ike_sa = ike_sa;
+ segment = put_entry(this, entry);
entry->checked_out = TRUE;
unlock_single_segment(this, segment);
-
- DBG2(DBG_MGR, "created IKE_SA");
return entry->ike_sa;
}
@@ -1042,9 +1050,7 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
enumerator_t *enumerator;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
- identification_t *my_id, *other_id;
- host_t *my_host, *other_host;
- ike_cfg_t *ike_cfg;
+ peer_cfg_t *current_cfg;
u_int segment;
if (!this->reuse_ikesa)
@@ -1054,70 +1060,29 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
return ike_sa;
}
- ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- my_id = peer_cfg->get_my_id(peer_cfg);
- other_id = peer_cfg->get_other_id(peer_cfg);
- my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0);
- other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0);
-
- if (my_host && other_host)
+ enumerator = create_table_enumerator(this);
+ while (enumerator->enumerate(enumerator, &entry, &segment))
{
- enumerator = create_table_enumerator(this);
- while (enumerator->enumerate(enumerator, &entry, &segment))
+ if (!wait_for_entry(this, entry, segment))
{
- identification_t *found_my_id, *found_other_id;
- host_t *found_my_host, *found_other_host;
-
- if (!wait_for_entry(this, entry, segment))
- {
- continue;
- }
-
- if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
- {
- /* skip IKE_SAs which are not usable */
- continue;
- }
-
- found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
- found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
- found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
- found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
+ continue;
+ }
+ if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
+ { /* skip IKE_SAs which are not usable */
+ continue;
+ }
- if (found_my_id->get_type(found_my_id) == ID_ANY &&
- found_other_id->get_type(found_other_id) == ID_ANY)
- {
- /* IKE_SA has no IDs yet, so we can't use it */
- continue;
- }
- DBG2(DBG_MGR, "candidate IKE_SA for \n"
- " %H[%D]...%H[%D]\n"
- " %H[%D]...%H[%D]",
- my_host, my_id, other_host, other_id,
- found_my_host, found_my_id, found_other_host, found_other_id);
- /* compare ID and hosts. Supplied ID may contain wildcards, and IP
- * may be %any. */
- if ((my_host->is_anyaddr(my_host) ||
- my_host->ip_equals(my_host, found_my_host)) &&
- (other_host->is_anyaddr(other_host) ||
- other_host->ip_equals(other_host, found_other_host)) &&
- found_my_id->matches(found_my_id, my_id) &&
- found_other_id->matches(found_other_id, other_id) &&
- streq(peer_cfg->get_name(peer_cfg),
- entry->ike_sa->get_name(entry->ike_sa)))
- {
- /* looks good, we take this one */
- DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
- my_host, my_id, other_host, other_id);
- entry->checked_out = TRUE;
- ike_sa = entry->ike_sa;
- break;
- }
+ current_cfg = entry->ike_sa->get_peer_cfg(entry->ike_sa);
+ if (current_cfg && current_cfg->equals(current_cfg, peer_cfg))
+ {
+ DBG2(DBG_MGR, "found an existing IKE_SA with a '%s' config",
+ current_cfg->get_name(current_cfg));
+ entry->checked_out = TRUE;
+ ike_sa = entry->ike_sa;
+ break;
}
- enumerator->destroy(enumerator);
}
- DESTROY_IF(my_host);
- DESTROY_IF(other_host);
+ enumerator->destroy(enumerator);
if (!ike_sa)
{ /* no IKE_SA using such a config, hand out a new */
@@ -1326,20 +1291,12 @@ static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
/* apply identities for duplicate test (only as responder) */
if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) &&
- (!entry->my_id || !entry->other_id))
+ ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
+ entry->my_id == NULL && entry->other_id == NULL)
{
- if (!entry->my_id && my_id->get_type(my_id) != ID_ANY)
- {
- entry->my_id = my_id->clone(my_id);
- }
- if (!entry->other_id && other_id->get_type(other_id) != ID_ANY)
- {
- entry->other_id = other_id->clone(other_id);
- }
- if (entry->my_id && entry->other_id)
- {
- put_connected_peers(this, entry);
- }
+ entry->my_id = my_id->clone(my_id);
+ entry->other_id = other_id->clone(other_id);
+ put_connected_peers(this, entry);
}
unlock_single_segment(this, segment);
@@ -1477,7 +1434,7 @@ static bool check_uniqueness(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
{
case UNIQUE_REPLACE:
DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer "
- "'%D' due to uniqueness policy", other);
+ "'%Y' due to uniqueness policy", other);
status = duplicate->delete(duplicate);
break;
case UNIQUE_KEEP:
diff --git a/src/charon/sa/ike_sa_manager.h b/src/charon/sa/ike_sa_manager.h
index 8fe991521..6da768080 100644
--- a/src/charon/sa/ike_sa_manager.h
+++ b/src/charon/sa/ike_sa_manager.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_sa_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -53,6 +51,9 @@ struct ike_sa_manager_t {
/**
* Create and check out a new IKE_SA.
+ *
+ * @note If initiator equals FALSE, the returned IKE_SA is not registered
+ * in the manager.
*
* @param initiator TRUE for initiator, FALSE otherwise
* @returns created and checked out IKE_SA
diff --git a/src/charon/sa/keymat.c b/src/charon/sa/keymat.c
index b2e646c93..117d260ba 100644
--- a/src/charon/sa/keymat.c
+++ b/src/charon/sa/keymat.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "keymat.h"
@@ -415,17 +413,18 @@ static bool derive_child_keys(private_keymat_t *this,
/* to bytes */
enc_size /= 8;
- /* CCM/GCM needs additional bytes */
+ /* CCM/GCM/CTR needs additional bytes */
switch (enc_alg)
{
case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16:
enc_size += 3;
- break;
+ break;
case ENCR_AES_GCM_ICV8:
case ENCR_AES_GCM_ICV12:
case ENCR_AES_GCM_ICV16:
+ case ENCR_AES_CTR:
enc_size += 4;
break;
default:
@@ -463,6 +462,16 @@ static bool derive_child_keys(private_keymat_t *this,
prf_plus->destroy(prf_plus);
+ if (enc_size)
+ {
+ DBG4(DBG_CHD, "encryption initiator key %B", encr_i);
+ DBG4(DBG_CHD, "encryption responder key %B", encr_r);
+ }
+ if (int_size)
+ {
+ DBG4(DBG_CHD, "integrity initiator key %B", integ_i);
+ DBG4(DBG_CHD, "integrity responder key %B", integ_r);
+ }
return TRUE;
}
diff --git a/src/charon/sa/keymat.h b/src/charon/sa/keymat.h
index 659e4dff2..43b9dd113 100644
--- a/src/charon/sa/keymat.h
+++ b/src/charon/sa/keymat.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/charon/sa/mediation_manager.c b/src/charon/sa/mediation_manager.c
index b508c48c3..890e567c7 100644
--- a/src/charon/sa/mediation_manager.c
+++ b/src/charon/sa/mediation_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mediation_manager.c 4579 2008-11-05 11:29:56Z martin $
*/
#include "mediation_manager.h"
@@ -227,12 +225,12 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
if (!found)
{
- DBG2(DBG_IKE, "adding peer '%D'", peer_id);
+ DBG2(DBG_IKE, "adding peer '%Y'", peer_id);
peer = peer_create(peer_id, NULL);
this->peers->insert_last(this->peers, peer);
}
- DBG2(DBG_IKE, "changing registered IKE_SA ID of peer '%D'", peer_id);
+ DBG2(DBG_IKE, "changing registered IKE_SA ID of peer '%Y'", peer_id);
peer->ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL;
/* send callbacks to registered peers */
@@ -284,7 +282,7 @@ static ike_sa_id_t *check_and_register(private_mediation_manager_t *this,
if (get_peer_by_id(this, peer_id, &peer) != SUCCESS)
{
- DBG2(DBG_IKE, "adding peer %D", peer_id);
+ DBG2(DBG_IKE, "adding peer %Y", peer_id);
peer = peer_create(peer_id, NULL);
this->peers->insert_last(this->peers, peer);
}
@@ -292,7 +290,7 @@ static ike_sa_id_t *check_and_register(private_mediation_manager_t *this,
if (!peer->ike_sa_id)
{
/* the peer is not online */
- DBG2(DBG_IKE, "requested peer '%D' is offline, registering peer '%D'", peer_id, requester);
+ DBG2(DBG_IKE, "requested peer '%Y' is offline, registering peer '%Y'", peer_id, requester);
register_peer(peer, requester);
this->mutex->unlock(this->mutex);
return NULL;
diff --git a/src/charon/sa/mediation_manager.h b/src/charon/sa/mediation_manager.h
index 7eee09d67..29e16d84f 100644
--- a/src/charon/sa/mediation_manager.h
+++ b/src/charon/sa/mediation_manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mediation_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c
index e5c5fe178..2cd9532eb 100644
--- a/src/charon/sa/task_manager.c
+++ b/src/charon/sa/task_manager.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: task_manager.c 4857 2009-02-09 10:45:51Z martin $
*/
#include "task_manager.h"
@@ -259,7 +257,7 @@ static status_t retransmit(private_task_manager_t *this, u_int32_t message_id)
this->initiating.retransmitted++;
job = (job_t*)retransmit_job_create(this->initiating.mid,
this->ike_sa->get_id(this->ike_sa));
- charon->scheduler->schedule_job(charon->scheduler, job, timeout);
+ charon->scheduler->schedule_job_ms(charon->scheduler, job, timeout);
}
return SUCCESS;
}
@@ -626,6 +624,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
/* message complete, send it */
DESTROY_IF(this->responding.packet);
+ this->responding.packet = NULL;
status = this->ike_sa->generate_message(this->ike_sa, message,
&this->responding.packet);
charon->bus->message(charon->bus, message, FALSE);
@@ -650,167 +649,170 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
static status_t process_request(private_task_manager_t *this,
message_t *message)
{
+ enumerator_t *enumerator;
iterator_t *iterator;
task_t *task = NULL;
payload_t *payload;
notify_payload_t *notify;
delete_payload_t *delete;
- /* create tasks depending on request type */
- switch (message->get_exchange_type(message))
- {
- case IKE_SA_INIT:
+ if (this->passive_tasks->get_count(this->passive_tasks) == 0)
+ { /* create tasks depending on request type, if not already some queued */
+ switch (message->get_exchange_type(message))
{
- task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
+ case IKE_SA_INIT:
+ {
+ task = (task_t*)ike_init_create(this->ike_sa, FALSE, NULL);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
#ifdef ME
- task = (task_t*)ike_me_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_me_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
#endif /* ME */
- task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_config_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)child_create_create(this->ike_sa, NULL);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- break;
- }
- case CREATE_CHILD_SA:
- { /* FIXME: we should prevent this on mediation connections */
- bool notify_found = FALSE, ts_found = FALSE;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
- {
- switch (payload->get_type(payload))
+ task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_config_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)child_create_create(this->ike_sa, NULL, NULL, NULL);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ break;
+ }
+ case CREATE_CHILD_SA:
+ { /* FIXME: we should prevent this on mediation connections */
+ bool notify_found = FALSE, ts_found = FALSE;
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
- case NOTIFY:
+ switch (payload->get_type(payload))
{
- /* if we find a rekey notify, its CHILD_SA rekeying */
- notify = (notify_payload_t*)payload;
- if (notify->get_notify_type(notify) == REKEY_SA &&
- (notify->get_protocol_id(notify) == PROTO_AH ||
- notify->get_protocol_id(notify) == PROTO_ESP))
- {
- notify_found = TRUE;
+ case NOTIFY:
+ { /* if we find a rekey notify, its CHILD_SA rekeying */
+ notify = (notify_payload_t*)payload;
+ if (notify->get_notify_type(notify) == REKEY_SA &&
+ (notify->get_protocol_id(notify) == PROTO_AH ||
+ notify->get_protocol_id(notify) == PROTO_ESP))
+ {
+ notify_found = TRUE;
+ }
+ break;
}
- break;
- }
- case TRAFFIC_SELECTOR_INITIATOR:
- case TRAFFIC_SELECTOR_RESPONDER:
- {
- /* if we don't find a TS, its IKE rekeying */
- ts_found = TRUE;
- break;
+ case TRAFFIC_SELECTOR_INITIATOR:
+ case TRAFFIC_SELECTOR_RESPONDER:
+ { /* if we don't find a TS, its IKE rekeying */
+ ts_found = TRUE;
+ break;
+ }
+ default:
+ break;
}
- default:
- break;
}
- }
- iterator->destroy(iterator);
-
- if (ts_found)
- {
- if (notify_found)
+ enumerator->destroy(enumerator);
+
+ if (ts_found)
{
- task = (task_t*)child_rekey_create(this->ike_sa,
- PROTO_NONE, 0);
+ if (notify_found)
+ {
+ task = (task_t*)child_rekey_create(this->ike_sa,
+ PROTO_NONE, 0);
+ }
+ else
+ {
+ task = (task_t*)child_create_create(this->ike_sa,
+ NULL, NULL, NULL);
+ }
}
else
{
- task = (task_t*)child_create_create(this->ike_sa, NULL);
+ task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
}
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ break;
}
- else
- {
- task = (task_t*)ike_rekey_create(this->ike_sa, FALSE);
- }
- this->passive_tasks->insert_last(this->passive_tasks, task);
- break;
- }
- case INFORMATIONAL:
- {
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ case INFORMATIONAL:
{
- switch (payload->get_type(payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
- case NOTIFY:
+ switch (payload->get_type(payload))
{
- notify = (notify_payload_t*)payload;
- switch (notify->get_notify_type(notify))
+ case NOTIFY:
{
- case ADDITIONAL_IP4_ADDRESS:
- case ADDITIONAL_IP6_ADDRESS:
- case NO_ADDITIONAL_ADDRESSES:
- case UPDATE_SA_ADDRESSES:
- case NO_NATS_ALLOWED:
- case UNACCEPTABLE_ADDRESSES:
- case UNEXPECTED_NAT_DETECTED:
- case COOKIE2:
- case NAT_DETECTION_SOURCE_IP:
- case NAT_DETECTION_DESTINATION_IP:
- task = (task_t*)ike_mobike_create(
- this->ike_sa, FALSE);
- break;
- case AUTH_LIFETIME:
- task = (task_t*)ike_auth_lifetime_create(
- this->ike_sa, FALSE);
- break;
- default:
- break;
+ notify = (notify_payload_t*)payload;
+ switch (notify->get_notify_type(notify))
+ {
+ case ADDITIONAL_IP4_ADDRESS:
+ case ADDITIONAL_IP6_ADDRESS:
+ case NO_ADDITIONAL_ADDRESSES:
+ case UPDATE_SA_ADDRESSES:
+ case NO_NATS_ALLOWED:
+ case UNACCEPTABLE_ADDRESSES:
+ case UNEXPECTED_NAT_DETECTED:
+ case COOKIE2:
+ case NAT_DETECTION_SOURCE_IP:
+ case NAT_DETECTION_DESTINATION_IP:
+ task = (task_t*)ike_mobike_create(
+ this->ike_sa, FALSE);
+ break;
+ case AUTH_LIFETIME:
+ task = (task_t*)ike_auth_lifetime_create(
+ this->ike_sa, FALSE);
+ break;
+ default:
+ break;
+ }
+ break;
}
- break;
- }
- case DELETE:
- {
- delete = (delete_payload_t*)payload;
- if (delete->get_protocol_id(delete) == PROTO_IKE)
- {
- task = (task_t*)ike_delete_create(this->ike_sa, FALSE);
- }
- else
+ case DELETE:
{
- task = (task_t*)child_delete_create(this->ike_sa,
+ delete = (delete_payload_t*)payload;
+ if (delete->get_protocol_id(delete) == PROTO_IKE)
+ {
+ task = (task_t*)ike_delete_create(this->ike_sa,
+ FALSE);
+ }
+ else
+ {
+ task = (task_t*)child_delete_create(this->ike_sa,
PROTO_NONE, 0);
+ }
+ break;
}
- break;
+ default:
+ break;
}
- default:
+ if (task)
+ {
break;
+ }
}
- if (task)
+ enumerator->destroy(enumerator);
+
+ if (task == NULL)
{
- break;
+ task = (task_t*)ike_dpd_create(FALSE);
}
+ this->passive_tasks->insert_last(this->passive_tasks, task);
+ break;
}
- iterator->destroy(iterator);
-
- if (task == NULL)
+#ifdef ME
+ case ME_CONNECT:
{
- task = (task_t*)ike_dpd_create(FALSE);
+ task = (task_t*)ike_me_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
}
- this->passive_tasks->insert_last(this->passive_tasks, task);
- break;
- }
-#ifdef ME
- case ME_CONNECT:
- {
- task = (task_t*)ike_me_create(this->ike_sa, FALSE);
- this->passive_tasks->insert_last(this->passive_tasks, task);
- }
#endif /* ME */
- default:
- break;
+ default:
+ break;
+ }
}
/* let the tasks process the message */
@@ -941,15 +943,6 @@ static void adopt_tasks(private_task_manager_t *this, private_task_manager_t *ot
task->migrate(task, this->ike_sa);
this->queued_tasks->insert_first(this->queued_tasks, task);
}
-
- /* reset active tasks and move them to others queued tasks */
- while (other->active_tasks->remove_last(other->active_tasks,
- (void**)&task) == SUCCESS)
- {
- DBG2(DBG_IKE, "migrating %N task", task_type_names, task->get_type(task));
- task->migrate(task, this->ike_sa);
- this->queued_tasks->insert_first(this->queued_tasks, task);
- }
}
/**
diff --git a/src/charon/sa/task_manager.h b/src/charon/sa/task_manager.h
index db21684c3..9c3b2cc87 100644
--- a/src/charon/sa/task_manager.h
+++ b/src/charon/sa/task_manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: task_manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index c07cd37b8..f51443738 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_create.c 4860 2009-02-11 13:09:52Z martin $
*/
#include "child_create.h"
@@ -87,6 +85,16 @@ struct private_child_create_t {
linked_list_t *tsr;
/**
+ * source of triggering packet
+ */
+ traffic_selector_t *packet_tsi;
+
+ /**
+ * destination of triggering packet
+ */
+ traffic_selector_t *packet_tsr;
+
+ /**
* optional diffie hellman exchange
*/
diffie_hellman_t *dh;
@@ -570,7 +578,7 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify
*/
static void process_payloads(private_child_create_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
sa_payload_t *sa_payload;
ke_payload_t *ke_payload;
@@ -579,8 +587,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
/* defaults to TUNNEL mode */
this->mode = MODE_TUNNEL;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
switch (payload->get_type(payload))
{
@@ -616,7 +624,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -643,9 +651,9 @@ static status_t build_i(private_child_create_t *this, message_t *message)
}
break;
case IKE_AUTH:
- if (!message->get_payload(message, ID_INITIATOR))
+ if (message->get_message_id(message) != 1)
{
- /* send only in the first request, not in subsequent EAP */
+ /* send only in the first request, not in subsequent rounds */
return NEED_MORE;
}
break;
@@ -694,7 +702,17 @@ static status_t build_i(private_child_create_t *this, message_t *message)
}
this->tsr = this->config->get_traffic_selectors(this->config, FALSE,
NULL, other);
-
+
+ if (this->packet_tsi)
+ {
+ this->tsi->insert_first(this->tsi,
+ this->packet_tsi->clone(this->packet_tsi));
+ }
+ if (this->packet_tsr)
+ {
+ this->tsr->insert_first(this->tsr,
+ this->packet_tsr->clone(this->packet_tsr));
+ }
this->proposals = this->config->get_proposals(this->config,
this->dh_group == MODP_NONE);
this->mode = this->config->get_mode(this->config);
@@ -737,8 +755,6 @@ static status_t build_i(private_child_create_t *this, message_t *message)
*/
static status_t process_r(private_child_create_t *this, message_t *message)
{
- peer_cfg_t *peer_cfg;
-
switch (message->get_exchange_type(message))
{
case IKE_SA_INIT:
@@ -747,42 +763,17 @@ static status_t process_r(private_child_create_t *this, message_t *message)
get_nonce(message, &this->other_nonce);
break;
case IKE_AUTH:
- if (message->get_payload(message, ID_INITIATOR) == NULL)
+ if (message->get_message_id(message) != 1)
{
- /* wait until extensible authentication completed, if used */
+ /* only handle first AUTH payload, not additional rounds */
return NEED_MORE;
}
default:
break;
}
-
+
process_payloads(this, message);
- if (this->tsi == NULL || this->tsr == NULL)
- {
- DBG1(DBG_IKE, "TS payload missing in message");
- return NEED_MORE;
- }
-
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (peer_cfg)
- {
- host_t *me, *other;
-
- me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (me == NULL)
- {
- me = this->ike_sa->get_my_host(this->ike_sa);
- }
- other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
- if (other == NULL)
- {
- other = this->ike_sa->get_other_host(this->ike_sa);
- }
-
- this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
- this->tsi, me, other);
- }
return NEED_MORE;
}
@@ -799,7 +790,7 @@ static void handle_child_sa_failure(private_child_create_t *this,
/* we delay the delete for 100ms, as the IKE_AUTH response must arrive
* first */
DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)
+ charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)
delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
100);
}
@@ -810,10 +801,11 @@ static void handle_child_sa_failure(private_child_create_t *this,
*/
static status_t build_r(private_child_create_t *this, message_t *message)
{
+ peer_cfg_t *peer_cfg;
payload_t *payload;
- iterator_t *iterator;
+ enumerator_t *enumerator;
bool no_dh = TRUE;
-
+
switch (message->get_exchange_type(message))
{
case IKE_SA_INIT:
@@ -828,9 +820,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
no_dh = FALSE;
break;
case IKE_AUTH:
- if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
- {
- /* wait until extensible authentication completed, if used */
+ if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+ { /* wait until all authentication round completed */
return NEED_MORE;
}
default:
@@ -844,6 +835,25 @@ static status_t build_r(private_child_create_t *this, message_t *message)
return SUCCESS;
}
+ peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ if (peer_cfg && this->tsi && this->tsr)
+ {
+ host_t *me, *other;
+
+ me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
+ if (me == NULL)
+ {
+ me = this->ike_sa->get_my_host(this->ike_sa);
+ }
+ other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
+ if (other == NULL)
+ {
+ other = this->ike_sa->get_other_host(this->ike_sa);
+ }
+ this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
+ this->tsi, me, other);
+ }
+
if (this->config == NULL)
{
DBG1(DBG_IKE, "traffic selectors %#R=== %#R inacceptable",
@@ -854,8 +864,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
}
/* check if ike_config_t included non-critical error notifies */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -868,7 +878,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
{
DBG1(DBG_IKE,"configuration payload negotation "
"failed, no CHILD_SA built");
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
handle_child_sa_failure(this, message);
return SUCCESS;
}
@@ -877,7 +887,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
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,
@@ -938,7 +948,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
*/
static status_t process_i(private_child_create_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
bool no_dh = TRUE;
@@ -951,9 +961,8 @@ static status_t process_i(private_child_create_t *this, message_t *message)
no_dh = FALSE;
break;
case IKE_AUTH:
- if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
- {
- /* wait until extensible authentication completed, if used */
+ if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+ { /* wait until all authentication round completed */
return NEED_MORE;
}
default:
@@ -961,8 +970,8 @@ static status_t process_i(private_child_create_t *this, message_t *message)
}
/* check for erronous notifies */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -982,7 +991,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
{
DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
notify_type_names, type);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
handle_child_sa_failure(this, message);
/* an error in CHILD_SA creation is not critical */
return SUCCESS;
@@ -1000,7 +1009,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
bad_group, diffie_hellman_group_names, this->dh_group);
this->public.task.migrate(&this->public.task, this->ike_sa);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return NEED_MORE;
}
default:
@@ -1008,7 +1017,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
process_payloads(this, message);
@@ -1149,6 +1158,8 @@ static void destroy(private_child_create_t *this)
{
DESTROY_IF(this->child_sa);
}
+ DESTROY_IF(this->packet_tsi);
+ DESTROY_IF(this->packet_tsr);
DESTROY_IF(this->proposal);
DESTROY_IF(this->dh);
if (this->proposals)
@@ -1163,7 +1174,8 @@ static void destroy(private_child_create_t *this)
/*
* Described in header.
*/
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
+child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+ traffic_selector_t *tsi, traffic_selector_t *tsr)
{
private_child_create_t *this = malloc_thing(private_child_create_t);
@@ -1195,6 +1207,8 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config)
this->proposal = NULL;
this->tsi = NULL;
this->tsr = NULL;
+ this->packet_tsi = tsi ? tsi->clone(tsi) : NULL;
+ this->packet_tsr = tsr ? tsr->clone(tsr) : NULL;
this->dh = NULL;
this->dh_group = MODP_NONE;
this->keymat = ike_sa->get_keymat(ike_sa);
diff --git a/src/charon/sa/tasks/child_create.h b/src/charon/sa/tasks/child_create.h
index d01baa594..ce2829a9a 100644
--- a/src/charon/sa/tasks/child_create.h
+++ b/src/charon/sa/tasks/child_create.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_create.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -73,8 +71,11 @@ struct child_create_t {
*
* @param ike_sa IKE_SA this task works for
* @param config child_cfg if task initiator, NULL if responder
- * @return child_create task to handle by the task_manager
+ * @param tsi source of triggering packet, or NULL
+ * @param tsr destination of triggering packet, or NULL
+ * @return child_create task to handle by the task_manager
*/
-child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config);
+child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config,
+ traffic_selector_t *tsi, traffic_selector_t *tsr);
#endif /** CHILD_CREATE_H_ @}*/
diff --git a/src/charon/sa/tasks/child_delete.c b/src/charon/sa/tasks/child_delete.c
index 0fd4a056b..0d89c148e 100644
--- a/src/charon/sa/tasks/child_delete.c
+++ b/src/charon/sa/tasks/child_delete.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_delete.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "child_delete.h"
@@ -114,15 +112,16 @@ static void build_payloads(private_child_delete_t *this, message_t *message)
*/
static void process_payloads(private_child_delete_t *this, message_t *message)
{
- iterator_t *payloads, *spis;
+ enumerator_t *payloads;
+ iterator_t *spis;
payload_t *payload;
delete_payload_t *delete_payload;
u_int32_t *spi;
protocol_id_t protocol;
child_sa_t *child_sa;
- payloads = message->get_payload_iterator(message);
- while (payloads->iterate(payloads, (void**)&payload))
+ payloads = message->create_payload_enumerator(message);
+ while (payloads->enumerate(payloads, &payload))
{
if (payload->get_type(payload) == DELETE)
{
@@ -202,10 +201,12 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
{
case ACTION_RESTART:
child_cfg->get_ref(child_cfg);
- status = this->ike_sa->initiate(this->ike_sa, child_cfg);
+ status = this->ike_sa->initiate(this->ike_sa, child_cfg, 0,
+ NULL, NULL);
break;
- case ACTION_ROUTE:
- status = this->ike_sa->route(this->ike_sa, child_cfg);
+ case ACTION_ROUTE:
+ charon->traps->install(charon->traps,
+ this->ike_sa->get_peer_cfg(this->ike_sa), child_cfg);
break;
default:
break;
diff --git a/src/charon/sa/tasks/child_delete.h b/src/charon/sa/tasks/child_delete.h
index 8886ff4a1..27d847035 100644
--- a/src/charon/sa/tasks/child_delete.h
+++ b/src/charon/sa/tasks/child_delete.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_delete.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/child_rekey.c b/src/charon/sa/tasks/child_rekey.c
index 0d8cf2db7..6ab00dc5b 100644
--- a/src/charon/sa/tasks/child_rekey.c
+++ b/src/charon/sa/tasks/child_rekey.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_rekey.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "child_rekey.h"
@@ -103,11 +101,11 @@ static status_t process_i_delete(private_child_rekey_t *this, message_t *message
*/
static void find_child(private_child_rekey_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
notify_payload_t *notify;
u_int32_t spi;
@@ -131,7 +129,7 @@ static void find_child(private_child_rekey_t *this, message_t *message)
break;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -159,7 +157,7 @@ static status_t build_i(private_child_rekey_t *this, message_t *message)
/* ... our CHILD_CREATE task does the hard work for us. */
reqid = this->child_sa->get_reqid(this->child_sa);
- this->child_create = child_create_create(this->ike_sa, config);
+ this->child_create = child_create_create(this->ike_sa, config, NULL, NULL);
this->child_create->use_reqid(this->child_create, reqid);
this->child_create->task.build(&this->child_create->task, message);
@@ -220,12 +218,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
protocol_id_t protocol;
u_int32_t spi;
child_sa_t *to_delete;
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
/* handle NO_ADDITIONAL_SAS notify */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -239,12 +237,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
charon->processor->queue_job(charon->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return SUCCESS;
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (this->child_create->task.process(&this->child_create->task, message) == NEED_MORE)
{
@@ -269,7 +267,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "CHILD_SA rekeying failed, "
"trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, job, retry);
}
return SUCCESS;
}
@@ -418,7 +416,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
this->initiator = FALSE;
- this->child_create = child_create_create(ike_sa, NULL);
+ this->child_create = child_create_create(ike_sa, NULL, NULL, NULL);
}
this->ike_sa = ike_sa;
diff --git a/src/charon/sa/tasks/child_rekey.h b/src/charon/sa/tasks/child_rekey.h
index 42fce0742..5aae2fb39 100644
--- a/src/charon/sa/tasks/child_rekey.h
+++ b/src/charon/sa/tasks/child_rekey.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: child_rekey.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index 93b145755..8d6cd56bd 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details
- *
- * $Id: ike_auth.c 4858 2009-02-10 17:21:44Z martin $
*/
#include "ike_auth.h"
@@ -21,14 +19,12 @@
#include <string.h>
#include <daemon.h>
-#include <crypto/diffie_hellman.h>
#include <encoding/payloads/id_payload.h>
#include <encoding/payloads/auth_payload.h>
#include <encoding/payloads/eap_payload.h>
#include <encoding/payloads/nonce_payload.h>
#include <sa/authenticators/eap_authenticator.h>
-
typedef struct private_ike_auth_t private_ike_auth_t;
/**
@@ -72,220 +68,65 @@ struct private_ike_auth_t {
packet_t *other_packet;
/**
- * EAP authenticator when using EAP
+ * completed authentication configs initiated by us (auth_cfg_t)
*/
- eap_authenticator_t *eap_auth;
+ linked_list_t *my_cfgs;
/**
- * EAP payload received and ready to process
+ * completed authentication configs initiated by other (auth_cfg_t)
*/
- eap_payload_t *eap_payload;
+ linked_list_t *other_cfgs;;
/**
- * has the peer been authenticated successfully?
+ * currently active authenticator, to authenticate us
*/
- bool peer_authenticated;
-};
-
-/**
- * get the authentication class of a config
- */
-auth_class_t get_auth_class(peer_cfg_t *config)
-{
- auth_class_t *class;
- auth_info_t *auth_info;
-
- auth_info = config->get_auth(config);
- if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
- {
- return *class;
- }
- /* fallback to pubkey authentication */
- return AUTH_CLASS_PUBKEY;
-}
-
-/**
- * get the eap type/vendor
- */
-static eap_type_t get_eap_type(peer_cfg_t *config, u_int32_t *vendor)
-{
- auth_info_t *auth_info;
- u_int *ptr;
-
- *vendor = 0;
- auth_info = config->get_auth(config);
- if (auth_info->get_item(auth_info, AUTHN_EAP_VENDOR, (void**)&ptr))
- {
- *vendor = *ptr;
- }
- if (auth_info->get_item(auth_info, AUTHN_EAP_TYPE, (void**)&ptr))
- {
- return *ptr;
- }
- return EAP_NAK;
-}
-
-/**
- * build the AUTH payload
- */
-static status_t build_auth(private_ike_auth_t *this, message_t *message)
-{
- authenticator_t *auth;
- auth_payload_t *auth_payload;
- peer_cfg_t *config;
- status_t status;
-
- /* create own authenticator and add auth payload */
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (!config)
- {
- DBG1(DBG_IKE, "unable to authenticate, no peer config found");
- return FAILED;
- }
-
- auth = authenticator_create_from_class(this->ike_sa, get_auth_class(config));
- if (auth == NULL)
- {
- DBG1(DBG_IKE, "configured authentication class %N not supported",
- auth_class_names, get_auth_class(config));
- return FAILED;
- }
-
- status = auth->build(auth, this->my_packet->get_data(this->my_packet),
- this->other_nonce, &auth_payload);
- auth->destroy(auth);
- if (status != SUCCESS)
- {
- DBG1(DBG_IKE, "generating authentication data failed");
- return FAILED;
- }
- message->add_payload(message, (payload_t*)auth_payload);
- return SUCCESS;
-}
-
-/**
- * build ID payload(s)
- */
-static status_t build_id(private_ike_auth_t *this, message_t *message)
-{
- identification_t *me, *other;
- id_payload_t *id;
- peer_cfg_t *config;
+ authenticator_t *my_auth;
- me = this->ike_sa->get_my_id(this->ike_sa);
- other = this->ike_sa->get_other_id(this->ike_sa);
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
-
- if (me->contains_wildcards(me))
- {
- me = config->get_my_id(config);
- if (me->contains_wildcards(me))
- {
- DBG1(DBG_IKE, "negotiation of own ID failed");
- return FAILED;
- }
- this->ike_sa->set_my_id(this->ike_sa, me->clone(me));
- }
+ /**
+ * currently active authenticator, to authenticate peer
+ */
+ authenticator_t *other_auth;
- id = id_payload_create_from_identification(this->initiator ? ID_INITIATOR : ID_RESPONDER, me);
- message->add_payload(message, (payload_t*)id);
+ /**
+ * peer_cfg candidates, ordered by priority
+ */
+ linked_list_t *candidates;
- /* as initiator, include other ID if it does not contain wildcards */
- if (this->initiator && !other->contains_wildcards(other))
- {
- id = id_payload_create_from_identification(ID_RESPONDER, other);
- message->add_payload(message, (payload_t*)id);
- }
- return SUCCESS;
-}
-
-/**
- * process AUTH payload
- */
-static status_t process_auth(private_ike_auth_t *this, message_t *message)
-{
- auth_payload_t *auth_payload;
- authenticator_t *auth;
- auth_method_t auth_method;
- status_t status;
+ /**
+ * selected peer config (might change when using multiple authentications)
+ */
+ peer_cfg_t *peer_cfg;
- auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+ /**
+ * have we planned an(other) authentication exchange?
+ */
+ bool do_another_auth;
- if (auth_payload == NULL)
- {
- /* AUTH payload is missing, client wants to use EAP authentication */
- return NOT_FOUND;
- }
+ /**
+ * has the peer announced another authentication exchange?
+ */
+ bool expect_another_auth;
- auth_method = auth_payload->get_auth_method(auth_payload);
- auth = authenticator_create_from_method(this->ike_sa,
- auth_payload->get_auth_method(auth_payload));
- if (auth == NULL)
- {
- DBG1(DBG_IKE, "authentication method %N used by '%D' not supported",
- auth_method_names, auth_method,
- this->ike_sa->get_other_id(this->ike_sa));
- return NOT_SUPPORTED;
- }
- status = auth->verify(auth, this->other_packet->get_data(this->other_packet),
- this->my_nonce, auth_payload);
- auth->destroy(auth);
- if (status != SUCCESS)
- {
- DBG0(DBG_IKE, "authentication of '%D' with %N failed",
- this->ike_sa->get_other_id(this->ike_sa),
- auth_method_names, auth_method);
- return FAILED;
- }
- return SUCCESS;
-}
+ /**
+ * should we send a AUTHENTICATION_FAILED notify?
+ */
+ bool authentication_failed;
+};
/**
- * process ID payload(s)
+ * check if multiple authentication extension is enabled, configuration-wise
*/
-static status_t process_id(private_ike_auth_t *this, message_t *message)
+static bool multiple_auth_enabled()
{
- identification_t *id, *req;
- id_payload_t *idr, *idi;
-
- idi = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
- idr = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
-
- if ((this->initiator && idr == NULL) || (!this->initiator && idi == NULL))
- {
- DBG1(DBG_IKE, "ID payload missing in message");
- return FAILED;
- }
-
- if (this->initiator)
- {
- id = idr->get_identification(idr);
- req = this->ike_sa->get_other_id(this->ike_sa);
- if (!id->matches(id, req))
- {
- DBG0(DBG_IKE, "peer ID '%D' unacceptable, '%D' required", id, req);
- id->destroy(id);
- return FAILED;
- }
- this->ike_sa->set_other_id(this->ike_sa, id);
- }
- else
- {
- id = idi->get_identification(idi);
- this->ike_sa->set_other_id(this->ike_sa, id);
- if (idr)
- {
- id = idr->get_identification(idr);
- this->ike_sa->set_my_id(this->ike_sa, id);
- }
- }
- return SUCCESS;
+ return lib->settings->get_bool(lib->settings,
+ "charon.multiple_authentication", TRUE);
}
/**
* collect the needed information in the IKE_SA_INIT exchange from our message
*/
-static status_t collect_my_init_data(private_ike_auth_t *this, message_t *message)
+static status_t collect_my_init_data(private_ike_auth_t *this,
+ message_t *message)
{
nonce_payload_t *nonce;
@@ -297,7 +138,7 @@ static status_t collect_my_init_data(private_ike_auth_t *this, message_t *messag
}
this->my_nonce = nonce->get_nonce(nonce);
- /* pre-generate the message, so we can store it for us */
+ /* pre-generate the message, keep a copy */
if (this->ike_sa->generate_message(this->ike_sa, message,
&this->my_packet) != SUCCESS)
{
@@ -309,7 +150,8 @@ static status_t collect_my_init_data(private_ike_auth_t *this, message_t *messag
/**
* collect the needed information in the IKE_SA_INIT exchange from others message
*/
-static status_t collect_other_init_data(private_ike_auth_t *this, message_t *message)
+static status_t collect_other_init_data(private_ike_auth_t *this,
+ message_t *message)
{
/* we collect the needed information in the IKE_SA_INIT exchange */
nonce_payload_t *nonce;
@@ -322,184 +164,186 @@ static status_t collect_other_init_data(private_ike_auth_t *this, message_t *mes
}
this->other_nonce = nonce->get_nonce(nonce);
- /* pre-generate the message, so we can store it for us */
+ /* keep a copy of the received packet */
this->other_packet = message->get_packet(message);
return NEED_MORE;
}
-
/**
- * Implementation of task_t.build to create AUTH payload from EAP data
+ * Get the next authentication configuration
*/
-static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
+static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
{
- authenticator_t *auth;
- auth_payload_t *auth_payload;
+ enumerator_t *e1, *e2;
+ auth_cfg_t *c1, *c2, *next = NULL;
- if (!this->initiator && !this->peer_authenticated)
+ /* find an available config not already done */
+ e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, local);
+ while (e1->enumerate(e1, &c1))
{
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
- }
-
- auth = (authenticator_t*)this->eap_auth;
- if (auth->build(auth, this->my_packet->get_data(this->my_packet),
- this->other_nonce, &auth_payload) != SUCCESS)
- {
- DBG1(DBG_IKE, "generating authentication data failed");
- if (!this->initiator)
+ bool found = FALSE;
+
+ if (local)
{
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+ e2 = this->my_cfgs->create_enumerator(this->my_cfgs);
+ }
+ else
+ {
+ e2 = this->other_cfgs->create_enumerator(this->other_cfgs);
+ }
+ while (e2->enumerate(e2, &c2))
+ {
+ if (c2->complies(c2, c1, FALSE))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ e2->destroy(e2);
+ if (!found)
+ {
+ next = c1;
+ break;
}
- return FAILED;
- }
- message->add_payload(message, (payload_t*)auth_payload);
- if (!this->initiator)
- {
- this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
- this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_unique_id(this->ike_sa),
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
- return SUCCESS;
}
- return NEED_MORE;
+ e1->destroy(e1);
+ return next;
}
/**
- * Implementation of task_t.process to verify AUTH payload after EAP
+ * Check if we have should initiate another authentication round
*/
-static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
+static bool do_another_auth(private_ike_auth_t *this)
{
- auth_payload_t *auth_payload;
- authenticator_t *auth;
-
- auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
- this->peer_authenticated = FALSE;
+ bool do_another = FALSE;
+ enumerator_t *done, *todo;
+ auth_cfg_t *done_cfg, *todo_cfg;
- if (auth_payload)
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
{
- auth = (authenticator_t*)this->eap_auth;
- if (auth->verify(auth, this->other_packet->get_data(this->other_packet),
- this->my_nonce, auth_payload) == SUCCESS)
- {
- this->peer_authenticated = TRUE;
- }
+ return FALSE;
}
-
- if (!this->peer_authenticated)
+
+ done = this->my_cfgs->create_enumerator(this->my_cfgs);
+ todo = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, TRUE);
+ while (todo->enumerate(todo, &todo_cfg))
{
- DBG0(DBG_IKE, "authentication of '%D' with %N failed",
- this->ike_sa->get_other_id(this->ike_sa),
- auth_class_names, AUTH_CLASS_EAP);
- if (this->initiator)
+ if (!done->enumerate(done, &done_cfg))
{
- return FAILED;
+ done_cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ }
+ if (!done_cfg->complies(done_cfg, todo_cfg, FALSE))
+ {
+ do_another = TRUE;
+ break;
}
- return NEED_MORE;
- }
- if (this->initiator)
- {
- this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
- this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_unique_id(this->ike_sa),
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
- return SUCCESS;
}
- return NEED_MORE;
+ done->destroy(done);
+ todo->destroy(todo);
+ return do_another;
}
/**
- * Implementation of task_t.process for EAP exchanges
+ * Get peer configuration candidates from backends
*/
-static status_t process_eap_i(private_ike_auth_t *this, message_t *message)
+static bool load_cfg_candidates(private_ike_auth_t *this)
{
- eap_payload_t *eap;
-
- eap = (eap_payload_t*)message->get_payload(message, EXTENSIBLE_AUTHENTICATION);
- if (eap == NULL)
- {
- DBG1(DBG_IKE, "EAP payload missing");
- return FAILED;
+ enumerator_t *enumerator;
+ peer_cfg_t *peer_cfg;
+ host_t *me, *other;
+ identification_t *my_id, *other_id;
+
+ me = this->ike_sa->get_my_host(this->ike_sa);
+ other = this->ike_sa->get_other_host(this->ike_sa);
+ my_id = this->ike_sa->get_my_id(this->ike_sa);
+ other_id = this->ike_sa->get_other_id(this->ike_sa);
+
+ enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+ me, other, my_id, other_id);
+ while (enumerator->enumerate(enumerator, &peer_cfg))
+ {
+ peer_cfg->get_ref(peer_cfg);
+ if (this->peer_cfg == NULL)
+ { /* best match */
+ this->peer_cfg = peer_cfg;
+ this->ike_sa->set_peer_cfg(this->ike_sa, peer_cfg);
+ }
+ else
+ {
+ this->candidates->insert_last(this->candidates, peer_cfg);
+ }
}
- switch (this->eap_auth->process(this->eap_auth, eap, &eap))
+ enumerator->destroy(enumerator);
+ if (this->peer_cfg)
{
- case NEED_MORE:
- this->eap_payload = eap;
- return NEED_MORE;
- case SUCCESS:
- /* EAP exchange completed, now create and process AUTH */
- this->eap_payload = NULL;
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
- return NEED_MORE;
- default:
- this->eap_payload = NULL;
- DBG0(DBG_IKE, "failed to authenticate against '%D' using EAP",
- this->ike_sa->get_other_id(this->ike_sa));
- return FAILED;
+ DBG1(DBG_CFG, "selected peer config '%s'",
+ this->peer_cfg->get_name(this->peer_cfg));
+ return TRUE;
}
+ DBG1(DBG_CFG, "no matching peer config found");
+ return FALSE;
}
/**
- * Implementation of task_t.process for EAP exchanges
- */
-static status_t process_eap_r(private_ike_auth_t *this, message_t *message)
-{
- this->eap_payload = (eap_payload_t*)message->get_payload(message,
- EXTENSIBLE_AUTHENTICATION);
- return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for EAP exchanges
- */
-static status_t build_eap_i(private_ike_auth_t *this, message_t *message)
-{
- message->add_payload(message, (payload_t*)this->eap_payload);
- return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for EAP exchanges
+ * update the current peer candidate if necessary, using candidates
*/
-static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
+static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
{
- status_t status = NEED_MORE;
- eap_payload_t *eap;
-
- if (this->eap_payload == NULL)
- {
- DBG1(DBG_IKE, "EAP payload missing");
- return FAILED;
- }
-
- switch (this->eap_auth->process(this->eap_auth, this->eap_payload, &eap))
+ do
{
- case NEED_MORE:
+ if (this->peer_cfg)
+ {
+ bool complies = TRUE;
+ enumerator_t *e1, *e2, *tmp;
+ auth_cfg_t *c1, *c2;
- break;
- case SUCCESS:
- /* EAP exchange completed, now create and process AUTH */
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
- break;
- default:
- DBG0(DBG_IKE, "authentication of '%D' with %N failed",
- this->ike_sa->get_other_id(this->ike_sa),
- auth_class_names, AUTH_CLASS_EAP);
- status = FAILED;
- break;
+ e1 = this->other_cfgs->create_enumerator(this->other_cfgs);
+ e2 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
+
+ if (strict)
+ { /* swap lists in strict mode: all configured rounds must be
+ * fulfilled. If !strict, we check only the rounds done so far. */
+ tmp = e1;
+ e1 = e2;
+ e2 = tmp;
+ }
+ while (e1->enumerate(e1, &c1))
+ {
+ /* check if done authentications comply to configured ones */
+ if ((!e2->enumerate(e2, &c2)) ||
+ (!strict && !c1->complies(c1, c2, TRUE)) ||
+ (strict && !c2->complies(c2, c1, TRUE)))
+ {
+ complies = FALSE;
+ break;
+ }
+ }
+ e1->destroy(e1);
+ e2->destroy(e2);
+ if (complies)
+ {
+ break;
+ }
+ DBG1(DBG_CFG, "selected peer config '%s' inacceptable",
+ this->peer_cfg->get_name(this->peer_cfg));
+ this->peer_cfg->destroy(this->peer_cfg);
+ }
+ if (this->candidates->remove_first(this->candidates,
+ (void**)&this->peer_cfg) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "no alternative config found");
+ this->peer_cfg = NULL;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "switching to peer config '%s'",
+ this->peer_cfg->get_name(this->peer_cfg));
+ this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
+ }
}
- message->add_payload(message, (payload_t*)eap);
- return status;
+ while (this->peer_cfg);
+
+ return this->peer_cfg != NULL;
}
/**
@@ -507,31 +351,104 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
*/
static status_t build_i(private_ike_auth_t *this, message_t *message)
{
- peer_cfg_t *config;
-
+ auth_cfg_t *cfg;
+
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return collect_my_init_data(this, message);
}
-
- if (build_id(this, message) != SUCCESS)
+
+ if (this->peer_cfg == NULL)
{
- return FAILED;
+ this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+ this->peer_cfg->get_ref(this->peer_cfg);
}
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (get_auth_class(config) == AUTH_CLASS_EAP)
- {
- this->eap_auth = eap_authenticator_create(this->ike_sa);
+ if (message->get_message_id(message) == 1 &&
+ this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
+ { /* in the first IKE_AUTH, indicate support for multiple authentication */
+ message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED, chunk_empty);
}
- else
+
+ if (!this->do_another_auth && !this->my_auth)
+ { /* we have done our rounds */
+ return NEED_MORE;
+ }
+
+ /* check if an authenticator is in progress */
+ if (this->my_auth == NULL)
{
- if (build_auth(this, message) != SUCCESS)
+ identification_t *id;
+ id_payload_t *id_payload;
+
+ /* clean up authentication config from a previous round */
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ cfg->purge(cfg, TRUE);
+
+ /* add (optional) IDr */
+ cfg = get_auth_cfg(this, FALSE);
+ if (cfg)
+ {
+ id = cfg->get(cfg, AUTH_RULE_IDENTITY);
+ if (id && !id->contains_wildcards(id))
+ {
+ this->ike_sa->set_other_id(this->ike_sa, id->clone(id));
+ id_payload = id_payload_create_from_identification(
+ ID_RESPONDER, id);
+ message->add_payload(message, (payload_t*)id_payload);
+ }
+ }
+ /* add IDi */
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
+ id = cfg->get(cfg, AUTH_RULE_IDENTITY);
+ if (!id)
+ {
+ DBG1(DBG_CFG, "configuration misses IDi");
+ return FAILED;
+ }
+ this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
+ id_payload = id_payload_create_from_identification(ID_INITIATOR, id);
+ message->add_payload(message, (payload_t*)id_payload);
+
+ /* build authentication data */
+ this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
+ this->other_nonce, this->my_nonce,
+ this->other_packet->get_data(this->other_packet),
+ this->my_packet->get_data(this->my_packet));
+ if (!this->my_auth)
{
return FAILED;
}
}
-
+ switch (this->my_auth->build(this->my_auth, message))
+ {
+ case SUCCESS:
+ /* authentication step complete, reset authenticator */
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE), TRUE);
+ this->my_cfgs->insert_last(this->my_cfgs, cfg);
+ this->my_auth->destroy(this->my_auth);
+ this->my_auth = NULL;
+ break;
+ case NEED_MORE:
+ break;
+ default:
+ return FAILED;
+ }
+
+ /* check for additional authentication rounds */
+ if (do_another_auth(this))
+ {
+ if (message->get_payload(message, AUTHENTICATION))
+ {
+ message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
+ }
+ }
+ else
+ {
+ this->do_another_auth = FALSE;
+ }
return NEED_MORE;
}
@@ -540,45 +457,136 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
*/
static status_t process_r(private_ike_auth_t *this, message_t *message)
{
- peer_cfg_t *config;
+ auth_cfg_t *cfg, *cand;
+ id_payload_t *id_payload;
+ identification_t *id;
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return collect_other_init_data(this, message);
}
- if (process_id(this, message) != SUCCESS)
+ if (this->my_auth == NULL && this->do_another_auth)
+ {
+ /* handle (optional) IDr payload, apply proposed identity */
+ id_payload = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
+ if (id_payload)
+ {
+ id = id_payload->get_identification(id_payload);
+ }
+ else
+ {
+ id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
+ this->ike_sa->set_my_id(this->ike_sa, id);
+ }
+
+ if (!this->expect_another_auth)
{
return NEED_MORE;
}
+ if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED))
+ {
+ this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
+ }
- switch (process_auth(this, message))
+ if (this->other_auth == NULL)
+ {
+ /* handle IDi payload */
+ id_payload = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
+ if (!id_payload)
+ {
+ DBG1(DBG_IKE, "IDi payload missing");
+ return FAILED;
+ }
+ id = id_payload->get_identification(id_payload);
+ this->ike_sa->set_other_id(this->ike_sa, id);
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
+
+ if (this->peer_cfg == NULL)
+ {
+ if (!load_cfg_candidates(this))
+ {
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
+ }
+ }
+ if (message->get_payload(message, AUTHENTICATION) == NULL)
+ { /* before authenticating with EAP, we need a EAP config */
+ cand = get_auth_cfg(this, FALSE);
+ while (!cand || (
+ (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
+ (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
+ { /* peer requested EAP, but current config does not match */
+ this->peer_cfg->destroy(this->peer_cfg);
+ this->peer_cfg = NULL;
+ if (!update_cfg_candidates(this, FALSE))
+ {
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
+ }
+ cand = get_auth_cfg(this, FALSE);
+ }
+ cfg->merge(cfg, cand, TRUE);
+ }
+
+ /* verify authentication data */
+ this->other_auth = authenticator_create_verifier(this->ike_sa,
+ message, this->other_nonce, this->my_nonce,
+ this->other_packet->get_data(this->other_packet),
+ this->my_packet->get_data(this->my_packet));
+ if (!this->other_auth)
+ {
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
+ }
+ }
+ switch (this->other_auth->process(this->other_auth, message))
{
case SUCCESS:
- this->peer_authenticated = TRUE;
- break;
- case NOT_FOUND:
- /* use EAP if no AUTH payload found */
- this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
+ this->other_auth->destroy(this->other_auth);
+ this->other_auth = NULL;
break;
+ case NEED_MORE:
+ if (message->get_payload(message, AUTHENTICATION))
+ { /* AUTH verification successful, but another build() needed */
+ break;
+ }
+ return NEED_MORE;
default:
+ this->authentication_failed = TRUE;
return NEED_MORE;
}
-
- config = charon->backends->get_peer_cfg(charon->backends,
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_other_auth(this->ike_sa));
- if (config)
+
+ /* store authentication information */
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+ this->other_cfgs->insert_last(this->other_cfgs, cfg);
+
+ /* another auth round done, invoke authorize hook */
+ if (!charon->bus->authorize(charon->bus, this->other_cfgs, FALSE))
{
- this->ike_sa->set_peer_cfg(this->ike_sa, config);
- config->destroy(config);
+ DBG1(DBG_IKE, "round %d authorization hook forbids IKE_SA, cancelling",
+ this->other_cfgs->get_count(this->other_cfgs));
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
}
- if (!this->peer_authenticated)
- {
- this->eap_auth = eap_authenticator_create(this->ike_sa);
+
+ if (!update_cfg_candidates(this, FALSE))
+ {
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
+ }
+
+ if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
+ {
+ this->expect_another_auth = FALSE;
+ if (!update_cfg_candidates(this, TRUE))
+ {
+ this->authentication_failed = TRUE;
+ return NEED_MORE;
+ }
}
return NEED_MORE;
}
@@ -588,54 +596,142 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
*/
static status_t build_r(private_ike_auth_t *this, message_t *message)
{
- peer_cfg_t *config;
- eap_type_t eap_type;
- u_int32_t eap_vendor;
- eap_payload_t *eap_payload;
- status_t status;
-
+ auth_cfg_t *cfg;
+
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
+ if (multiple_auth_enabled())
+ {
+ message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
+ chunk_empty);
+ }
return collect_my_init_data(this, message);
}
- if (!this->peer_authenticated && this->eap_auth == NULL)
+ if (this->authentication_failed || this->peer_cfg == NULL)
{
- /* peer not authenticated, nor does it want to use EAP */
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (config == NULL)
+ if (this->my_auth == NULL && this->do_another_auth)
{
- DBG1(DBG_IKE, "no matching config found for '%D'...'%D'",
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
+ identification_t *id, *id_cfg;
+ id_payload_t *id_payload;
+
+ /* add IDr */
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+ cfg->purge(cfg, TRUE);
+ cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
+
+ id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
+ id = this->ike_sa->get_my_id(this->ike_sa);
+ if (id->get_type(id) == ID_ANY)
+ { /* no IDr received, apply configured ID */
+ if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
+ {
+ DBG1(DBG_CFG, "IDr not configured and negotiation failed");
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ return FAILED;
+ }
+ this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
+ id = id_cfg;
+ }
+ else
+ { /* IDr received, check if it matches configuration */
+ if (id_cfg && !id->matches(id, id_cfg))
+ {
+ DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ return FAILED;
+ }
+ }
+
+ id_payload = id_payload_create_from_identification(ID_RESPONDER, id);
+ message->add_payload(message, (payload_t*)id_payload);
+
+ /* build authentication data */
+ this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
+ this->other_nonce, this->my_nonce,
+ this->other_packet->get_data(this->other_packet),
+ this->my_packet->get_data(this->my_packet));
+ if (!this->my_auth)
+ {
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+ return FAILED;
+ }
}
- if (build_id(this, message) != SUCCESS ||
- build_auth(this, message) != SUCCESS)
+ if (this->other_auth)
{
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
+ switch (this->other_auth->build(this->other_auth, message))
+ {
+ case SUCCESS:
+ this->other_auth->destroy(this->other_auth);
+ this->other_auth = NULL;
+ break;
+ case NEED_MORE:
+ break;
+ default:
+ if (!message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
+ { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ }
+ return FAILED;
+ }
}
-
- if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
- this->ike_sa))
+ if (this->my_auth)
{
- DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
+ switch (this->my_auth->build(this->my_auth, message))
+ {
+ case SUCCESS:
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE),
+ TRUE);
+ this->my_cfgs->insert_last(this->my_cfgs, cfg);
+ this->my_auth->destroy(this->my_auth);
+ this->my_auth = NULL;
+ break;
+ case NEED_MORE:
+ break;
+ default:
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ return FAILED;
+ }
}
- /* use "traditional" authentication if we could authenticate peer */
- if (this->peer_authenticated)
+ /* check for additional authentication rounds */
+ if (do_another_auth(this))
+ {
+ message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
+ }
+ else
+ {
+ this->do_another_auth = FALSE;
+ }
+ if (!this->do_another_auth && !this->expect_another_auth)
{
+ if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
+ this->ike_sa))
+ {
+ DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ return FAILED;
+ }
+ if (!charon->bus->authorize(charon->bus, this->other_cfgs, TRUE))
+ {
+ DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+ return FAILED;
+ }
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
+ DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
this->ike_sa->get_name(this->ike_sa),
this->ike_sa->get_unique_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
@@ -644,21 +740,6 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
this->ike_sa->get_other_id(this->ike_sa));
return SUCCESS;
}
-
- /* initiate EAP authenitcation */
- eap_type = get_eap_type(config, &eap_vendor);
- status = this->eap_auth->initiate(this->eap_auth, eap_type,
- eap_vendor, &eap_payload);
- message->add_payload(message, (payload_t*)eap_payload);
- if (status != NEED_MORE)
- {
- DBG1(DBG_IKE, "unable to initiate EAP authentication");
- return FAILED;
- }
-
- /* switch to EAP methods */
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_r;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_r;
return NEED_MORE;
}
@@ -667,18 +748,22 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
*/
static status_t process_i(private_ike_auth_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
- peer_cfg_t *config;
- auth_info_t *auth;
+ auth_cfg_t *cfg;
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
+ if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
+ multiple_auth_enabled())
+ {
+ this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
+ }
return collect_other_init_data(this, message);
}
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -714,7 +799,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return FAILED;
}
DBG2(DBG_IKE, "received %N notify",
@@ -724,39 +809,116 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
- if (process_id(this, message) != SUCCESS ||
- process_auth(this, message) != SUCCESS)
+ if (this->my_auth)
{
- return FAILED;
+ switch (this->my_auth->process(this->my_auth, message))
+ {
+ case SUCCESS:
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE),
+ TRUE);
+ this->my_cfgs->insert_last(this->my_cfgs, cfg);
+ this->my_auth->destroy(this->my_auth);
+ this->my_auth = NULL;
+ this->do_another_auth = do_another_auth(this);
+ break;
+ case NEED_MORE:
+ break;
+ default:
+ return FAILED;
+ }
}
- if (this->eap_auth)
+ if (this->expect_another_auth)
{
- /* switch to EAP authentication methods */
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_i;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_i;
- return process_eap_i(this, message);
+ if (this->other_auth == NULL)
+ {
+ id_payload_t *id_payload;
+ identification_t *id;
+
+ /* responder is not allowed to do EAP */
+ if (!message->get_payload(message, AUTHENTICATION))
+ {
+ DBG1(DBG_IKE, "AUTH payload missing");
+ return FAILED;
+ }
+
+ /* handle IDr payload */
+ id_payload = (id_payload_t*)message->get_payload(message,
+ ID_RESPONDER);
+ if (!id_payload)
+ {
+ DBG1(DBG_IKE, "IDr payload missing");
+ return FAILED;
+ }
+ id = id_payload->get_identification(id_payload);
+ this->ike_sa->set_other_id(this->ike_sa, id);
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+ cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
+
+ /* verify authentication data */
+ this->other_auth = authenticator_create_verifier(this->ike_sa,
+ message, this->other_nonce, this->my_nonce,
+ this->other_packet->get_data(this->other_packet),
+ this->my_packet->get_data(this->my_packet));
+ if (!this->other_auth)
+ {
+ return FAILED;
+ }
+ }
+ switch (this->other_auth->process(this->other_auth, message))
+ {
+ case SUCCESS:
+ break;
+ case NEED_MORE:
+ return NEED_MORE;
+ default:
+ return FAILED;
+ }
+ /* store authentication information, reset authenticator */
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+ this->other_cfgs->insert_last(this->other_cfgs, cfg);
+ this->other_auth->destroy(this->other_auth);
+ this->other_auth = NULL;
+
+ /* another auth round done, invoke authorize hook */
+ if (!charon->bus->authorize(charon->bus, this->other_cfgs, FALSE))
+ {
+ DBG1(DBG_IKE, "round %d authorization forbids IKE_SA, cancelling",
+ this->other_cfgs->get_count(this->other_cfgs));
+ return FAILED;
+ }
}
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- auth = this->ike_sa->get_other_auth(this->ike_sa);
- if (!auth->complies(auth, config->get_auth(config)))
+ if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
{
- DBG0(DBG_IKE, "authorization of '%D' for config %s failed",
- this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
- return FAILED;
+ this->expect_another_auth = FALSE;
}
- this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
- this->ike_sa->get_name(this->ike_sa),
- this->ike_sa->get_unique_id(this->ike_sa),
- this->ike_sa->get_my_host(this->ike_sa),
- this->ike_sa->get_my_id(this->ike_sa),
- this->ike_sa->get_other_host(this->ike_sa),
- this->ike_sa->get_other_id(this->ike_sa));
- return SUCCESS;
+ if (!this->expect_another_auth && !this->do_another_auth && !this->my_auth)
+ {
+ if (!update_cfg_candidates(this, TRUE))
+ {
+ return FAILED;
+ }
+ if (!charon->bus->authorize(charon->bus, this->other_cfgs, TRUE))
+ {
+ DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
+ return FAILED;
+ }
+ this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
+ DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
+ this->ike_sa->get_name(this->ike_sa),
+ this->ike_sa->get_unique_id(this->ike_sa),
+ this->ike_sa->get_my_host(this->ike_sa),
+ this->ike_sa->get_my_id(this->ike_sa),
+ this->ike_sa->get_other_host(this->ike_sa),
+ this->ike_sa->get_other_id(this->ike_sa));
+ return SUCCESS;
+ }
+ return NEED_MORE;
}
/**
@@ -776,28 +938,25 @@ static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
chunk_free(&this->other_nonce);
DESTROY_IF(this->my_packet);
DESTROY_IF(this->other_packet);
- if (this->eap_auth)
- {
- this->eap_auth->authenticator_interface.destroy(
- &this->eap_auth->authenticator_interface);
- }
+ DESTROY_IF(this->peer_cfg);
+ DESTROY_IF(this->my_auth);
+ DESTROY_IF(this->other_auth);
+ this->my_cfgs->destroy_offset(this->my_cfgs, offsetof(auth_cfg_t, destroy));
+ this->other_cfgs->destroy_offset(this->other_cfgs, offsetof(auth_cfg_t, destroy));
+ this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
this->my_packet = NULL;
this->other_packet = NULL;
- this->peer_authenticated = FALSE;
- this->eap_auth = NULL;
- this->eap_payload = NULL;
this->ike_sa = ike_sa;
- if (this->initiator)
- {
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
- }
- else
- {
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
- }
+ this->peer_cfg = NULL;
+ this->my_auth = NULL;
+ this->other_auth = NULL;
+ this->do_another_auth = TRUE;
+ this->expect_another_auth = TRUE;
+ this->authentication_failed = FALSE;
+ this->my_cfgs = linked_list_create();
+ this->other_cfgs = linked_list_create();
+ this->candidates = linked_list_create();
}
/**
@@ -809,11 +968,12 @@ static void destroy(private_ike_auth_t *this)
chunk_free(&this->other_nonce);
DESTROY_IF(this->my_packet);
DESTROY_IF(this->other_packet);
- if (this->eap_auth)
- {
- this->eap_auth->authenticator_interface.destroy(
- &this->eap_auth->authenticator_interface);
- }
+ DESTROY_IF(this->my_auth);
+ DESTROY_IF(this->other_auth);
+ DESTROY_IF(this->peer_cfg);
+ this->my_cfgs->destroy_offset(this->my_cfgs, offsetof(auth_cfg_t, destroy));
+ this->other_cfgs->destroy_offset(this->other_cfgs, offsetof(auth_cfg_t, destroy));
+ this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
free(this);
}
@@ -823,7 +983,7 @@ static void destroy(private_ike_auth_t *this)
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
{
private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
-
+
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
@@ -845,9 +1005,16 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
this->other_nonce = chunk_empty;
this->my_packet = NULL;
this->other_packet = NULL;
- this->peer_authenticated = FALSE;
- this->eap_auth = NULL;
- this->eap_payload = NULL;
+ this->peer_cfg = NULL;
+ this->my_cfgs = linked_list_create();
+ this->other_cfgs = linked_list_create();
+ this->candidates = linked_list_create();
+ this->my_auth = NULL;
+ this->other_auth = NULL;
+ this->do_another_auth = TRUE;
+ this->expect_another_auth = TRUE;
+ this->authentication_failed = FALSE;
return &this->public;
}
+
diff --git a/src/charon/sa/tasks/ike_auth.h b/src/charon/sa/tasks/ike_auth.h
index a4719ec24..bba46d961 100644
--- a/src/charon/sa/tasks/ike_auth.h
+++ b/src/charon/sa/tasks/ike_auth.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_auth.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.c b/src/charon/sa/tasks/ike_auth_lifetime.c
index cb17cc2dc..a047e6b81 100644
--- a/src/charon/sa/tasks/ike_auth_lifetime.c
+++ b/src/charon/sa/tasks/ike_auth_lifetime.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_auth_lifetime.c 4576 2008-11-05 08:32:38Z martin $
*/
#include "ike_auth_lifetime.h"
@@ -64,12 +62,12 @@ static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *mess
*/
static void process_payloads(private_ike_auth_lifetime_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
notify_payload_t *notify;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -88,7 +86,7 @@ static void process_payloads(private_ike_auth_lifetime_t *this, message_t *messa
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.h b/src/charon/sa/tasks/ike_auth_lifetime.h
index 46595e6ed..812caaf43 100644
--- a/src/charon/sa/tasks/ike_auth_lifetime.h
+++ b/src/charon/sa/tasks/ike_auth_lifetime.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_auth_lifetime.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_cert_post.c b/src/charon/sa/tasks/ike_cert_post.c
index cb533236e..70e87c2e7 100644
--- a/src/charon/sa/tasks/ike_cert_post.c
+++ b/src/charon/sa/tasks/ike_cert_post.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cert_post.c 4276 2008-08-22 10:44:51Z martin $
*/
#include "ike_cert_post.h"
@@ -22,6 +20,7 @@
#include <sa/ike_sa.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/certreq_payload.h>
+#include <encoding/payloads/auth_payload.h>
#include <credentials/certificates/x509.h>
@@ -98,70 +97,71 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certifi
}
/**
- * from ike_auth.c
- */
-auth_class_t get_auth_class(peer_cfg_t *config);
-
-/**
* add certificates to message
*/
static void build_certs(private_ike_cert_post_t *this, message_t *message)
{
peer_cfg_t *peer_cfg;
+ auth_payload_t *payload;
+ payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
- if (peer_cfg && get_auth_class(peer_cfg) == AUTH_CLASS_PUBKEY)
+ if (!peer_cfg || !payload || payload->get_auth_method(payload) == AUTH_PSK)
+ { /* no CERT payload for EAP/PSK */
+ return;
+ }
+
+ switch (peer_cfg->get_cert_policy(peer_cfg))
{
- switch (peer_cfg->get_cert_policy(peer_cfg))
+ case CERT_NEVER_SEND:
+ break;
+ case CERT_SEND_IF_ASKED:
+ if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
+ {
+ break;
+ }
+ /* FALL */
+ case CERT_ALWAYS_SEND:
{
- case CERT_NEVER_SEND:
+ cert_payload_t *payload;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ auth_rule_t type;
+ auth_cfg_t *auth;
+
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+
+ /* get subject cert first, then issuing certificates */
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (!cert)
+ {
break;
- case CERT_SEND_IF_ASKED:
- if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
- {
- break;
- }
- /* FALL */
- case CERT_ALWAYS_SEND:
+ }
+ payload = build_cert_payload(this, cert);
+ if (!payload)
{
- cert_payload_t *payload;
- enumerator_t *enumerator;
- certificate_t *cert;
- auth_info_t *auth;
- auth_item_t item;
-
- auth = this->ike_sa->get_my_auth(this->ike_sa);
- /* get subject cert first, then issuing certificates */
- if (!auth->get_item(auth, AUTHZ_SUBJECT_CERT, (void**)&cert))
- {
- break;
- }
- payload = build_cert_payload(this, cert);
- if (!payload)
- {
- break;
- }
- DBG1(DBG_IKE, "sending end entity cert \"%D\"",
- cert->get_subject(cert));
- message->add_payload(message, (payload_t*)payload);
-
- enumerator = auth->create_item_enumerator(auth);
- while (enumerator->enumerate(enumerator, &item, &cert))
+ break;
+ }
+ DBG1(DBG_IKE, "sending end entity cert \"%Y\"",
+ cert->get_subject(cert));
+ message->add_payload(message, (payload_t*)payload);
+
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &type, &cert))
+ {
+ if (type == AUTH_RULE_IM_CERT)
{
- if (item == AUTHZ_IM_CERT)
+ payload = cert_payload_create_from_cert(cert);
+ if (payload)
{
- payload = cert_payload_create_from_cert(cert);
- if (payload)
- {
- DBG1(DBG_IKE, "sending issuer cert \"%D\"",
- cert->get_subject(cert));
- message->add_payload(message, (payload_t*)payload);
- }
+ DBG1(DBG_IKE, "sending issuer cert \"%Y\"",
+ cert->get_subject(cert));
+ message->add_payload(message, (payload_t*)payload);
}
}
- enumerator->destroy(enumerator);
- }
- }
+ }
+ enumerator->destroy(enumerator);
+ }
}
}
@@ -170,12 +170,9 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message)
*/
static status_t build_i(private_ike_cert_post_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- return NEED_MORE;
- }
build_certs(this, message);
- return SUCCESS;
+
+ return NEED_MORE;
}
/**
@@ -191,11 +188,12 @@ static status_t process_r(private_ike_cert_post_t *this, message_t *message)
*/
static status_t build_r(private_ike_cert_post_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
+ build_certs(this, message);
+
+ if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+ { /* stay alive, we might have additional rounds with certs */
return NEED_MORE;
}
- build_certs(this, message);
return SUCCESS;
}
@@ -204,8 +202,8 @@ static status_t build_r(private_ike_cert_post_t *this, message_t *message)
*/
static status_t process_i(private_ike_cert_post_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
+ if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+ { /* stay alive, we might have additional rounds with CERTS */
return NEED_MORE;
}
return SUCCESS;
diff --git a/src/charon/sa/tasks/ike_cert_post.h b/src/charon/sa/tasks/ike_cert_post.h
index ec9d172e1..fa555eac7 100644
--- a/src/charon/sa/tasks/ike_cert_post.h
+++ b/src/charon/sa/tasks/ike_cert_post.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cert_post.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_cert_pre.c b/src/charon/sa/tasks/ike_cert_pre.c
index 353b76a22..1c72f289f 100644
--- a/src/charon/sa/tasks/ike_cert_pre.c
+++ b/src/charon/sa/tasks/ike_cert_pre.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2007 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cert_pre.c 4285 2008-08-26 05:15:34Z andreas $
*/
#include "ike_cert_pre.h"
@@ -48,9 +46,14 @@ struct private_ike_cert_pre_t {
bool initiator;
/**
- * Did we send a HTTP_CERT_LOOKUP_SUPPORTED Notify?
+ * Do we accept HTTP certificate lookup requests
+ */
+ bool do_http_lookup;
+
+ /**
+ * wheter this is the final authentication round
*/
- bool http_cert_lookup_supported_sent;
+ bool final;
};
/**
@@ -58,23 +61,22 @@ struct private_ike_cert_pre_t {
*/
static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
- auth_info_t *auth;
- bool ca_found = FALSE;
+ auth_cfg_t *auth;
- auth = this->ike_sa->get_my_auth(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
switch(payload->get_type(payload))
{
case CERTIFICATE_REQUEST:
{
certreq_payload_t *certreq = (certreq_payload_t*)payload;
- chunk_t keyid;
enumerator_t *enumerator;
+ chunk_t keyid;
this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
@@ -96,17 +98,14 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
CERT_X509, KEY_ANY, id, TRUE);
if (cert)
{
- DBG1(DBG_IKE, "received cert request for \"%D\"",
+ DBG1(DBG_IKE, "received cert request for \"%Y\"",
cert->get_subject(cert));
- auth->add_item(auth, AUTHN_CA_CERT, cert);
- cert->destroy(cert);
- ca_found = TRUE;
+ auth->add(auth, AUTH_RULE_CA_CERT, cert);
}
else
{
DBG1(DBG_IKE, "received cert request for unknown ca "
- "with keyid %D", id);
- auth->add_item(auth, AUTHN_CA_CERT_KEYID, id);
+ "with keyid %Y", id);
}
id->destroy(id);
}
@@ -129,7 +128,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -140,6 +139,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
static certificate_t *try_get_cert(cert_payload_t *cert_payload)
{
certificate_t *cert = NULL;
+
switch (cert_payload->get_cert_encoding(cert_payload))
{
case ENC_X509_SIGNATURE:
@@ -158,7 +158,7 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
}
id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
cert = charon->credentials->get_cert(charon->credentials,
- CERT_X509, KEY_ANY, id, FALSE);
+ CERT_X509, KEY_ANY, id, FALSE);
id->destroy(id);
break;
}
@@ -175,78 +175,81 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
*/
static void process_certs(private_ike_cert_pre_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
- auth_info_t *auth;
+ auth_cfg_t *auth;
bool first = TRUE;
- auth = this->ike_sa->get_other_auth(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == CERTIFICATE)
{
- cert_payload_t *cert_payload = (cert_payload_t*)payload;
- cert_encoding_t type = cert_payload->get_cert_encoding(cert_payload);
- switch (type)
+ cert_payload_t *cert_payload;
+ cert_encoding_t encoding;
+ certificate_t *cert;
+ char *url;
+
+ cert_payload = (cert_payload_t*)payload;
+ encoding = cert_payload->get_cert_encoding(cert_payload);
+
+ switch (encoding)
{
- case ENC_X509_SIGNATURE:
case ENC_X509_HASH_AND_URL:
{
- if (type == ENC_X509_HASH_AND_URL &&
- !this->http_cert_lookup_supported_sent)
+ if (!this->do_http_lookup)
{
DBG1(DBG_IKE, "received hash-and-url encoded cert, but"
" we don't accept them, ignore");
break;
}
-
- certificate_t *cert = try_get_cert(cert_payload);
-
+ /* FALL */
+ }
+ case ENC_X509_SIGNATURE:
+ {
+ cert = try_get_cert(cert_payload);
if (cert)
{
- /* we've got a certificate from the payload or the cache */
if (first)
- { /* the first certificate MUST be an end entity one */
- DBG1(DBG_IKE, "received end entity cert \"%D\"",
+ { /* the first is an end entity certificate */
+ DBG1(DBG_IKE, "received end entity cert \"%Y\"",
cert->get_subject(cert));
- auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
+ auth->add(auth, AUTH_HELPER_SUBJECT_CERT, cert);
first = FALSE;
}
else
{
- DBG1(DBG_IKE, "received issuer cert \"%D\"",
+ DBG1(DBG_IKE, "received issuer cert \"%Y\"",
cert->get_subject(cert));
- auth->add_item(auth, AUTHN_IM_CERT, cert);
+ auth->add(auth, AUTH_HELPER_IM_CERT, cert);
}
- cert->destroy(cert);
}
- else if (type == ENC_X509_HASH_AND_URL)
+ else if (encoding == ENC_X509_HASH_AND_URL)
{
- /* we received a "Hash and URL" encoded certificate that
- * we haven't fetched yet, we store the URL and fetch
- * it later */
- char *url = cert_payload->get_url(cert_payload);
+ /* we fetch the certificate not yet, but only if
+ * it is really needed during authentication */
+ url = cert_payload->get_url(cert_payload);
if (!url)
{
- DBG1(DBG_IKE, "received invalid hash-and-url encoded"
- " cert, ignore");
+ DBG1(DBG_IKE, "received invalid hash-and-url "
+ "encoded cert, ignore");
break;
}
-
+ url = strdup(url);
if (first)
- { /* the first certificate MUST be an end entity one */
+ { /* first URL is for an end entity certificate */
DBG1(DBG_IKE, "received hash-and-url for end"
- " entity cert \"%s\"", url);
- auth->add_item(auth, AUTHN_SUBJECT_HASH_URL, url);
+ " entity cert \"%s\"", url);
+ auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
first = FALSE;
}
else
{
DBG1(DBG_IKE, "received hash-and-url for issuer"
" cert \"%s\"", url);
- auth->add_item(auth, AUTHN_IM_HASH_URL, url);
+ auth->add(auth, AUTH_HELPER_IM_HASH_URL, url);
}
}
break;
@@ -264,31 +267,23 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message)
case ENC_OCSP_CONTENT:
default:
DBG1(DBG_ENC, "certificate encoding %N not supported",
- cert_encoding_names, cert_payload->get_cert_encoding(cert_payload));
+ cert_encoding_names, encoding);
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
- * add a certificate request to the message, building request payload if required.
+ * add the keyid of a certificate to the certificate request payload
*/
-static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
- certificate_t *cert)
+static void add_certreq(certreq_payload_t **req, certificate_t *cert)
{
- public_key_t *public;
- certreq_payload_t *req;
-
- public = cert->get_public_key(cert);
- if (!public)
- {
- return;
- }
switch (cert->get_type(cert))
{
case CERT_X509:
{
+ public_key_t *public;
identification_t *keyid;
x509_t *x509 = (x509_t*)cert;
@@ -296,22 +291,49 @@ static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
{ /* no CA cert, skip */
break;
}
- if (*reqp == NULL)
+ public = cert->get_public_key(cert);
+ if (!public)
{
- *reqp = certreq_payload_create_type(CERT_X509);
- message->add_payload(message, (payload_t*)*reqp);
+ break;
+ }
+ if (*req == NULL)
+ {
+ *req = certreq_payload_create_type(CERT_X509);
}
- req = *reqp;
keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
- req->add_keyid(req, keyid->get_encoding(keyid));
- DBG1(DBG_IKE, "sending cert request for \"%D\"",
+ (*req)->add_keyid(*req, keyid->get_encoding(keyid));
+ public->destroy(public);
+ DBG1(DBG_IKE, "sending cert request for \"%Y\"",
cert->get_subject(cert));
break;
}
default:
break;
}
- public->destroy(public);
+}
+
+/**
+ * add a auth_cfg's CA certificates to the certificate request
+ */
+static void add_certreqs(certreq_payload_t **req, auth_cfg_t *auth)
+{
+ enumerator_t *enumerator;
+ auth_rule_t type;
+ void *value;
+
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ switch (type)
+ {
+ case AUTH_RULE_CA_CERT:
+ add_certreq(req, (certificate_t*)value);
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
}
/**
@@ -319,88 +341,96 @@ static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
*/
static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
{
+ enumerator_t *enumerator;
ike_cfg_t *ike_cfg;
peer_cfg_t *peer_cfg;
- enumerator_t *enumerator;
certificate_t *cert;
- bool restricted = FALSE;
- certreq_payload_t *x509_req = NULL;
+ auth_cfg_t *auth;
+ certreq_payload_t *req = NULL;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
if (!ike_cfg->send_certreq(ike_cfg))
{
return;
}
-
+
/* check if we require a specific CA for that peer */
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg)
{
- void *ptr;
- identification_t *id;
- auth_item_t item;
- auth_info_t *auth = peer_cfg->get_auth(peer_cfg);
- enumerator_t *auth_enumerator = auth->create_item_enumerator(auth);
-
- while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
+ enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
+ while (enumerator->enumerate(enumerator, &auth))
{
- switch (item)
- {
- case AUTHZ_CA_CERT:
- cert = (certificate_t *)ptr;
- add_certreq_payload(message, &x509_req, cert);
- restricted = TRUE;
- break;
- case AUTHZ_CA_CERT_NAME:
- id = (identification_t *)ptr;
- enumerator = charon->credentials->create_cert_enumerator(
- charon->credentials, CERT_ANY, KEY_ANY, id, TRUE);
- while (enumerator->enumerate(enumerator, &cert, TRUE))
- {
- add_certreq_payload(message, &x509_req, cert);
- restricted = TRUE;
- }
- enumerator->destroy(enumerator);
- break;
- default:
- break;
- }
+ add_certreqs(&req, auth);
}
- auth_enumerator->destroy(auth_enumerator);
+ enumerator->destroy(enumerator);
}
-
- if (!restricted)
+
+ if (!req)
{
- /* otherwise include all trusted CA certificates */
+ /* otherwise add all trusted CA certificates */
enumerator = charon->credentials->create_cert_enumerator(
charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
- while (enumerator->enumerate(enumerator, &cert, TRUE))
+ while (enumerator->enumerate(enumerator, &cert))
{
- add_certreq_payload(message, &x509_req, cert);
+ add_certreq(&req, cert);
}
enumerator->destroy(enumerator);
}
- /* if we've added at least one certreq, we notify our peer that we support
- * "Hash and URL" for the requested certificates */
- if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE) &&
- message->get_payload(message, CERTIFICATE_REQUEST))
+ if (req)
{
- message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED, chunk_empty);
- this->http_cert_lookup_supported_sent = TRUE;
+ message->add_payload(message, (payload_t*)req);
+
+ if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE))
+ {
+ message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
+ chunk_empty);
+ this->do_http_lookup = TRUE;
+ }
}
}
/**
+ * Check if this is the final authentication round
+ */
+static bool final_auth(message_t *message)
+{
+ enumerator_t *enumerator;
+ payload_t *payload;
+ notify_payload_t *notify;
+
+ /* we check for an AUTH payload without a ANOTHER_AUTH_FOLLOWS notify */
+ if (message->get_payload(message, AUTHENTICATION) == NULL)
+ {
+ return FALSE;
+ }
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ if (notify->get_notify_type(notify) == ANOTHER_AUTH_FOLLOWS)
+ {
+ enumerator->destroy(enumerator);
+ return FALSE;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return TRUE;
+}
+
+/**
* Implementation of task_t.process for initiator
*/
static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- return NEED_MORE;
+ if (message->get_message_id(message) == 1)
+ { /* initiator sends CERTREQs in first IKE_AUTH */
+ build_certreqs(this, message);
}
- build_certreqs(this, message);
return NEED_MORE;
}
@@ -408,13 +438,13 @@ static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
* Implementation of task_t.process for responder
*/
static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
-{
- if (message->get_exchange_type(message) == IKE_SA_INIT)
- {
- return NEED_MORE;
+{
+ if (message->get_exchange_type(message) != IKE_SA_INIT)
+ { /* handle certreqs/certs in any IKE_AUTH, just in case */
+ process_certreqs(this, message);
+ process_certs(this, message);
}
- process_certreqs(this, message);
- process_certs(this, message);
+ this->final = final_auth(message);
return NEED_MORE;
}
@@ -426,9 +456,12 @@ static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
build_certreqs(this, message);
- return NEED_MORE;
}
- return SUCCESS;
+ if (this->final)
+ {
+ return SUCCESS;
+ }
+ return NEED_MORE;
}
/**
@@ -439,10 +472,14 @@ static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
process_certreqs(this, message);
- return NEED_MORE;
}
process_certs(this, message);
- return SUCCESS;
+
+ if (final_auth(message))
+ {
+ return SUCCESS;
+ }
+ return NEED_MORE;
}
/**
@@ -493,7 +530,8 @@ ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
this->ike_sa = ike_sa;
this->initiator = initiator;
- this->http_cert_lookup_supported_sent = FALSE;
+ this->do_http_lookup = FALSE;
+ this->final = FALSE;
return &this->public;
}
diff --git a/src/charon/sa/tasks/ike_cert_pre.h b/src/charon/sa/tasks/ike_cert_pre.h
index d6d06b04f..d49005e68 100644
--- a/src/charon/sa/tasks/ike_cert_pre.h
+++ b/src/charon/sa/tasks/ike_cert_pre.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_cert_pre.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_config.c b/src/charon/sa/tasks/ike_config.c
index b890e93ba..1f75521b6 100644
--- a/src/charon/sa/tasks/ike_config.c
+++ b/src/charon/sa/tasks/ike_config.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_config.c 4867 2009-02-13 11:57:50Z andreas $
*/
#include "ike_config.h"
@@ -50,54 +48,34 @@ struct private_ike_config_t {
* virtual ip
*/
host_t *virtual_ip;
-
- /**
- * list of DNS servers
- */
- linked_list_t *dns;
-
- /**
- * list of WINS servers
- */
- linked_list_t *nbns;
};
/**
- * build configuration payloads and attributes
+ * build INTERNAL_IPV4/6_ADDRESS from virtual ip
*/
-static void build_payloads(private_ike_config_t *this, message_t *message,
- config_type_t type)
+static void build_vip(private_ike_config_t *this, host_t *vip, cp_payload_t *cp)
{
- cp_payload_t *cp;
configuration_attribute_t *ca;
chunk_t chunk, prefix;
- if (!this->virtual_ip)
- {
- return;
- }
-
- cp = cp_payload_create();
- cp->set_config_type(cp, type);
-
ca = configuration_attribute_create();
- if (this->virtual_ip->get_family(this->virtual_ip) == AF_INET)
+ if (vip->get_family(vip) == AF_INET)
{
ca->set_type(ca, INTERNAL_IP4_ADDRESS);
- if (this->virtual_ip->is_anyaddr(this->virtual_ip))
+ if (vip->is_anyaddr(vip))
{
chunk = chunk_empty;
}
else
{
- chunk = this->virtual_ip->get_address(this->virtual_ip);
+ chunk = vip->get_address(vip);
}
}
else
{
ca->set_type(ca, INTERNAL_IP6_ADDRESS);
- if (this->virtual_ip->is_anyaddr(this->virtual_ip))
+ if (vip->is_anyaddr(vip))
{
chunk = chunk_empty;
}
@@ -105,71 +83,12 @@ static void build_payloads(private_ike_config_t *this, message_t *message,
{
prefix = chunk_alloca(1);
*prefix.ptr = 64;
- chunk = this->virtual_ip->get_address(this->virtual_ip);
+ chunk = vip->get_address(vip);
chunk = chunk_cata("cc", chunk, prefix);
}
}
ca->set_value(ca, chunk);
cp->add_configuration_attribute(cp, ca);
-
- /* we currently always add a DNS request if we request an IP */
- if (this->initiator)
- {
- ca = configuration_attribute_create();
- if (this->virtual_ip->get_family(this->virtual_ip) == AF_INET)
- {
- ca->set_type(ca, INTERNAL_IP4_DNS);
- }
- else
- {
- ca->set_type(ca, INTERNAL_IP6_DNS);
- }
- cp->add_configuration_attribute(cp, ca);
- }
- else
- {
- host_t *ip;
- iterator_t *iterator;
-
- /* Add internal DNS servers */
- iterator = this->dns->create_iterator(this->dns, TRUE);
- while (iterator->iterate(iterator, (void**)&ip))
- {
- ca = configuration_attribute_create();
- if (ip->get_family(ip) == AF_INET)
- {
- ca->set_type(ca, INTERNAL_IP4_DNS);
- }
- else
- {
- ca->set_type(ca, INTERNAL_IP6_DNS);
- }
- chunk = ip->get_address(ip);
- ca->set_value(ca, chunk);
- cp->add_configuration_attribute(cp, ca);
- }
- iterator->destroy(iterator);
-
- /* Add internal WINS servers */
- iterator = this->nbns->create_iterator(this->nbns, TRUE);
- while (iterator->iterate(iterator, (void**)&ip))
- {
- ca = configuration_attribute_create();
- if (ip->get_family(ip) == AF_INET)
- {
- ca->set_type(ca, INTERNAL_IP4_NBNS);
- }
- else
- {
- ca->set_type(ca, INTERNAL_IP6_NBNS);
- }
- chunk = ip->get_address(ip);
- ca->set_value(ca, chunk);
- cp->add_configuration_attribute(cp, ca);
- }
- iterator->destroy(iterator);
- }
- message->add_payload(message, (payload_t*)cp);
}
/**
@@ -203,55 +122,23 @@ static void process_attribute(private_ike_config_t *this,
}
ip = host_create_from_chunk(family, addr, 0);
}
- if (ip && !this->virtual_ip)
- {
- this->virtual_ip = ip;
- }
- break;
- }
- case INTERNAL_IP4_DNS:
- family = AF_INET;
- /* fall */
- case INTERNAL_IP6_DNS:
- {
- addr = ca->get_value(ca);
- if (addr.len == 0)
- {
- ip = host_create_any(family);
- }
- else
- {
- ip = host_create_from_chunk(family, addr, 0);
- }
if (ip)
{
- this->dns->insert_last(this->dns, ip);
+ DESTROY_IF(this->virtual_ip);
+ this->virtual_ip = ip;
}
break;
}
- case INTERNAL_IP4_NBNS:
- case INTERNAL_IP6_NBNS:
- {
- addr = ca->get_value(ca);
- if (addr.len == 0)
+ default:
+ if (this->initiator)
{
- ip = host_create_any(family);
+ this->ike_sa->add_configuration_attribute(this->ike_sa,
+ ca->get_type(ca), ca->get_value(ca));
}
else
{
- ip = host_create_from_chunk(family, addr, 0);
+ /* we do not handle attribute requests other than for VIPs */
}
- if (ip)
- {
- this->nbns->insert_last(this->nbns, ip);
- }
- break;
- }
- default:
- DBG1(DBG_IKE, "ignoring %N config attribute",
- configuration_attribute_type_names,
- ca->get_type(ca));
- break;
}
}
@@ -260,11 +147,12 @@ static void process_attribute(private_ike_config_t *this,
*/
static void process_payloads(private_ike_config_t *this, message_t *message)
{
- iterator_t *iterator, *attributes;
+ enumerator_t *enumerator;
+ iterator_t *attributes;
payload_t *payload;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == CONFIGURATION)
{
@@ -290,7 +178,7 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -298,9 +186,8 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
*/
static status_t build_i(private_ike_config_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, ID_INITIATOR))
- {
+ if (message->get_message_id(message) == 1)
+ { /* in first IKE_AUTH only */
peer_cfg_t *config;
host_t *vip;
@@ -313,12 +200,28 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
}
if (vip)
{
- this->virtual_ip = vip->clone(vip);
+ configuration_attribute_t *ca;
+ cp_payload_t *cp;
+
+ cp = cp_payload_create();
+ cp->set_config_type(cp, CFG_REQUEST);
+
+ build_vip(this, vip, cp);
+
+ /* we currently always add a DNS request if we request an IP */
+ ca = configuration_attribute_create();
+ if (vip->get_family(vip) == AF_INET)
+ {
+ ca->set_type(ca, INTERNAL_IP4_DNS);
+ }
+ else
+ {
+ ca->set_type(ca, INTERNAL_IP6_DNS);
+ }
+ cp->add_configuration_attribute(cp, ca);
+ message->add_payload(message, (payload_t*)cp);
}
-
- build_payloads(this, message, CFG_REQUEST);
}
-
return NEED_MORE;
}
@@ -327,9 +230,8 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
*/
static status_t process_r(private_ike_config_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, ID_INITIATOR))
- {
+ if (message->get_message_id(message) == 1)
+ { /* in first IKE_AUTH only */
process_payloads(this, message);
}
return NEED_MORE;
@@ -340,25 +242,28 @@ static status_t process_r(private_ike_config_t *this, message_t *message)
*/
static status_t build_r(private_ike_config_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, EXTENSIBLE_AUTHENTICATION) == NULL)
- {
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ { /* in last IKE_AUTH exchange */
peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa);
if (config && this->virtual_ip)
{
- host_t *ip = NULL;
+ enumerator_t *enumerator;
+ configuration_attribute_type_t type;
+ configuration_attribute_t *ca;
+ chunk_t value;
+ cp_payload_t *cp;
+ host_t *vip = NULL;
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
if (config->get_pool(config))
{
- ip = charon->attributes->acquire_address(charon->attributes,
+ vip = charon->attributes->acquire_address(charon->attributes,
config->get_pool(config),
this->ike_sa->get_other_id(this->ike_sa),
- this->ike_sa->get_other_auth(this->ike_sa),
this->virtual_ip);
}
- if (ip == NULL)
+ if (vip == NULL)
{
DBG1(DBG_IKE, "no virtual IP found, sending %N",
notify_type_names, INTERNAL_ADDRESS_FAILURE);
@@ -366,13 +271,28 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
chunk_empty);
return SUCCESS;
}
- DBG1(DBG_IKE, "assigning virtual IP %H to peer", ip);
- this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, ip);
+ DBG1(DBG_IKE, "assigning virtual IP %H to peer", vip);
+ this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
+
+ cp = cp_payload_create();
+ cp->set_config_type(cp, CFG_REPLY);
- this->virtual_ip->destroy(this->virtual_ip);
- this->virtual_ip = ip;
+ build_vip(this, vip, cp);
+ vip->destroy(vip);
- build_payloads(this, message, CFG_REPLY);
+ /* if we add an IP, we also look for other attributes */
+ enumerator = charon->attributes->create_attribute_enumerator(
+ charon->attributes, this->ike_sa->get_other_id(this->ike_sa));
+ while (enumerator->enumerate(enumerator, &type, &value))
+ {
+ ca = configuration_attribute_create();
+ ca->set_type(ca, type);
+ ca->set_value(ca, value);
+ cp->add_configuration_attribute(cp, ca);
+ }
+ enumerator->destroy(enumerator);
+
+ message->add_payload(message, (payload_t*)cp);
}
return SUCCESS;
}
@@ -384,39 +304,14 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
*/
static status_t process_i(private_ike_config_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- !message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
- {
- host_t *ip;
- peer_cfg_t *config;
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ { /* in last IKE_AUTH exchange */
- DESTROY_IF(this->virtual_ip);
- this->virtual_ip = NULL;
-
process_payloads(this, message);
- if (this->virtual_ip == NULL)
- { /* force a configured virtual IP, even if server didn't return one */
- config = this->ike_sa->get_peer_cfg(this->ike_sa);
- this->virtual_ip = config->get_virtual_ip(config);
- if (this->virtual_ip)
- {
- this->virtual_ip = this->virtual_ip->clone(this->virtual_ip);
- }
- }
-
- if (this->virtual_ip && !this->virtual_ip->is_anyaddr(this->virtual_ip))
+ if (this->virtual_ip)
{
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
-
- while (this->dns->remove_last(this->dns, (void**)&ip) == SUCCESS)
- {
- if (!ip->is_anyaddr(ip))
- {
- this->ike_sa->add_dns_server(this->ike_sa, ip);
- }
- ip->destroy(ip);
- }
}
return SUCCESS;
}
@@ -437,11 +332,9 @@ static task_type_t get_type(private_ike_config_t *this)
static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
{
DESTROY_IF(this->virtual_ip);
- this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
this->ike_sa = ike_sa;
this->virtual_ip = NULL;
- this->dns = linked_list_create();
}
/**
@@ -450,8 +343,6 @@ static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
static void destroy(private_ike_config_t *this)
{
DESTROY_IF(this->virtual_ip);
- this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
- this->nbns->destroy_offset(this->nbns, offsetof(host_t, destroy));
free(this);
}
@@ -461,7 +352,7 @@ static void destroy(private_ike_config_t *this)
ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
{
private_ike_config_t *this = malloc_thing(private_ike_config_t);
-
+
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
@@ -469,9 +360,7 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
this->initiator = initiator;
this->ike_sa = ike_sa;
this->virtual_ip = NULL;
- this->dns = linked_list_create();
- this->nbns = linked_list_create();
-
+
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
@@ -479,49 +368,10 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
}
else
{
- int i;
-
- /* assign DNS servers */
- for (i = 1; i <= DNS_SERVER_MAX; i++)
- {
- char dns_key[16], *dns_str;
-
- snprintf(dns_key, sizeof(dns_key), "charon.dns%d", i);
- dns_str = lib->settings->get_str(lib->settings, dns_key, NULL);
- if (dns_str)
- {
- host_t *dns = host_create_from_string(dns_str, 0);
-
- if (dns)
- {
- DBG2(DBG_CFG, "assigning DNS server %H to peer", dns);
- this->dns->insert_last(this->dns, dns);
- }
- }
- }
-
- /* assign WINS servers */
- for (i = 1; i <= NBNS_SERVER_MAX; i++)
- {
- char nbns_key[16], *nbns_str;
-
- snprintf(nbns_key, sizeof(nbns_key), "charon.nbns%d", i);
- nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL);
- if (nbns_str)
- {
- host_t *nbns = host_create_from_string(nbns_str, 0);
-
- if (nbns)
- {
- DBG2(DBG_CFG, "assigning NBNS server %H to peer", nbns);
- this->nbns->insert_last(this->nbns, nbns);
- }
- }
- }
-
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
}
-
+
return &this->public;
}
+
diff --git a/src/charon/sa/tasks/ike_config.h b/src/charon/sa/tasks/ike_config.h
index cc709f4d6..32635e85e 100644
--- a/src/charon/sa/tasks/ike_config.h
+++ b/src/charon/sa/tasks/ike_config.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_config.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_delete.c b/src/charon/sa/tasks/ike_delete.c
index 1c051853c..f308a6358 100644
--- a/src/charon/sa/tasks/ike_delete.c
+++ b/src/charon/sa/tasks/ike_delete.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_delete.c 4458 2008-10-17 03:44:06Z andreas $
*/
#include "ike_delete.h"
@@ -56,7 +54,7 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
{
delete_payload_t *delete_payload;
- DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]",
+ DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%Y]...%H[%Y]",
this->ike_sa->get_name(this->ike_sa),
this->ike_sa->get_unique_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
@@ -95,7 +93,7 @@ static status_t process_r(private_ike_delete_t *this, message_t *message)
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));
- DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%D]...%H[%D]",
+ DBG0(DBG_IKE, "deleting IKE_SA %s[%d] between %H[%Y]...%H[%Y]",
this->ike_sa->get_name(this->ike_sa),
this->ike_sa->get_unique_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
diff --git a/src/charon/sa/tasks/ike_delete.h b/src/charon/sa/tasks/ike_delete.h
index ea4e9832b..82782f393 100644
--- a/src/charon/sa/tasks/ike_delete.h
+++ b/src/charon/sa/tasks/ike_delete.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_delete.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_dpd.c b/src/charon/sa/tasks/ike_dpd.c
index 9f1d43cbf..3aa714049 100644
--- a/src/charon/sa/tasks/ike_dpd.c
+++ b/src/charon/sa/tasks/ike_dpd.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_dpd.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ike_dpd.h"
diff --git a/src/charon/sa/tasks/ike_dpd.h b/src/charon/sa/tasks/ike_dpd.h
index 0eadd0db7..36388d15b 100644
--- a/src/charon/sa/tasks/ike_dpd.h
+++ b/src/charon/sa/tasks/ike_dpd.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_dpd.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_init.c b/src/charon/sa/tasks/ike_init.c
index 139107480..2705f5886 100644
--- a/src/charon/sa/tasks/ike_init.c
+++ b/src/charon/sa/tasks/ike_init.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_init.c 4717 2008-11-28 09:51:44Z martin $
*/
#include "ike_init.h"
@@ -170,11 +168,11 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
*/
static void process_payloads(private_ike_init_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
-
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
switch (payload->get_type(payload))
{
@@ -182,7 +180,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
{
sa_payload_t *sa_payload = (sa_payload_t*)payload;
linked_list_t *proposal_list;
-
+
proposal_list = sa_payload->get_proposals(sa_payload);
this->proposal = this->config->select_proposal(this->config,
proposal_list);
@@ -225,7 +223,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -317,12 +315,12 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
#ifdef ME
{
chunk_t connect_id = chunk_empty;
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
-
+
/* check for a ME_CONNECTID notify */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -353,7 +351,7 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (connect_id.ptr)
{
@@ -458,12 +456,12 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
*/
static status_t process_i(private_ike_init_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
-
+
/* check for erronous notifies */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -489,19 +487,22 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
this->ike_sa->reset(this->ike_sa);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return NEED_MORE;
}
case NAT_DETECTION_SOURCE_IP:
case NAT_DETECTION_DESTINATION_IP:
/* skip, handled in ike_natd_t */
break;
+ case MULTIPLE_AUTH_SUPPORTED:
+ /* handled in ike_auth_t */
+ break;
case COOKIE:
{
chunk_free(&this->cookie);
this->cookie = chunk_clone(notify->get_notification_data(notify));
this->ike_sa->reset(this->ike_sa);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
DBG2(DBG_IKE, "received %N notify", notify_type_names, type);
return NEED_MORE;
}
@@ -511,7 +512,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return FAILED;
}
DBG2(DBG_IKE, "received %N notify",
@@ -521,7 +522,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
process_payloads(this, message);
diff --git a/src/charon/sa/tasks/ike_init.h b/src/charon/sa/tasks/ike_init.h
index 84f28a98d..8d3810ef2 100644
--- a/src/charon/sa/tasks/ike_init.h
+++ b/src/charon/sa/tasks/ike_init.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_init.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_me.c b/src/charon/sa/tasks/ike_me.c
index f58d51341..d359aa339 100644
--- a/src/charon/sa/tasks/ike_me.c
+++ b/src/charon/sa/tasks/ike_me.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_me.c 4640 2008-11-12 16:07:17Z martin $
*/
#include "ike_me.h"
@@ -166,11 +164,11 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message)
*/
static void process_payloads(private_ike_me_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
-
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) != NOTIFY)
{
@@ -237,7 +235,7 @@ static void process_payloads(private_ike_me_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -339,7 +337,7 @@ static status_t process_r(private_ike_me_t *this, message_t *message)
if (this->callback)
{
- DBG1(DBG_IKE, "received ME_CALLBACK for '%D'", this->peer_id);
+ DBG1(DBG_IKE, "received ME_CALLBACK for '%Y'", this->peer_id);
break;
}
@@ -471,7 +469,7 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
if (this->failed)
{
- DBG1(DBG_IKE, "peer '%D' is not online", this->peer_id);
+ DBG1(DBG_IKE, "peer '%Y' is not online", this->peer_id);
/* FIXME: notify the mediated connection (job?) */
}
else
diff --git a/src/charon/sa/tasks/ike_me.h b/src/charon/sa/tasks/ike_me.h
index 3bef0a7f1..4b35c313c 100644
--- a/src/charon/sa/tasks/ike_me.h
+++ b/src/charon/sa/tasks/ike_me.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_me.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index b5e065081..9a1afe744 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_mobike.c 4816 2008-12-19 14:34:40Z martin $
*/
#include "ike_mobike.h"
@@ -97,12 +95,12 @@ static void flush_additional_addresses(private_ike_mobike_t *this)
*/
static void process_payloads(private_ike_mobike_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
bool first = TRUE;
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
int family = AF_INET;
notify_payload_t *notify;
@@ -181,7 +179,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -332,9 +330,8 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
*/
static status_t build_i(private_ike_mobike_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, ID_INITIATOR))
- {
+ if (message->get_message_id(message) == 1)
+ { /* only in first IKE_AUTH */
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
build_address_list(this, message);
}
@@ -381,9 +378,8 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
*/
static status_t process_r(private_ike_mobike_t *this, message_t *message)
{
- if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, ID_INITIATOR))
- {
+ if (message->get_message_id(message) == 1)
+ { /* only first IKE_AUTH */
process_payloads(this, message);
}
else if (message->get_exchange_type(message) == INFORMATIONAL)
diff --git a/src/charon/sa/tasks/ike_mobike.h b/src/charon/sa/tasks/ike_mobike.h
index 4a2006a80..919b5ddd3 100644
--- a/src/charon/sa/tasks/ike_mobike.h
+++ b/src/charon/sa/tasks/ike_mobike.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_mobike.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_natd.c b/src/charon/sa/tasks/ike_natd.c
index eb84c876f..bb18e7bda 100644
--- a/src/charon/sa/tasks/ike_natd.c
+++ b/src/charon/sa/tasks/ike_natd.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_natd.c 5029 2009-03-26 11:49:07Z martin $
*/
#include "ike_natd.h"
@@ -166,7 +164,7 @@ static notify_payload_t *build_natd_payload(private_ike_natd_t *this,
*/
static void process_payloads(private_ike_natd_t *this, message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
notify_payload_t *notify;
chunk_t hash, src_hash, dst_hash;
@@ -184,8 +182,8 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
DBG3(DBG_IKE, "precalculated src_hash %B", &src_hash);
DBG3(DBG_IKE, "precalculated dst_hash %B", &dst_hash);
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) != NOTIFY)
{
@@ -235,7 +233,7 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
chunk_free(&src_hash);
chunk_free(&dst_hash);
diff --git a/src/charon/sa/tasks/ike_natd.h b/src/charon/sa/tasks/ike_natd.h
index 155ae4b4c..698394842 100644
--- a/src/charon/sa/tasks/ike_natd.h
+++ b/src/charon/sa/tasks/ike_natd.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_natd.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_reauth.c b/src/charon/sa/tasks/ike_reauth.c
index 61701075f..80f1b7b8c 100644
--- a/src/charon/sa/tasks/ike_reauth.c
+++ b/src/charon/sa/tasks/ike_reauth.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_reauth.c 4495 2008-10-28 16:07:06Z martin $
*/
#include "ike_reauth.h"
@@ -100,7 +98,7 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message)
/* we initiate the new IKE_SA of the mediation connection without CHILD_SA */
if (peer_cfg->is_mediation(peer_cfg))
{
- if (new->initiate(new, NULL) == DESTROY_ME)
+ if (new->initiate(new, NULL, 0, NULL, NULL) == DESTROY_ME)
{
charon->ike_sa_manager->checkin_and_destroy(
charon->ike_sa_manager, new);
@@ -128,7 +126,7 @@ static status_t process_i(private_ike_reauth_t *this, message_t *message)
/* initiate/queue all child SAs */
child_cfg_t *child_cfg = child_sa->get_config(child_sa);
child_cfg->get_ref(child_cfg);
- if (new->initiate(new, child_cfg) == DESTROY_ME)
+ if (new->initiate(new, child_cfg, 0, NULL, NULL) == DESTROY_ME)
{
iterator->destroy(iterator);
charon->ike_sa_manager->checkin_and_destroy(
diff --git a/src/charon/sa/tasks/ike_reauth.h b/src/charon/sa/tasks/ike_reauth.h
index 689550c92..5e97b719c 100644
--- a/src/charon/sa/tasks/ike_reauth.h
+++ b/src/charon/sa/tasks/ike_reauth.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_reauth.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/ike_rekey.c b/src/charon/sa/tasks/ike_rekey.c
index e61d161bc..bead408a6 100644
--- a/src/charon/sa/tasks/ike_rekey.c
+++ b/src/charon/sa/tasks/ike_rekey.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_rekey.c 4730 2008-12-01 18:38:28Z martin $
*/
#include "ike_rekey.h"
@@ -177,7 +175,7 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message)
this->ike_sa->set_state(this->ike_sa, IKE_REKEYING);
this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
+ DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
this->new_sa->get_name(this->new_sa),
this->new_sa->get_unique_id(this->new_sa),
this->ike_sa->get_my_host(this->ike_sa),
@@ -193,13 +191,12 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message)
*/
static status_t process_i(private_ike_rekey_t *this, message_t *message)
{
- ike_sa_id_t *to_delete;
- iterator_t *iterator;
+ enumerator_t *enumerator;
payload_t *payload;
-
+
/* handle NO_ADDITIONAL_SAS notify */
- iterator = message->get_payload_iterator(message);
- while (iterator->iterate(iterator, (void**)&payload))
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
{
if (payload->get_type(payload) == NOTIFY)
{
@@ -213,12 +210,12 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
charon->processor->queue_job(charon->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return SUCCESS;
}
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
switch (this->ike_init->task.process(&this->ike_init->task, message))
{
@@ -235,7 +232,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "IKE_SA rekeying failed, "
"trying again in %d seconds", retry);
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry * 1000);
+ charon->scheduler->schedule_job(charon->scheduler, job, retry);
}
return SUCCESS;
case NEED_MORE:
@@ -245,17 +242,15 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
default:
break;
}
-
+
this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED);
- DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
+ DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
this->new_sa->get_name(this->new_sa),
this->new_sa->get_unique_id(this->new_sa),
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
-
- to_delete = this->ike_sa->get_id(this->ike_sa);
/* check for collisions */
if (this->collision &&
@@ -273,8 +268,13 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
if (memcmp(this_nonce.ptr, other_nonce.ptr,
min(this_nonce.len, other_nonce.len)) < 0)
{
+ /* peer should delete this SA. Add a timeout just in case. */
+ job_t *job = (job_t*)delete_ike_sa_job_create(
+ other->new_sa->get_id(other->new_sa), TRUE);
+ charon->scheduler->schedule_job(charon->scheduler, job, 10);
DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
+ other->new_sa = NULL;
}
else
{
@@ -285,11 +285,22 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
host = this->ike_sa->get_other_host(this->ike_sa);
this->new_sa->set_other_host(this->new_sa, host->clone(host));
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- to_delete = this->new_sa->get_id(this->new_sa);
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa);
+ if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ /* set threads active IKE_SA after checkin */
+ charon->bus->set_sa(charon->bus, this->ike_sa);
/* inherit to other->new_sa in destroy() */
this->new_sa = other->new_sa;
other->new_sa = NULL;
+ return SUCCESS;
}
/* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
diff --git a/src/charon/sa/tasks/ike_rekey.h b/src/charon/sa/tasks/ike_rekey.h
index ab82789f3..6748279ab 100644
--- a/src/charon/sa/tasks/ike_rekey.h
+++ b/src/charon/sa/tasks/ike_rekey.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ike_rekey.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/tasks/task.c b/src/charon/sa/tasks/task.c
index fd15379f3..9e35b62a5 100644
--- a/src/charon/sa/tasks/task.c
+++ b/src/charon/sa/tasks/task.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: task.c 4618 2008-11-11 09:22:00Z tobias $
*/
#include "task.h"
diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h
index a5eb2caa3..f9b409f35 100644
--- a/src/charon/sa/tasks/task.h
+++ b/src/charon/sa/tasks/task.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: task.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/charon/sa/trap_manager.c b/src/charon/sa/trap_manager.c
new file mode 100644
index 000000000..a74fab93f
--- /dev/null
+++ b/src/charon/sa/trap_manager.c
@@ -0,0 +1,371 @@
+/*
+ * 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 "trap_manager.h"
+
+#include <daemon.h>
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+
+
+typedef struct private_trap_manager_t private_trap_manager_t;
+typedef struct trap_listener_t trap_listener_t;
+
+/**
+ * listener to track acquires
+ */
+struct trap_listener_t {
+
+ /**
+ * Implements listener interface
+ */
+ listener_t listener;
+
+ /**
+ * points to trap_manager
+ */
+ private_trap_manager_t *traps;
+};
+
+/**
+ * Private data of an trap_manager_t object.
+ */
+struct private_trap_manager_t {
+
+ /**
+ * Public trap_manager_t interface.
+ */
+ trap_manager_t public;
+
+ /**
+ * Installed traps, as entry_t
+ */
+ linked_list_t *traps;
+
+ /**
+ * read write lock for traps list
+ */
+ rwlock_t *lock;
+
+ /**
+ * listener to track acquiring IKE_SAs
+ */
+ trap_listener_t listener;
+};
+
+/**
+ * A installed trap entry
+ */
+typedef struct {
+ /** ref to peer_cfg to initiate */
+ peer_cfg_t *peer_cfg;
+ /** ref to instanciated CHILD_SA */
+ child_sa_t *child_sa;
+ /** pending IKE_SA connecting upon acquire */
+ ike_sa_t *pending;
+} entry_t;
+
+/**
+ * actually uninstall and destroy an installed entry
+ */
+static void destroy_entry(entry_t *entry)
+{
+ entry->child_sa->destroy(entry->child_sa);
+ entry->peer_cfg->destroy(entry->peer_cfg);
+ free(entry);
+}
+
+/**
+ * Implementation of trap_manager_t.install
+ */
+static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
+ child_cfg_t *child)
+{
+ entry_t *entry;
+ ike_cfg_t *ike_cfg;
+ child_sa_t *child_sa;
+ host_t *me, *other;
+ linked_list_t *my_ts, *other_ts;
+ enumerator_t *enumerator;
+ bool found = FALSE;
+ status_t status;
+ u_int32_t reqid;
+
+ /* check if not already done */
+ this->lock->read_lock(this->lock);
+ enumerator = this->traps->create_enumerator(this->traps);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (streq(entry->child_sa->get_name(entry->child_sa),
+ child->get_name(child)))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ if (found)
+ {
+ DBG1(DBG_CFG, "CHILD_SA named '%s' already routed",
+ child->get_name(child));
+ return 0;
+ }
+
+ /* try to resolve addresses */
+ ike_cfg = peer->get_ike_cfg(peer);
+ other = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg),
+ 0, IKEV2_UDP_PORT);
+ if (!other)
+ {
+ DBG1(DBG_CFG, "installing trap failed, remote address unknown");
+ return 0;
+ }
+ me = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg),
+ other->get_family(other), IKEV2_UDP_PORT);
+ if (!me || me->is_anyaddr(me))
+ {
+ DESTROY_IF(me);
+ me = charon->kernel_interface->get_source_addr(
+ charon->kernel_interface, other, NULL);
+ if (!me)
+ {
+ DBG1(DBG_CFG, "installing trap failed, local address unknown");
+ other->destroy(other);
+ return 0;
+ }
+ me->set_port(me, IKEV2_UDP_PORT);
+ }
+
+ /* create and route CHILD_SA */
+ child_sa = child_sa_create(me, other, child, 0, FALSE);
+ my_ts = child->get_traffic_selectors(child, TRUE, NULL, me);
+ other_ts = child->get_traffic_selectors(child, FALSE, NULL, other);
+ me->destroy(me);
+ other->destroy(other);
+
+ child_sa->set_mode(child_sa, child->get_mode(child));
+ status = child_sa->add_policies(child_sa, my_ts, other_ts);
+ my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
+ other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+ if (status != SUCCESS)
+ {
+ child_sa->destroy(child_sa);
+ DBG1(DBG_CFG, "installing trap failed");
+ return 0;
+ }
+
+ reqid = child_sa->get_reqid(child_sa);
+ entry = malloc_thing(entry_t);
+ entry->child_sa = child_sa;
+ entry->peer_cfg = peer->get_ref(peer);
+ entry->pending = NULL;
+
+ this->lock->write_lock(this->lock);
+ this->traps->insert_last(this->traps, entry);
+ this->lock->unlock(this->lock);
+
+ return reqid;
+}
+
+/**
+ * Implementation of trap_manager_t.uninstall
+ */
+static bool uninstall(private_trap_manager_t *this, u_int32_t reqid)
+{
+ enumerator_t *enumerator;
+ entry_t *entry, *found = NULL;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->traps->create_enumerator(this->traps);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->child_sa->get_reqid(entry->child_sa) == reqid)
+ {
+ this->traps->remove_at(this->traps, enumerator);
+ found = entry;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ if (!found)
+ {
+ DBG1(DBG_CFG, "trap %d not found to uninstall", reqid);
+ return FALSE;
+ }
+
+ destroy_entry(found);
+ return TRUE;
+}
+
+/**
+ * convert enumerated entries to peer_cfg, child_sa
+ */
+static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg,
+ void *none, child_sa_t **child_sa)
+{
+ if (peer_cfg)
+ {
+ *peer_cfg = (*entry)->peer_cfg;
+ }
+ if (child_sa)
+ {
+ *child_sa = (*entry)->child_sa;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of trap_manager_t.create_enumerator
+ */
+static enumerator_t* create_enumerator(private_trap_manager_t *this)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_filter(this->traps->create_enumerator(this->traps),
+ (void*)trap_filter, this->lock,
+ (void*)this->lock->unlock);
+}
+
+/**
+ * Implementation of trap_manager_t.acquire
+ */
+static void acquire(private_trap_manager_t *this, u_int32_t reqid,
+ traffic_selector_t *src, traffic_selector_t *dst)
+{
+ enumerator_t *enumerator;
+ entry_t *entry, *found = NULL;
+ peer_cfg_t *peer;
+ child_cfg_t *child;
+ ike_sa_t *ike_sa;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->traps->create_enumerator(this->traps);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->child_sa->get_reqid(entry->child_sa) == reqid)
+ {
+ found = entry;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ DBG1(DBG_CFG, "trap not found, unable to acquire reqid %d",reqid);
+ }
+ else if (found->pending)
+ {
+ DBG1(DBG_CFG, "ignoring acquire, connection attempt pending");
+ }
+ else
+ {
+ child = found->child_sa->get_config(found->child_sa);
+ peer = found->peer_cfg;
+ ike_sa = charon->ike_sa_manager->checkout_by_config(
+ charon->ike_sa_manager, peer);
+ if (ike_sa->get_peer_cfg(ike_sa) == NULL)
+ {
+ ike_sa->set_peer_cfg(ike_sa, peer);
+ }
+ child->get_ref(child);
+ reqid = found->child_sa->get_reqid(found->child_sa);
+ if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME)
+ {
+ found->pending = ike_sa;
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ }
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Implementation of listener_t.ike_state_change
+ */
+static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
+ ike_sa_state_t state)
+{
+ private_trap_manager_t *this;
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ switch (state)
+ {
+ case IKE_ESTABLISHED:
+ case IKE_DESTROYING:
+ break;
+ default:
+ return TRUE;
+ }
+
+ this = listener->traps;
+ this->lock->read_lock(this->lock);
+ enumerator = this->traps->create_enumerator(this->traps);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->pending == ike_sa)
+ {
+ entry->pending = NULL;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ return TRUE;
+}
+
+/**
+ * Implementation of trap_manager_t.destroy.
+ */
+static void destroy(private_trap_manager_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener.listener);
+ this->traps->invoke_function(this->traps, (void*)destroy_entry);
+ this->traps->destroy(this->traps);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+trap_manager_t *trap_manager_create()
+{
+ private_trap_manager_t *this = malloc_thing(private_trap_manager_t);
+
+ this->public.install = (u_int(*)(trap_manager_t*, peer_cfg_t *peer, child_cfg_t *child))install;
+ this->public.uninstall = (bool(*)(trap_manager_t*, u_int32_t id))uninstall;
+ this->public.create_enumerator = (enumerator_t*(*)(trap_manager_t*))create_enumerator;
+ this->public.acquire = (void(*)(trap_manager_t*, u_int32_t reqid, traffic_selector_t *src, traffic_selector_t *dst))acquire;
+ this->public.destroy = (void(*)(trap_manager_t*))destroy;
+
+ this->traps = linked_list_create();
+ this->lock = rwlock_create(RWLOCK_DEFAULT);
+
+ /* register listener for IKE state changes */
+ this->listener.traps = this;
+ memset(&this->listener.listener, 0, sizeof(listener_t));
+ this->listener.listener.ike_state_change = (void*)ike_state_change;
+ charon->bus->add_listener(charon->bus, &this->listener.listener);
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/trap_manager.h b/src/charon/sa/trap_manager.h
new file mode 100644
index 000000000..cb6907cdc
--- /dev/null
+++ b/src/charon/sa/trap_manager.h
@@ -0,0 +1,81 @@
+/*
+ * 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 trap_manager trap_manager
+ * @{ @ingroup sa
+ */
+
+#ifndef TRAP_MANAGER_H_
+#define TRAP_MANAGER_H_
+
+#include <library.h>
+#include <utils/enumerator.h>
+#include <config/peer_cfg.h>
+
+typedef struct trap_manager_t trap_manager_t;
+
+/**
+ * Manage policies to create SAs from traffic.
+ */
+struct trap_manager_t {
+
+ /**
+ * Install a policy as a trap.
+ *
+ * @param peer peer configuration to initiate on trap
+ * @param child child configuration to install as a trap
+ * @return reqid of installed CHILD_SA, 0 if failed
+ */
+ u_int32_t (*install)(trap_manager_t *this, peer_cfg_t *peer,
+ child_cfg_t *child);
+
+ /**
+ * Uninstall a trap policy.
+ *
+ * @param id reqid of CHILD_SA to uninstall, returned by install()
+ * @return TRUE if uninstalled successfully
+ */
+ bool (*uninstall)(trap_manager_t *this, u_int32_t reqid);
+
+ /**
+ * Create an enumerator over all installed traps.
+ *
+ * @return enumerator over (peer_cfg_t, child_sa_t)
+ */
+ enumerator_t* (*create_enumerator)(trap_manager_t *this);
+
+ /**
+ * Acquire an SA triggered by an installed trap.
+ *
+ * @param reqid requid of the triggering CHILD_SA
+ * @param src source of the triggering packet
+ * @param dst destination of the triggering packet
+ */
+ void (*acquire)(trap_manager_t *this, u_int32_t reqid,
+ traffic_selector_t *src, traffic_selector_t *dst);
+
+ /**
+ * Destroy a trap_manager_t.
+ */
+ void (*destroy)(trap_manager_t *this);
+};
+
+/**
+ * Create a trap_manager instance.
+ */
+trap_manager_t *trap_manager_create();
+
+#endif /* TRAP_MANAGER_ @}*/
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
index 029290fb6..b7fb3f7c8 100644
--- a/src/dumm/Makefile.am
+++ b/src/dumm/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_DIST = ext/dumm.c ext/extconf.rb ext/README \
+EXTRA_DIST = ext/dumm.c ext/README \
ext/lib/dumm.rb ext/lib/dumm/guest.rb
lib_LTLIBRARIES = libdumm.la
@@ -15,5 +15,18 @@ dumm_LDADD = libdumm.la ${gtk_LIBS}
irdumm_LDADD = libdumm.la -lruby1.8
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
- -I/usr/lib/ruby/1.8/i486-linux/
+ ${RUBYINCLUDE}
AM_CFLAGS = -D_FILE_OFFSET_BITS=64
+
+all-local: ext
+
+clean-local:
+ (test -f ext/Makefile && cd ext && $(MAKE) clean && rm Makefile || true)
+
+install-data-local:
+ (test -f ext/Makefile && cd ext && $(MAKE) install)
+
+ext: libdumm.la
+ (cd ext && $(RUBY) extconf.rb && $(MAKE))
+
+.PHONY: ext
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 6cf2a88af..fdbf41f47 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -97,6 +97,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -119,6 +120,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -130,6 +134,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -143,6 +148,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -203,6 +210,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -214,11 +222,12 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-EXTRA_DIST = ext/dumm.c ext/extconf.rb ext/README \
+EXTRA_DIST = ext/dumm.c ext/README \
ext/lib/dumm.rb ext/lib/dumm/guest.rb
lib_LTLIBRARIES = libdumm.la
@@ -233,7 +242,7 @@ libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
dumm_LDADD = libdumm.la ${gtk_LIBS}
irdumm_LDADD = libdumm.la -lruby1.8
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
- -I/usr/lib/ruby/1.8/i486-linux/
+ ${RUBYINCLUDE}
AM_CFLAGS = -D_FILE_OFFSET_BITS=64
all: all-am
@@ -244,8 +253,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -380,7 +389,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -450,7 +459,7 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) all-local
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -482,7 +491,7 @@ maintainer-clean-generic:
clean: clean-am
clean-am: clean-generic clean-ipsecPROGRAMS clean-libLTLIBRARIES \
- clean-libtool mostlyclean-am
+ clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -500,7 +509,7 @@ info: info-am
info-am:
-install-data-am: install-ipsecPROGRAMS
+install-data-am: install-data-local install-ipsecPROGRAMS
install-dvi: install-dvi-am
@@ -540,21 +549,35 @@ uninstall-am: uninstall-ipsecPROGRAMS uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-ipsecPROGRAMS clean-libLTLIBRARIES clean-libtool ctags \
- distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-ipsecPROGRAMS install-libLTLIBRARIES \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-ipsecPROGRAMS uninstall-libLTLIBRARIES
+.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
+ clean-generic clean-ipsecPROGRAMS clean-libLTLIBRARIES \
+ clean-libtool clean-local ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-data-local install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-ipsecPROGRAMS install-libLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-ipsecPROGRAMS uninstall-libLTLIBRARIES
+
+
+all-local: ext
+
+clean-local:
+ (test -f ext/Makefile && cd ext && $(MAKE) clean && rm Makefile || true)
+
+install-data-local:
+ (test -f ext/Makefile && cd ext && $(MAKE) install)
+
+ext: libdumm.la
+ (cd ext && $(RUBY) extconf.rb && $(MAKE))
+.PHONY: ext
# 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/dumm/bridge.h b/src/dumm/bridge.h
index 79a0a3a72..37b22a03e 100644
--- a/src/dumm/bridge.h
+++ b/src/dumm/bridge.h
@@ -24,19 +24,19 @@ typedef struct bridge_t bridge_t;
#include "iface.h"
/**
- * @brief Interface in a guest, connected to a tap device on the host.
+ * Interface in a guest, connected to a tap device on the host.
*/
struct bridge_t {
/**
- * @brief Get the name of the bridge.
+ * Get the name of the bridge.
*
* @return name of the bridge
*/
char* (*get_name)(bridge_t *this);
/**
- * @brief Add an interface to a bridge.
+ * Add an interface to a bridge.
*
* @param iface interface to add
* @return TRUE if interface added
@@ -44,7 +44,7 @@ struct bridge_t {
bool (*connect_iface)(bridge_t *this, iface_t *iface);
/**
- * @brief Remove an interface from a bridge.
+ * Remove an interface from a bridge.
*
* @param iface interface to remove
* @return TRUE if interface removed
@@ -52,20 +52,20 @@ struct bridge_t {
bool (*disconnect_iface)(bridge_t *this, iface_t *iface);
/**
- * @brief Create an enumerator over all interfaces.
+ * Create an enumerator over all interfaces.
*
* @return enumerator over iface_t's
*/
enumerator_t* (*create_iface_enumerator)(bridge_t *this);
/**
- * @brief Destroy a bridge
+ * Destroy a bridge
*/
void (*destroy) (bridge_t *this);
};
/**
- * @brief Create a new bridge.
+ * Create a new bridge.
*
* @param name name of the bridge to create
* @return bridge, NULL if failed
diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c
index 88041811e..69f008976 100644
--- a/src/dumm/cowfs.c
+++ b/src/dumm/cowfs.c
@@ -96,7 +96,7 @@ static void rel(const char **path)
static int get_rd(const char *path)
{
private_cowfs_t *this = get_this();
-
+
if (this->over_fd > 0 && faccessat(this->over_fd, path, F_OK, 0) == 0)
{
return this->over_fd;
@@ -223,7 +223,7 @@ static int copy(const char *path)
static int cowfs_getattr(const char *path, struct stat *stbuf)
{
rel(&path);
-
+
if (fstatat(get_rd(path), path, stbuf, AT_SYMLINK_NOFOLLOW) < 0)
{
return -errno;
@@ -242,7 +242,7 @@ static int cowfs_access(const char *path, int mask)
{
return -errno;
}
- return 0;
+ return 0;
}
/**
@@ -251,16 +251,16 @@ static int cowfs_access(const char *path, int mask)
static int cowfs_readlink(const char *path, char *buf, size_t size)
{
int res;
-
+
rel(&path);
res = readlinkat(get_rd(path), path, buf, size - 1);
- if (res < 0)
- {
- return -errno;
+ if (res < 0)
+ {
+ return -errno;
}
- buf[res] = '\0';
- return 0;
+ buf[res] = '\0';
+ return 0;
}
/**
@@ -329,7 +329,7 @@ static int cowfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
{
st.st_ino = ent->d_ino;
st.st_mode = ent->d_type << 12;
- filler(buf, ent->d_name, &st, 0);
+ filler(buf, ent->d_name, &st, 0);
}
}
closedir(d1);
@@ -343,7 +343,7 @@ static int cowfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
{
st.st_ino = ent->d_ino;
st.st_mode = ent->d_type << 12;
- filler(buf, ent->d_name, &st, 0);
+ filler(buf, ent->d_name, &st, 0);
}
}
closedir(d2);
@@ -355,11 +355,11 @@ static int cowfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
{
st.st_ino = ent->d_ino;
st.st_mode = ent->d_type << 12;
- filler(buf, ent->d_name, &st, 0);
+ filler(buf, ent->d_name, &st, 0);
}
closedir(d3);
}
- return 0;
+ return 0;
}
/**
@@ -369,13 +369,13 @@ static int cowfs_mknod(const char *path, mode_t mode, dev_t rdev)
{
int fd;
rel(&path);
-
+
fd = get_wr(path);
if (!clone_path(get_rd(path), fd, path))
{
return -errno;
}
-
+
if (mknodat(fd, path, mode, rdev) < 0)
{
return -errno;
@@ -390,7 +390,7 @@ static int cowfs_mkdir(const char *path, mode_t mode)
{
int fd;
rel(&path);
-
+
fd = get_wr(path);
if (!clone_path(get_rd(path), fd, path))
{
@@ -415,7 +415,7 @@ static int cowfs_unlink(const char *path)
{
return -errno;
}
- return 0;
+ return 0;
}
/**
@@ -430,7 +430,7 @@ static int cowfs_rmdir(const char *path)
{
return -errno;
}
- return 0;
+ return 0;
}
/**
@@ -440,10 +440,10 @@ static int cowfs_symlink(const char *from, const char *to)
{
int fd;
const char *fromrel = from;
-
+
rel(&to);
rel(&fromrel);
-
+
fd = get_wr(to);
if (!clone_path(get_rd(fromrel), fd, fromrel))
{
@@ -462,24 +462,18 @@ static int cowfs_symlink(const char *from, const char *to)
static int cowfs_rename(const char *from, const char *to)
{
int fd;
- private_cowfs_t *this = get_this();
-
+
rel(&from);
rel(&to);
-
- fd = get_rd(from);
- if (fd == this->master_fd)
+
+ fd = copy(from);
+ if (fd < 0)
{
- fd = copy(from);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
}
-
if (renameat(fd, from, get_wr(to), to) < 0)
{
- return -errno;
+ return -errno;
}
return 0;
}
@@ -490,7 +484,7 @@ static int cowfs_rename(const char *from, const char *to)
static int cowfs_link(const char *from, const char *to)
{
int rd, wr;
-
+
rel(&from);
rel(&to);
@@ -502,12 +496,12 @@ static int cowfs_link(const char *from, const char *to)
DBG1("cloning path '%s' failed", to);
return -errno;
}
- if (linkat(rd, from, wr, to, 0) < 0)
- {
+ if (linkat(rd, from, wr, to, 0) < 0)
+ {
DBG1("linking '%s' to '%s' failed", from, to);
- return -errno;
+ return -errno;
}
- return 0;
+ return 0;
}
/**
@@ -517,25 +511,21 @@ static int cowfs_chmod(const char *path, mode_t mode)
{
int fd;
struct stat st;
- private_cowfs_t *this = get_this();
rel(&path);
fd = get_rd(path);
- if (fd == this->master_fd)
+ if (fstatat(fd, path, &st, 0) < 0)
{
- if (fstatat(fd, path, &st, 0) < 0)
- {
- return -errno;
- }
- if (st.st_mode == mode)
- {
- return 0;
- }
- fd = copy(path);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
+ }
+ if (st.st_mode == mode)
+ {
+ return 0;
+ }
+ fd = copy(path);
+ if (fd < 0)
+ {
+ return -errno;
}
if (fchmodat(fd, path, mode, 0) < 0)
{
@@ -551,25 +541,21 @@ static int cowfs_chown(const char *path, uid_t uid, gid_t gid)
{
int fd;
struct stat st;
- private_cowfs_t *this = get_this();
rel(&path);
fd = get_rd(path);
- if (fd == this->master_fd)
+ if (fstatat(fd, path, &st, 0) < 0)
{
- if (fstatat(fd, path, &st, 0) < 0)
- {
- return -errno;
- }
- if (st.st_uid == uid && st.st_gid == gid)
- {
- return 0;
- }
- fd = copy(path);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
+ }
+ if (st.st_uid == uid && st.st_gid == gid)
+ {
+ return 0;
+ }
+ fd = copy(path);
+ if (fd < 0)
+ {
+ return -errno;
}
if (fchownat(fd, path, uid, gid, AT_SYMLINK_NOFOLLOW) < 0)
{
@@ -586,25 +572,20 @@ static int cowfs_truncate(const char *path, off_t size)
int fd;
struct stat st;
- private_cowfs_t *this = get_this();
-
rel(&path);
fd = get_rd(path);
- if (fd == this->master_fd)
+ if (fstatat(fd, path, &st, 0) < 0)
{
- if (fstatat(fd, path, &st, 0) < 0)
- {
- return -errno;
- }
- if (st.st_size == size)
- {
- return 0;
- }
- fd = copy(path);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
+ }
+ if (st.st_size == size)
+ {
+ return 0;
+ }
+ fd = copy(path);
+ if (fd < 0)
+ {
+ return -errno;
}
fd = openat(fd, path, O_WRONLY);
if (fd < 0)
@@ -627,24 +608,19 @@ static int cowfs_utimens(const char *path, const struct timespec ts[2])
{
struct timeval tv[2];
int fd;
- private_cowfs_t *this = get_this();
-
+
rel(&path);
- fd = get_rd(path);
- if (fd == this->master_fd)
+ fd = copy(path);
+ if (fd < 0)
{
- fd = copy(path);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
}
-
+
tv[0].tv_sec = ts[0].tv_sec;
tv[0].tv_usec = ts[0].tv_nsec / 1000;
tv[1].tv_sec = ts[1].tv_sec;
tv[1].tv_usec = ts[1].tv_nsec / 1000;
-
+
if (futimesat(fd, path, tv) < 0)
{
return -errno;
@@ -658,10 +634,10 @@ static int cowfs_utimens(const char *path, const struct timespec ts[2])
static int cowfs_open(const char *path, struct fuse_file_info *fi)
{
int fd;
-
+
rel(&path);
fd = get_rd(path);
-
+
fd = openat(fd, path, fi->flags);
if (fd < 0)
{
@@ -678,11 +654,11 @@ static int cowfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
int file, fd, res;
-
+
rel(&path);
-
+
fd = get_rd(path);
-
+
file = openat(fd, path, O_RDONLY);
if (file < 0)
{
@@ -704,20 +680,14 @@ static int cowfs_read(const char *path, char *buf, size_t size, off_t offset,
static int cowfs_write(const char *path, const char *buf, size_t size,
off_t offset, struct fuse_file_info *fi)
{
- private_cowfs_t *this = get_this();
int file, fd, res;
-
+
rel(&path);
-
- fd = get_wr(path);
- if (fd == this->master_fd ||
- (this->over_fd > 0 && fd == this->host_fd))
+
+ fd = copy(path);
+ if (fd < 0)
{
- fd = copy(path);
- if (fd < 0)
- {
- return -errno;
- }
+ return -errno;
}
file = openat(fd, path, O_WRONLY);
if (file < 0)
@@ -738,21 +708,15 @@ static int cowfs_write(const char *path, const char *buf, size_t size,
*/
static int cowfs_statfs(const char *path, struct statvfs *stbuf)
{
- private_cowfs_t *this = get_this();
int fd;
- fd = this->host_fd;
- if (this->over_fd > 0)
- {
- fd = this->over_fd;
- }
-
+ fd = get_rd(path);
if (fstatvfs(fd, stbuf) < 0)
{
return -errno;
}
- return 0;
+ return 0;
}
/**
@@ -771,26 +735,26 @@ static void *cowfs_init(struct fuse_conn_info *conn)
* FUSE method vectors
*/
static struct fuse_operations cowfs_operations = {
- .getattr = cowfs_getattr,
- .access = cowfs_access,
- .readlink = cowfs_readlink,
- .readdir = cowfs_readdir,
- .mknod = cowfs_mknod,
- .mkdir = cowfs_mkdir,
- .symlink = cowfs_symlink,
- .unlink = cowfs_unlink,
- .rmdir = cowfs_rmdir,
- .rename = cowfs_rename,
- .link = cowfs_link,
- .chmod = cowfs_chmod,
- .chown = cowfs_chown,
- .truncate = cowfs_truncate,
- .utimens = cowfs_utimens,
- .open = cowfs_open,
- .read = cowfs_read,
- .write = cowfs_write,
- .statfs = cowfs_statfs,
- .init = cowfs_init,
+ .getattr = cowfs_getattr,
+ .access = cowfs_access,
+ .readlink = cowfs_readlink,
+ .readdir = cowfs_readdir,
+ .mknod = cowfs_mknod,
+ .mkdir = cowfs_mkdir,
+ .symlink = cowfs_symlink,
+ .unlink = cowfs_unlink,
+ .rmdir = cowfs_rmdir,
+ .rename = cowfs_rename,
+ .link = cowfs_link,
+ .chmod = cowfs_chmod,
+ .chown = cowfs_chown,
+ .truncate = cowfs_truncate,
+ .utimens = cowfs_utimens,
+ .open = cowfs_open,
+ .read = cowfs_read,
+ .write = cowfs_write,
+ .statfs = cowfs_statfs,
+ .init = cowfs_init,
};
/**
@@ -854,63 +818,63 @@ cowfs_t *cowfs_create(char *master, char *host, char *mount)
this->public.set_overlay = (bool(*)(cowfs_t*, char *path))set_overlay;
this->public.destroy = (void(*)(cowfs_t*))destroy;
- this->master_fd = open(master, O_RDONLY | O_DIRECTORY);
- if (this->master_fd < 0)
- {
- DBG1("failed to open master filesystem '%s'", master);
- free(this);
- return NULL;
- }
- this->host_fd = open(host, O_RDONLY | O_DIRECTORY);
+ this->master_fd = open(master, O_RDONLY | O_DIRECTORY);
+ if (this->master_fd < 0)
+ {
+ DBG1("failed to open master filesystem '%s'", master);
+ free(this);
+ return NULL;
+ }
+ this->host_fd = open(host, O_RDONLY | O_DIRECTORY);
if (this->host_fd < 0)
- {
- DBG1("failed to open host filesystem '%s'", host);
- close(this->master_fd);
- free(this);
- return NULL;
- }
+ {
+ DBG1("failed to open host filesystem '%s'", host);
+ close(this->master_fd);
+ free(this);
+ return NULL;
+ }
this->over_fd = -1;
- this->chan = fuse_mount(mount, &args);
- if (this->chan == NULL)
- {
- DBG1("mounting cowfs FUSE on '%s' failed", mount);
- close(this->master_fd);
- close(this->host_fd);
- free(this);
- return NULL;
- }
-
- this->fuse = fuse_new(this->chan, &args, &cowfs_operations,
- sizeof(cowfs_operations), this);
- if (this->fuse == NULL)
- {
- DBG1("creating cowfs FUSE handle failed");
- close(this->master_fd);
- close(this->host_fd);
- fuse_unmount(mount, this->chan);
- free(this);
- return NULL;
- }
-
- this->mount = strdup(mount);
- this->master = strdup(master);
- this->host = strdup(host);
- this->over = NULL;
+ this->chan = fuse_mount(mount, &args);
+ if (this->chan == NULL)
+ {
+ DBG1("mounting cowfs FUSE on '%s' failed", mount);
+ close(this->master_fd);
+ close(this->host_fd);
+ free(this);
+ return NULL;
+ }
+
+ this->fuse = fuse_new(this->chan, &args, &cowfs_operations,
+ sizeof(cowfs_operations), this);
+ if (this->fuse == NULL)
+ {
+ DBG1("creating cowfs FUSE handle failed");
+ close(this->master_fd);
+ close(this->host_fd);
+ fuse_unmount(mount, this->chan);
+ free(this);
+ return NULL;
+ }
+
+ this->mount = strdup(mount);
+ this->master = strdup(master);
+ this->host = strdup(host);
+ this->over = NULL;
if (pthread_create(&this->thread, NULL, (void*)fuse_loop, this->fuse) != 0)
{
- DBG1("creating thread to handle FUSE failed");
- fuse_unmount(mount, this->chan);
- free(this->mount);
- free(this->master);
- free(this->host);
- close(this->master_fd);
- close(this->host_fd);
- free(this);
- return NULL;
- }
-
- return &this->public;
+ DBG1("creating thread to handle FUSE failed");
+ fuse_unmount(mount, this->chan);
+ free(this->mount);
+ free(this->master);
+ free(this->host);
+ close(this->master_fd);
+ close(this->host_fd);
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
}
diff --git a/src/dumm/cowfs.h b/src/dumm/cowfs.h
index 419197dd6..bb589f158 100644
--- a/src/dumm/cowfs.h
+++ b/src/dumm/cowfs.h
@@ -21,13 +21,13 @@
typedef struct cowfs_t cowfs_t;
/**
- * @brief cowfs - Copy on write FUSE filesystem.
+ * cowfs - Copy on write FUSE filesystem.
*
*/
struct cowfs_t {
/**
- * @brief Set an additional copy on write overlay.
+ * Set an additional copy on write overlay.
*
* @param path path of the overlay
* @return FALSE if failed
@@ -35,13 +35,13 @@ struct cowfs_t {
bool (*set_overlay)(cowfs_t *this, char *path);
/**
- * @brief Stop, umount and destroy a cowfs FUSE filesystem.
+ * Stop, umount and destroy a cowfs FUSE filesystem.
*/
void (*destroy) (cowfs_t *this);
};
/**
- * @brief Mount a cowfs FUSE filesystem.
+ * Mount a cowfs FUSE filesystem.
*
* @param master read only master file system directory
* @param host copy on write host directory
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c
index cf8d9719c..2cb1235e1 100644
--- a/src/dumm/dumm.c
+++ b/src/dumm/dumm.c
@@ -28,8 +28,9 @@
#include "dumm.h"
-#define PERME (S_IRWXU | S_IRWXG)
+#define PERME (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
#define GUEST_DIR "guests"
+#define TEMPLATE_DIR "templates"
typedef struct private_dumm_t private_dumm_t;
@@ -133,10 +134,10 @@ static void clear_template(private_dumm_t *this)
{
enumerator_t *enumerator;
guest_t *guest;
-
+
free(this->template);
this->template = NULL;
-
+
enumerator = this->guests->create_enumerator(this->guests);
while (enumerator->enumerate(enumerator, (void**)&guest))
{
@@ -165,7 +166,11 @@ static bool load_template(private_dumm_t *this, char *dir)
return FALSE;
}
- this->template = strdup(dir);
+ if (asprintf(&this->template, "%s/%s", TEMPLATE_DIR, dir) < 0)
+ {
+ this->template = NULL;
+ return FALSE;
+ }
if (access(this->template, F_OK) != 0)
{ /* does not exist, create template */
if (!mkdir_p(this->template, PERME))
@@ -189,13 +194,66 @@ static bool load_template(private_dumm_t *this, char *dir)
}
/**
+ * Template directory enumerator
+ */
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** directory enumerator */
+ enumerator_t *inner;
+} template_enumerator_t;
+
+/**
+ * Implementation of template_enumerator_t.enumerate
+ */
+static bool template_enumerate(template_enumerator_t *this, char **template)
+{
+ struct stat st;
+ char *rel;
+
+ while (this->inner->enumerate(this->inner, &rel, NULL, &st))
+ {
+ if (S_ISDIR(st.st_mode) && *rel != '.')
+ {
+ *template = rel;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of template_enumerator_t.destroy
+ */
+static void template_enumerator_destroy(template_enumerator_t *this)
+{
+ this->inner->destroy(this->inner);
+ free(this);
+}
+
+/**
+ * Implementation of dumm_t.create_template_enumerator
+ */
+static enumerator_t* create_template_enumerator(private_dumm_t *this)
+{
+ template_enumerator_t *enumerator;
+
+ enumerator = malloc_thing(template_enumerator_t);
+ enumerator->public.enumerate = (void*)template_enumerate;
+ enumerator->public.destroy = (void*)template_enumerator_destroy;
+ enumerator->inner = enumerator_create_directory(TEMPLATE_DIR);
+
+ return &enumerator->public;
+}
+
+/**
* Implementation of dumm_t.destroy
*/
static void destroy(private_dumm_t *this)
{
enumerator_t *enumerator;
guest_t *guest;
-
+
this->bridges->destroy_offset(this->bridges, offsetof(bridge_t, destroy));
enumerator = this->guests->create_enumerator(this->guests);
@@ -233,8 +291,8 @@ static void load_guests(private_dumm_t *this)
while ((ent = readdir(dir)))
{
- if (streq(ent->d_name, ".") || streq(ent->d_name, ".."))
- {
+ if (*ent->d_name == '.')
+ { /* skip ".", ".." and hidden files (such as ".svn") */
continue;
}
guest = guest_load(this->guest_dir, ent->d_name);
@@ -265,6 +323,7 @@ dumm_t *dumm_create(char *dir)
this->public.create_bridge_enumerator = (enumerator_t*(*)(dumm_t*))create_bridge_enumerator;
this->public.delete_bridge = (void(*)(dumm_t*,bridge_t*))delete_bridge;
this->public.load_template = (bool(*)(dumm_t*, char *name))load_template;
+ this->public.create_template_enumerator = (enumerator_t*(*)(dumm_t*))create_template_enumerator;
this->public.destroy = (void(*)(dumm_t*))destroy;
if (dir && *dir == '/')
@@ -273,11 +332,11 @@ dumm_t *dumm_create(char *dir)
}
else
{
- if (getcwd(cwd, sizeof(cwd)) == NULL)
- {
- free(this);
- return NULL;
- }
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ {
+ free(this);
+ return NULL;
+ }
if (dir)
{
if (asprintf(&this->dir, "%s/%s", cwd, dir) < 0)
diff --git a/src/dumm/dumm.h b/src/dumm/dumm.h
index f5db0e45b..5f2e0542a 100644
--- a/src/dumm/dumm.h
+++ b/src/dumm/dumm.h
@@ -28,14 +28,14 @@
typedef struct dumm_t dumm_t;
/**
- * @brief dumm - Dynamic Uml Mesh Modeler
+ * dumm - Dynamic Uml Mesh Modeler
*
* Controls a group of UML guests and their networks.
*/
struct dumm_t {
/**
- * @brief Starts a new UML guest
+ * Starts a new UML guest
*
* @param name name of the guest
* @param kernel UML kernel to use for guest
@@ -47,21 +47,21 @@ struct dumm_t {
char *master, char *args);
/**
- * @brief Create an enumerator over all guests.
+ * Create an enumerator over all guests.
*
* @return enumerator over guest_t's
*/
enumerator_t* (*create_guest_enumerator) (dumm_t *this);
/**
- * @brief Delete a guest from disk.
+ * Delete a guest from disk.
*
* @param guest guest to destroy
*/
void (*delete_guest) (dumm_t *this, guest_t *guest);
/**
- * @brief Create a new bridge.
+ * Create a new bridge.
*
* @param name name of the bridge to create
* @return created bridge
@@ -69,21 +69,21 @@ struct dumm_t {
bridge_t* (*create_bridge)(dumm_t *this, char *name);
/**
- * @brief Create an enumerator over all bridges.
+ * Create an enumerator over all bridges.
*
* @return enumerator over bridge_t's
*/
enumerator_t* (*create_bridge_enumerator)(dumm_t *this);
/**
- * @brief Delete a bridge.
+ * Delete a bridge.
*
* @param bridge bridge to destroy
*/
void (*delete_bridge) (dumm_t *this, bridge_t *bridge);
/**
- * @brief Loads a template, create a new one if it does not exist.
+ * Loads a template, create a new one if it does not exist.
*
* @param name dir to the template, NULL to close
* @return FALSE if load/create failed
@@ -91,13 +91,20 @@ struct dumm_t {
bool (*load_template)(dumm_t *this, char *dir);
/**
- * @brief stop all guests and destroy the modeler
+ * Create an enumerator over all available templates.
+ *
+ * @return enumerator over char*
+ */
+ enumerator_t* (*create_template_enumerator)(dumm_t *this);
+
+ /**
+ * stop all guests and destroy the modeler
*/
void (*destroy) (dumm_t *this);
};
/**
- * @brief Create a group of UML hosts and networks.
+ * Create a group of UML hosts and networks.
*
* @param dir directory to create guests/load from, NULL for cwd
* @return created UML group, or NULL if failed.
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
index 2610affc3..f7caf252d 100644
--- a/src/dumm/ext/dumm.c
+++ b/src/dumm/ext/dumm.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: dumm.c 4447 2008-10-15 14:47:52Z martin $
*/
#include <stdio.h>
@@ -24,11 +22,13 @@
#include <library.h>
#include <dumm.h>
#include <debug.h>
+#include <utils/linked_list.h>
#undef PACKAGE_NAME
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#undef PACKAGE_STRING
+#undef PACKAGE_BUGREPORT
#include <ruby.h>
static dumm_t *dumm;
@@ -84,8 +84,6 @@ static void sigchld_handler(int signal, siginfo_t *info, void* ptr)
enumerator->destroy(enumerator);
}
-
-
/**
* Guest bindings
*/
@@ -93,7 +91,9 @@ static VALUE guest_find(VALUE class, VALUE key)
{
enumerator_t *enumerator;
guest_t *guest, *found = NULL;
- if (TYPE(key) == T_SYMBOL) {
+
+ if (TYPE(key) == T_SYMBOL)
+ {
key = rb_convert_type(key, T_STRING, "String", "to_s");
}
enumerator = dumm->create_guest_enumerator(dumm);
@@ -125,19 +125,26 @@ static VALUE guest_get(VALUE class, VALUE key)
static VALUE guest_each(int argc, VALUE *argv, VALUE class)
{
+ linked_list_t *list;
enumerator_t *enumerator;
guest_t *guest;
-
+
if (!rb_block_given_p())
- {
+ {
rb_raise(rb_eArgError, "must be called with a block");
}
+ list = linked_list_create();
enumerator = dumm->create_guest_enumerator(dumm);
while (enumerator->enumerate(enumerator, &guest))
{
- rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest));
+ list->insert_last(list, guest);
}
enumerator->destroy(enumerator);
+ while (list->remove_first(list, (void**)&guest) == SUCCESS)
+ {
+ rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest));
+ }
+ list->destroy(list);
return class;
}
@@ -249,7 +256,9 @@ static VALUE guest_find_iface(VALUE self, VALUE key)
enumerator_t *enumerator;
iface_t *iface, *found = NULL;
guest_t *guest;
- if (TYPE(key) == T_SYMBOL) {
+
+ if (TYPE(key) == T_SYMBOL)
+ {
key = rb_convert_type(key, T_STRING, "String", "to_s");
}
Data_Get_Struct(self, guest_t, guest);
@@ -283,20 +292,27 @@ static VALUE guest_get_iface(VALUE self, VALUE key)
static VALUE guest_each_iface(int argc, VALUE *argv, VALUE self)
{
enumerator_t *enumerator;
+ linked_list_t *list;
guest_t *guest;
iface_t *iface;
-
+
if (!rb_block_given_p())
- {
+ {
rb_raise(rb_eArgError, "must be called with a block");
}
Data_Get_Struct(self, guest_t, guest);
+ list = linked_list_create();
enumerator = guest->create_iface_enumerator(guest);
while (enumerator->enumerate(enumerator, &iface))
{
- rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
+ list->insert_last(list, iface);
}
enumerator->destroy(enumerator);
+ while (list->remove_first(list, (void**)&iface) == SUCCESS)
+ {
+ rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
+ }
+ list->destroy(list);
return self;
}
@@ -305,6 +321,10 @@ static VALUE guest_delete(VALUE self)
guest_t *guest;
Data_Get_Struct(self, guest_t, guest);
+ if (guest->get_pid(guest))
+ {
+ rb_raise(rb_eRuntimeError, "guest is running");
+ }
dumm->delete_guest(dumm, guest);
return Qnil;
}
@@ -338,11 +358,15 @@ static void guest_init()
/**
* Bridge binding
*/
-static VALUE bridge_get(VALUE class, VALUE key)
+static VALUE bridge_find(VALUE class, VALUE key)
{
enumerator_t *enumerator;
bridge_t *bridge, *found = NULL;
+ if (TYPE(key) == T_SYMBOL)
+ {
+ key = rb_convert_type(key, T_STRING, "String", "to_s");
+ }
enumerator = dumm->create_bridge_enumerator(dumm);
while (enumerator->enumerate(enumerator, &bridge))
{
@@ -355,26 +379,43 @@ static VALUE bridge_get(VALUE class, VALUE key)
enumerator->destroy(enumerator);
if (!found)
{
- rb_raise(rb_eRuntimeError, "bridge not found");
+ return Qnil;
}
return Data_Wrap_Struct(class, NULL, NULL, found);
}
+static VALUE bridge_get(VALUE class, VALUE key)
+{
+ VALUE bridge = bridge_find(class, key);
+ if (NIL_P(bridge))
+ {
+ rb_raise(rb_eRuntimeError, "bridge not found");
+ }
+ return bridge;
+}
+
static VALUE bridge_each(int argc, VALUE *argv, VALUE class)
{
enumerator_t *enumerator;
+ linked_list_t *list;
bridge_t *bridge;
-
+
if (!rb_block_given_p())
- {
+ {
rb_raise(rb_eArgError, "must be called with a block");
}
+ list = linked_list_create();
enumerator = dumm->create_bridge_enumerator(dumm);
while (enumerator->enumerate(enumerator, &bridge))
{
- rb_yield(Data_Wrap_Struct(class, NULL, NULL, bridge));
+ list->insert_last(list, bridge);
}
enumerator->destroy(enumerator);
+ while (list->remove_first(list, (void**)&bridge) == SUCCESS)
+ {
+ rb_yield(Data_Wrap_Struct(class, NULL, NULL, bridge));
+ }
+ list->destroy(list);
return class;
}
@@ -402,20 +443,27 @@ static VALUE bridge_to_s(VALUE self)
static VALUE bridge_each_iface(int argc, VALUE *argv, VALUE self)
{
enumerator_t *enumerator;
+ linked_list_t *list;
bridge_t *bridge;
iface_t *iface;
-
+
if (!rb_block_given_p())
- {
+ {
rb_raise(rb_eArgError, "must be called with a block");
}
Data_Get_Struct(self, bridge_t, bridge);
+ list = linked_list_create();
enumerator = bridge->create_iface_enumerator(bridge);
while (enumerator->enumerate(enumerator, &iface))
{
- rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
+ list->insert_last(list, iface);
}
enumerator->destroy(enumerator);
+ while (list->remove_first(list, (void**)&iface) == SUCCESS)
+ {
+ rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface));
+ }
+ list->destroy(list);
return self;
}
@@ -437,6 +485,8 @@ static void bridge_init()
rb_define_singleton_method(rbc_bridge, "[]", bridge_get, 1);
rb_define_singleton_method(rbc_bridge, "each", bridge_each, -1);
rb_define_singleton_method(rbc_bridge, "new", bridge_new, 1);
+ rb_define_singleton_method(rbc_bridge, "include?", bridge_find, 1);
+ rb_define_singleton_method(rbc_bridge, "bridge?", bridge_find, 1);
rb_define_method(rbc_bridge, "to_s", bridge_to_s, 0);
rb_define_method(rbc_bridge, "each", bridge_each_iface, -1);
@@ -509,22 +559,29 @@ static VALUE iface_add_addr(VALUE self, VALUE name)
static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
{
enumerator_t *enumerator;
+ linked_list_t *list;
iface_t *iface;
host_t *addr;
char buf[64];
-
+
if (!rb_block_given_p())
- {
+ {
rb_raise(rb_eArgError, "must be called with a block");
}
Data_Get_Struct(self, iface_t, iface);
enumerator = iface->create_address_enumerator(iface);
while (enumerator->enumerate(enumerator, &addr))
{
- snprintf(buf, sizeof(buf), "%H", addr);
- rb_yield(rb_str_new2(buf));
+ list->insert_last(list, addr->clone(addr));
}
enumerator->destroy(enumerator);
+ while (list->remove_first(list, (void**)&addr) == SUCCESS)
+ {
+ snprintf(buf, sizeof(buf), "%H", addr);
+ addr->destroy(addr);
+ rb_yield(rb_str_new2(buf));
+ }
+ list->destroy(list);
return self;
}
@@ -595,12 +652,31 @@ static VALUE template_unload(VALUE class)
return class;
}
+static VALUE template_each(int argc, VALUE *argv, VALUE class)
+{
+ enumerator_t *enumerator;
+ char *template;
+
+ if (!rb_block_given_p())
+ {
+ rb_raise(rb_eArgError, "must be called with a block");
+ }
+ enumerator = dumm->create_template_enumerator(dumm);
+ while (enumerator->enumerate(enumerator, &template))
+ {
+ rb_yield(rb_str_new2(template));
+ }
+ enumerator->destroy(enumerator);
+ return class;
+}
+
static void template_init()
{
rbc_template = rb_define_class_under(rbm_dumm , "Template", rb_cObject);
rb_define_singleton_method(rbc_template, "load", template_load, 1);
rb_define_singleton_method(rbc_template, "unload", template_unload, 0);
+ rb_define_singleton_method(rbc_template, "each", template_each, -1);
}
/**
diff --git a/src/dumm/ext/extconf.rb b/src/dumm/ext/extconf.rb
deleted file mode 100644
index 136be5c2c..000000000
--- a/src/dumm/ext/extconf.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# DUMM for Ruby
-#
-
-require "mkmf"
-
-dir_config("dumm")
-
-unless find_header('library.h', '../../libstrongswan') and
- find_header('dumm.h', '..')
- puts "... failed: one or more header files not found!"
- exit
-end
-
-unless find_library('dumm', 'dumm_create')
- puts "... failed: 'libdumm' not found!"
- exit
-end
-
-create_makefile("dumm")
-
diff --git a/src/dumm/ext/extconf.rb.in b/src/dumm/ext/extconf.rb.in
new file mode 100644
index 000000000..36536ec52
--- /dev/null
+++ b/src/dumm/ext/extconf.rb.in
@@ -0,0 +1,19 @@
+#
+# DUMM for Ruby
+#
+
+require 'mkmf'
+
+$defs << " @DEFS@"
+$CFLAGS << " -Wno-format"
+
+dir_config('dumm', '@top_srcdir@/src/dumm', '../.libs')
+dir_config('strongswan', '@top_srcdir@/src/libstrongswan', '../../libstrongswan/.libs')
+
+unless find_library('dumm', 'dumm_create')
+ puts "... failed: 'libdumm' not found!"
+ exit
+end
+
+create_makefile('dumm', '@top_srcdir@/src/dumm/ext')
+
diff --git a/src/dumm/ext/lib/dumm.rb b/src/dumm/ext/lib/dumm.rb
index 2e860ae9f..25939e9f4 100644
--- a/src/dumm/ext/lib/dumm.rb
+++ b/src/dumm/ext/lib/dumm.rb
@@ -11,11 +11,52 @@
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-
- $Id: dumm.rb 4295 2008-08-27 07:35:20Z tobias $
=end
require 'dumm.so'
require 'dumm/guest'
+module Dumm
+
+ # use guest/bridge indentifiers directly
+ def method_missing(id, *args)
+ if Guest.guest? id
+ return Guest[id]
+ end
+ if Bridge.bridge? id
+ return Bridge[id]
+ end
+ super(id, *args)
+ end
+
+ # shortcut for Template loading
+ def template(name = nil)
+ if name
+ Template.load name
+ else
+ Template.each {|t| puts t }
+ end
+ end
+
+ # unload templates, reset all guests and delete bridges
+ def reset
+ Template.unload
+ Guest.each { |guest|
+ guest.reset if guest.running?
+ }
+ Bridge.each { |bridge|
+ bridge.delete
+ }
+ return Dumm
+ end
+
+ # wait until all running guests have booted up
+ def boot
+ Guest.each {|g|
+ g.boot if g.running?
+ }
+ return Dumm
+ end
+end
+
# vim:sw=2 ts=2 et
diff --git a/src/dumm/ext/lib/dumm/guest.rb b/src/dumm/ext/lib/dumm/guest.rb
index bdd0c33d8..936f512dd 100644
--- a/src/dumm/ext/lib/dumm/guest.rb
+++ b/src/dumm/ext/lib/dumm/guest.rb
@@ -11,8 +11,6 @@
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-
- $Id: guest.rb 4295 2008-08-27 07:35:20Z tobias $
=end
module Dumm
@@ -34,6 +32,30 @@ module Dumm
end
self[id]
end
+
+ # delete all interfaces
+ def reset
+ each {|i|
+ i.delete
+ }
+ end
+
+ # has the guest booted up?
+ def booted?
+ begin
+ exec("pgrep getty")
+ rescue
+ return false
+ end
+ return true
+ end
+
+ # wait until the guest has booted
+ def boot
+ while not booted?
+ sleep(1)
+ end
+ end
end
end
diff --git a/src/dumm/guest.c b/src/dumm/guest.c
index 014a9113f..969a2a99d 100644
--- a/src/dumm/guest.c
+++ b/src/dumm/guest.c
@@ -36,8 +36,8 @@
#include "mconsole.h"
#include "cowfs.h"
-#define PERME (S_IRWXU | S_IRWXG)
-#define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
+#define PERME (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)
+#define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
#define MASTER_DIR "master"
#define DIFF_DIR "diff"
@@ -300,7 +300,6 @@ static bool load_template(private_guest_t *this, char *path)
{
char dir[PATH_MAX];
size_t len;
- iface_t *iface;
if (path == NULL)
{
@@ -324,10 +323,6 @@ static bool load_template(private_guest_t *this, char *path)
{
return FALSE;
}
- while (this->ifaces->remove_last(this->ifaces, (void**)&iface) == SUCCESS)
- {
- iface->destroy(iface);
- }
return TRUE;
}
diff --git a/src/dumm/guest.h b/src/dumm/guest.h
index 19dc8a8bf..a1e4966ac 100644
--- a/src/dumm/guest.h
+++ b/src/dumm/guest.h
@@ -26,7 +26,7 @@ typedef struct guest_t guest_t;
#include "iface.h"
/**
- * @brief State of a guest (started, stopped, ...)
+ * State of a guest (started, stopped, ...)
*/
enum guest_state_t {
/** guest kernel not running at all */
@@ -68,33 +68,33 @@ typedef pid_t (*invoke_function_t)(void *data, guest_t *guest,
typedef void (*idle_function_t)(void);
/**
- * @brief A guest is a UML instance running on the host.
+ * A guest is a UML instance running on the host.
**/
struct guest_t {
/**
- * @brief Get the name of this guest.
+ * Get the name of this guest.
*
* @return name of the guest
*/
char* (*get_name) (guest_t *this);
/**
- * @brief Get the process ID of the guest child process.
+ * Get the process ID of the guest child process.
*
* @return name of the guest
*/
pid_t (*get_pid) (guest_t *this);
/**
- * @brief Get the state of the guest (stopped, started, etc.).
+ * Get the state of the guest (stopped, started, etc.).
*
* @return guests state
*/
guest_state_t (*get_state)(guest_t *this);
/**
- * @brief Start the guest.
+ * Start the guest.
*
* @param invoke UML guest invocation function
* @param data data to pass back to invoke function
@@ -105,14 +105,14 @@ struct guest_t {
idle_function_t idle);
/**
- * @brief Kill the guest.
+ * Kill the guest.
*
* @param idle idle function to call while waiting to termination
*/
void (*stop) (guest_t *this, idle_function_t idle);
/**
- * @brief Create a new interface in the current scenario.
+ * Create a new interface in the current scenario.
*
* @param name name of the interface in the guest
* @return created interface, or NULL if failed
@@ -120,21 +120,21 @@ struct guest_t {
iface_t* (*create_iface)(guest_t *this, char *name);
/**
- * @brief Destroy an interface on guest.
+ * Destroy an interface on guest.
*
* @param iface interface to destroy
*/
void (*destroy_iface)(guest_t *this, iface_t *iface);
/**
- * @brief Create an enumerator over all guest interfaces.
+ * Create an enumerator over all guest interfaces.
*
* @return enumerator over iface_t's
*/
enumerator_t* (*create_iface_enumerator)(guest_t *this);
/**
- * @brief Set the template COWFS overlay to use.
+ * Set the template COWFS overlay to use.
*
* @param parent parent directory where template diff should point to
* @return FALSE if failed
@@ -172,18 +172,18 @@ struct guest_t {
void *data, char *cmd, ...);
/**
- * @brief Called whenever a SIGCHILD for the guests PID is received.
+ * Called whenever a SIGCHILD for the guests PID is received.
*/
void (*sigchild)(guest_t *this);
/**
- * @brief Close and destroy a guest with all interfaces
+ * Close and destroy a guest with all interfaces
*/
void (*destroy) (guest_t *this);
};
/**
- * @brief Create a new, unstarted guest.
+ * Create a new, unstarted guest.
*
* @param parent parent directory to create the guest in
* @param name name of the guest to create
@@ -196,7 +196,7 @@ guest_t *guest_create(char *parent, char *name, char *kernel,
char *master, char *args);
/**
- * @brief Load a guest created with guest_create().
+ * Load a guest created with guest_create().
*
* @param parent parent directory to look for a guest
* @param name name of the guest directory
diff --git a/src/dumm/iface.h b/src/dumm/iface.h
index 54a0554c0..7aef95c01 100644
--- a/src/dumm/iface.h
+++ b/src/dumm/iface.h
@@ -29,19 +29,19 @@ typedef struct iface_t iface_t;
#include "guest.h"
/**
- * @brief Interface in a guest, connected to a tap device on the host.
+ * Interface in a guest, connected to a tap device on the host.
*/
struct iface_t {
/**
- * @brief Get the interface name in the guest (e.g. eth0).
+ * Get the interface name in the guest (e.g. eth0).
*
* @return guest interface name
*/
char* (*get_guestif)(iface_t *this);
/**
- * @brief Get the interface name at the host (e.g. tap0).
+ * Get the interface name at the host (e.g. tap0).
*
* @return host interface (tap device) name
*/
@@ -71,34 +71,34 @@ struct iface_t {
bool (*delete_address)(iface_t *this, host_t *addr);
/**
- * @brief Set the bridge this interface is attached to.
+ * Set the bridge this interface is attached to.
*
* @param bridge assigned bridge, or NULL for none
*/
void (*set_bridge)(iface_t *this, bridge_t *bridge);
/**
- * @brief Get the bridge this iface is connected, or NULL.
+ * Get the bridge this iface is connected, or NULL.
*
* @return connected bridge, or NULL
*/
bridge_t* (*get_bridge)(iface_t *this);
/**
- * @brief Get the guest this iface belongs to.
+ * Get the guest this iface belongs to.
*
* @return guest of this iface
*/
guest_t* (*get_guest)(iface_t *this);
/**
- * @brief Destroy an interface
+ * Destroy an interface
*/
void (*destroy) (iface_t *this);
};
/**
- * @brief Create a new interface for a guest
+ * Create a new interface for a guest
*
* @param name name of the interface in the guest
* @param guest guest this iface is connecting
diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c
index 02db5ab7e..72d6d1b5e 100644
--- a/src/dumm/mconsole.c
+++ b/src/dumm/mconsole.c
@@ -147,8 +147,11 @@ static int request(private_mconsole_t *this, void(*cb)(void*,char*,size_t),
}
else if (reply.err)
{
- DBG1("received mconsole error %d: %*.s",
- reply.err, reply.len, reply.data);
+ if (reply.len && *reply.data)
+ {
+ DBG1("received mconsole error %d: %*.s",
+ reply.err, reply.len, reply.data);
+ }
break;
}
}
diff --git a/src/dumm/mconsole.h b/src/dumm/mconsole.h
index e8493b5bb..a4d93e48e 100644
--- a/src/dumm/mconsole.h
+++ b/src/dumm/mconsole.h
@@ -21,12 +21,12 @@
typedef struct mconsole_t mconsole_t;
/**
- * @brief UML mconsole, change running UML configuration using mconsole.
+ * UML mconsole, change running UML configuration using mconsole.
*/
struct mconsole_t {
/**
- * @brief Create a guest interface and connect it to tap host interface.
+ * Create a guest interface and connect it to tap host interface.
*
* @param guest name of the interface to create in the guest
* @param host name of the tap device to connect guest to
@@ -35,7 +35,7 @@ struct mconsole_t {
bool (*add_iface)(mconsole_t *this, char *guest, char *host);
/**
- * @brief Delete a guest interface.
+ * Delete a guest interface.
*
* @param guest name of the interface to delete on the guest
* @return TRUE if interface deleted
@@ -54,13 +54,13 @@ struct mconsole_t {
char *cmd);
/**
- * @brief Destroy the mconsole instance
+ * Destroy the mconsole instance
*/
void (*destroy) (mconsole_t *this);
};
/**
- * @brief Create a new mconsole connection to a guest.
+ * Create a new mconsole connection to a guest.
*
* Waits for a notification from the guest through the notify socket and tries
* to connect to the mconsole socket supplied in the received notification.
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 25c46e648..7ee0793ec 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -57,6 +57,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -79,6 +80,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -90,6 +94,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -103,6 +108,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -163,6 +170,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -174,6 +182,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -189,8 +198,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
diff --git a/src/ipsec/Makefile.am b/src/ipsec/Makefile.am
index 44964e041..f3ca1ca06 100644
--- a/src/ipsec/Makefile.am
+++ b/src/ipsec/Makefile.am
@@ -12,5 +12,5 @@ ipsec : ipsec.in
-e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:@IPSEC_CONFDIR@:$(confdir):" \
-e "s:@IPSEC_PIDDIR@:$(piddir):" \
- $< > $@
+ $(srcdir)/$@.in > $@
chmod +x $@
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index e32d0e91e..d5a6dc82f 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -65,6 +65,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -87,6 +88,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -98,6 +102,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -111,6 +116,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -171,6 +178,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -182,6 +190,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -197,8 +206,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -258,8 +267,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -438,7 +447,7 @@ ipsec : ipsec.in
-e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:@IPSEC_CONFDIR@:$(confdir):" \
-e "s:@IPSEC_PIDDIR@:$(piddir):" \
- $< > $@
+ $(srcdir)/$@.in > $@
chmod +x $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/ipsec/ipsec.8 b/src/ipsec/ipsec.8
index 5c0835fe4..0cd9914cc 100644
--- a/src/ipsec/ipsec.8
+++ b/src/ipsec/ipsec.8
@@ -1,5 +1,4 @@
.TH IPSEC 8 "9 February 2006"
-.\" RCSID $Id: ipsec.8 3268 2007-10-08 19:59:18Z andreas $
.SH NAME
ipsec \- invoke IPsec utilities
.SH SYNOPSIS
diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in
index 4f2c1caa3..1da3c2d90 100755
--- a/src/ipsec/ipsec.in
+++ b/src/ipsec/ipsec.in
@@ -13,8 +13,6 @@
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
-#
-# RCSID $Id: ipsec.in 4790 2008-12-11 12:49:41Z martin $
# define a minimum PATH environment in case it is not set
PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
@@ -67,7 +65,7 @@ case "$1" in
echo " rereadsecrets|rereadgroups"
echo " rereadcacerts|rereadaacerts|rereadocspcerts"
echo " rereadacerts|rereadcrls|rereadall"
- echo " purgeocsp"
+ echo " purgeocsp|purgeike"
echo " scencrypt|scdecrypt <value> [--inbase <base>] [--outbase <base>] [--keyid <id>]"
echo " openac"
echo " pluto"
@@ -184,6 +182,15 @@ rereadall|purgeocsp)
fi
exit "$rc"
;;
+purgeike)
+ rc=7
+ if [ -e $IPSEC_CHARON_PID ]
+ then
+ $IPSEC_STROKE purgeike
+ rc="$?"
+ fi
+ exit "$rc"
+ ;;
ready)
shift
if [ -e $IPSEC_PLUTO_PID ]
diff --git a/src/libcrypto/Makefile.am b/src/libcrypto/Makefile.am
deleted file mode 100644
index 4416c8daf..000000000
--- a/src/libcrypto/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-noinst_LIBRARIES = libcrypto.a
-libcrypto_a_SOURCES = \
-libaes/aes_xcbc_mac.c libaes/aes_cbc.c libaes/aes_xcbc_mac.h libaes/aes_cbc.h libaes/aes.c libaes/aes.h \
-include/md32_common.h include/cbc_generic.h include/hmac_generic.h libblowfish/bf_skey.c libblowfish/blowfish.h \
-libblowfish/bf_pi.h libblowfish/bf_locl.h libblowfish/bf_enc.c libsha2/hmac_sha2.c libsha2/sha2.h libsha2/hmac_sha2.h \
-libsha2/sha2.c libserpent/serpent_cbc.c libserpent/serpent_cbc.h libserpent/serpent.c libserpent/serpent.h \
-libtwofish/twofish_cbc.h libtwofish/twofish_cbc.c libtwofish/twofish.c libtwofish/twofish.h libdes/des_enc.c \
-libdes/podd.h libdes/sk.h libdes/set_key.c libdes/fcrypt_b.c libdes/fcrypt.c libdes/destest.c \
-libdes/spr.h libdes/cbc_enc.c libdes/ecb_enc.c libdes/des_locl.h libdes/des_ver.h libdes/des.h
-
-INCLUDES = -I$(top_srcdir)/src/libcrypto/include
diff --git a/src/libcrypto/Makefile.in b/src/libcrypto/Makefile.in
deleted file mode 100644
index 0e4b3c7f4..000000000
--- a/src/libcrypto/Makefile.in
+++ /dev/null
@@ -1,741 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/libcrypto
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_CLEAN_FILES =
-LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-libcrypto_a_AR = $(AR) $(ARFLAGS)
-libcrypto_a_LIBADD =
-am_libcrypto_a_OBJECTS = aes_xcbc_mac.$(OBJEXT) aes_cbc.$(OBJEXT) \
- aes.$(OBJEXT) bf_skey.$(OBJEXT) bf_enc.$(OBJEXT) \
- hmac_sha2.$(OBJEXT) sha2.$(OBJEXT) serpent_cbc.$(OBJEXT) \
- serpent.$(OBJEXT) twofish_cbc.$(OBJEXT) twofish.$(OBJEXT) \
- des_enc.$(OBJEXT) set_key.$(OBJEXT) fcrypt_b.$(OBJEXT) \
- fcrypt.$(OBJEXT) destest.$(OBJEXT) cbc_enc.$(OBJEXT) \
- ecb_enc.$(OBJEXT)
-libcrypto_a_OBJECTS = $(am_libcrypto_a_OBJECTS)
-DEFAULT_INCLUDES = -I.@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libcrypto_a_SOURCES)
-DIST_SOURCES = $(libcrypto_a_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GPERF = @GPERF@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
-IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LINUX_HEADERS = @LINUX_HEADERS@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-confdir = @confdir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-ipsecdir = @ipsecdir@
-ipsecgroup = @ipsecgroup@
-ipsecuser = @ipsecuser@
-libdir = @libdir@
-libexecdir = @libexecdir@
-libstrongswan_plugins = @libstrongswan_plugins@
-linuxdir = @linuxdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-nm_CFLAGS = @nm_CFLAGS@
-nm_LIBS = @nm_LIBS@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-piddir = @piddir@
-plugindir = @plugindir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-resolv_conf = @resolv_conf@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-simreader = @simreader@
-srcdir = @srcdir@
-strongswan_conf = @strongswan_conf@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-xml_CFLAGS = @xml_CFLAGS@
-xml_LIBS = @xml_LIBS@
-noinst_LIBRARIES = libcrypto.a
-libcrypto_a_SOURCES = \
-libaes/aes_xcbc_mac.c libaes/aes_cbc.c libaes/aes_xcbc_mac.h libaes/aes_cbc.h libaes/aes.c libaes/aes.h \
-include/md32_common.h include/cbc_generic.h include/hmac_generic.h libblowfish/bf_skey.c libblowfish/blowfish.h \
-libblowfish/bf_pi.h libblowfish/bf_locl.h libblowfish/bf_enc.c libsha2/hmac_sha2.c libsha2/sha2.h libsha2/hmac_sha2.h \
-libsha2/sha2.c libserpent/serpent_cbc.c libserpent/serpent_cbc.h libserpent/serpent.c libserpent/serpent.h \
-libtwofish/twofish_cbc.h libtwofish/twofish_cbc.c libtwofish/twofish.c libtwofish/twofish.h libdes/des_enc.c \
-libdes/podd.h libdes/sk.h libdes/set_key.c libdes/fcrypt_b.c libdes/fcrypt.c libdes/destest.c \
-libdes/spr.h libdes/cbc_enc.c libdes/ecb_enc.c libdes/des_locl.h libdes/des_ver.h libdes/des.h
-
-INCLUDES = -I$(top_srcdir)/src/libcrypto/include
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcrypto/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcrypto/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
-
-clean-noinstLIBRARIES:
- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-libcrypto.a: $(libcrypto_a_OBJECTS) $(libcrypto_a_DEPENDENCIES)
- -rm -f libcrypto.a
- $(libcrypto_a_AR) libcrypto.a $(libcrypto_a_OBJECTS) $(libcrypto_a_LIBADD)
- $(RANLIB) libcrypto.a
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_xcbc_mac.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bf_enc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bf_skey.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cbc_enc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des_enc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/destest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecb_enc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcrypt.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcrypt_b.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_sha2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent_cbc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_key.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish_cbc.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-
-aes_xcbc_mac.o: libaes/aes_xcbc_mac.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_xcbc_mac.o -MD -MP -MF $(DEPDIR)/aes_xcbc_mac.Tpo -c -o aes_xcbc_mac.o `test -f 'libaes/aes_xcbc_mac.c' || echo '$(srcdir)/'`libaes/aes_xcbc_mac.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_xcbc_mac.Tpo $(DEPDIR)/aes_xcbc_mac.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes_xcbc_mac.c' object='aes_xcbc_mac.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_xcbc_mac.o `test -f 'libaes/aes_xcbc_mac.c' || echo '$(srcdir)/'`libaes/aes_xcbc_mac.c
-
-aes_xcbc_mac.obj: libaes/aes_xcbc_mac.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_xcbc_mac.obj -MD -MP -MF $(DEPDIR)/aes_xcbc_mac.Tpo -c -o aes_xcbc_mac.obj `if test -f 'libaes/aes_xcbc_mac.c'; then $(CYGPATH_W) 'libaes/aes_xcbc_mac.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes_xcbc_mac.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_xcbc_mac.Tpo $(DEPDIR)/aes_xcbc_mac.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes_xcbc_mac.c' object='aes_xcbc_mac.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_xcbc_mac.obj `if test -f 'libaes/aes_xcbc_mac.c'; then $(CYGPATH_W) 'libaes/aes_xcbc_mac.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes_xcbc_mac.c'; fi`
-
-aes_cbc.o: libaes/aes_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cbc.o -MD -MP -MF $(DEPDIR)/aes_cbc.Tpo -c -o aes_cbc.o `test -f 'libaes/aes_cbc.c' || echo '$(srcdir)/'`libaes/aes_cbc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_cbc.Tpo $(DEPDIR)/aes_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes_cbc.c' object='aes_cbc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cbc.o `test -f 'libaes/aes_cbc.c' || echo '$(srcdir)/'`libaes/aes_cbc.c
-
-aes_cbc.obj: libaes/aes_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cbc.obj -MD -MP -MF $(DEPDIR)/aes_cbc.Tpo -c -o aes_cbc.obj `if test -f 'libaes/aes_cbc.c'; then $(CYGPATH_W) 'libaes/aes_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes_cbc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_cbc.Tpo $(DEPDIR)/aes_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes_cbc.c' object='aes_cbc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cbc.obj `if test -f 'libaes/aes_cbc.c'; then $(CYGPATH_W) 'libaes/aes_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes_cbc.c'; fi`
-
-aes.o: libaes/aes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes.o -MD -MP -MF $(DEPDIR)/aes.Tpo -c -o aes.o `test -f 'libaes/aes.c' || echo '$(srcdir)/'`libaes/aes.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes.Tpo $(DEPDIR)/aes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes.c' object='aes.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes.o `test -f 'libaes/aes.c' || echo '$(srcdir)/'`libaes/aes.c
-
-aes.obj: libaes/aes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes.obj -MD -MP -MF $(DEPDIR)/aes.Tpo -c -o aes.obj `if test -f 'libaes/aes.c'; then $(CYGPATH_W) 'libaes/aes.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes.Tpo $(DEPDIR)/aes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libaes/aes.c' object='aes.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes.obj `if test -f 'libaes/aes.c'; then $(CYGPATH_W) 'libaes/aes.c'; else $(CYGPATH_W) '$(srcdir)/libaes/aes.c'; fi`
-
-bf_skey.o: libblowfish/bf_skey.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bf_skey.o -MD -MP -MF $(DEPDIR)/bf_skey.Tpo -c -o bf_skey.o `test -f 'libblowfish/bf_skey.c' || echo '$(srcdir)/'`libblowfish/bf_skey.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bf_skey.Tpo $(DEPDIR)/bf_skey.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libblowfish/bf_skey.c' object='bf_skey.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bf_skey.o `test -f 'libblowfish/bf_skey.c' || echo '$(srcdir)/'`libblowfish/bf_skey.c
-
-bf_skey.obj: libblowfish/bf_skey.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bf_skey.obj -MD -MP -MF $(DEPDIR)/bf_skey.Tpo -c -o bf_skey.obj `if test -f 'libblowfish/bf_skey.c'; then $(CYGPATH_W) 'libblowfish/bf_skey.c'; else $(CYGPATH_W) '$(srcdir)/libblowfish/bf_skey.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bf_skey.Tpo $(DEPDIR)/bf_skey.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libblowfish/bf_skey.c' object='bf_skey.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bf_skey.obj `if test -f 'libblowfish/bf_skey.c'; then $(CYGPATH_W) 'libblowfish/bf_skey.c'; else $(CYGPATH_W) '$(srcdir)/libblowfish/bf_skey.c'; fi`
-
-bf_enc.o: libblowfish/bf_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bf_enc.o -MD -MP -MF $(DEPDIR)/bf_enc.Tpo -c -o bf_enc.o `test -f 'libblowfish/bf_enc.c' || echo '$(srcdir)/'`libblowfish/bf_enc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bf_enc.Tpo $(DEPDIR)/bf_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libblowfish/bf_enc.c' object='bf_enc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bf_enc.o `test -f 'libblowfish/bf_enc.c' || echo '$(srcdir)/'`libblowfish/bf_enc.c
-
-bf_enc.obj: libblowfish/bf_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bf_enc.obj -MD -MP -MF $(DEPDIR)/bf_enc.Tpo -c -o bf_enc.obj `if test -f 'libblowfish/bf_enc.c'; then $(CYGPATH_W) 'libblowfish/bf_enc.c'; else $(CYGPATH_W) '$(srcdir)/libblowfish/bf_enc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/bf_enc.Tpo $(DEPDIR)/bf_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libblowfish/bf_enc.c' object='bf_enc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bf_enc.obj `if test -f 'libblowfish/bf_enc.c'; then $(CYGPATH_W) 'libblowfish/bf_enc.c'; else $(CYGPATH_W) '$(srcdir)/libblowfish/bf_enc.c'; fi`
-
-hmac_sha2.o: libsha2/hmac_sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac_sha2.o -MD -MP -MF $(DEPDIR)/hmac_sha2.Tpo -c -o hmac_sha2.o `test -f 'libsha2/hmac_sha2.c' || echo '$(srcdir)/'`libsha2/hmac_sha2.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_sha2.Tpo $(DEPDIR)/hmac_sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libsha2/hmac_sha2.c' object='hmac_sha2.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hmac_sha2.o `test -f 'libsha2/hmac_sha2.c' || echo '$(srcdir)/'`libsha2/hmac_sha2.c
-
-hmac_sha2.obj: libsha2/hmac_sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hmac_sha2.obj -MD -MP -MF $(DEPDIR)/hmac_sha2.Tpo -c -o hmac_sha2.obj `if test -f 'libsha2/hmac_sha2.c'; then $(CYGPATH_W) 'libsha2/hmac_sha2.c'; else $(CYGPATH_W) '$(srcdir)/libsha2/hmac_sha2.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/hmac_sha2.Tpo $(DEPDIR)/hmac_sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libsha2/hmac_sha2.c' object='hmac_sha2.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hmac_sha2.obj `if test -f 'libsha2/hmac_sha2.c'; then $(CYGPATH_W) 'libsha2/hmac_sha2.c'; else $(CYGPATH_W) '$(srcdir)/libsha2/hmac_sha2.c'; fi`
-
-sha2.o: libsha2/sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2.o -MD -MP -MF $(DEPDIR)/sha2.Tpo -c -o sha2.o `test -f 'libsha2/sha2.c' || echo '$(srcdir)/'`libsha2/sha2.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libsha2/sha2.c' object='sha2.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2.o `test -f 'libsha2/sha2.c' || echo '$(srcdir)/'`libsha2/sha2.c
-
-sha2.obj: libsha2/sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2.obj -MD -MP -MF $(DEPDIR)/sha2.Tpo -c -o sha2.obj `if test -f 'libsha2/sha2.c'; then $(CYGPATH_W) 'libsha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/libsha2/sha2.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libsha2/sha2.c' object='sha2.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2.obj `if test -f 'libsha2/sha2.c'; then $(CYGPATH_W) 'libsha2/sha2.c'; else $(CYGPATH_W) '$(srcdir)/libsha2/sha2.c'; fi`
-
-serpent_cbc.o: libserpent/serpent_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT serpent_cbc.o -MD -MP -MF $(DEPDIR)/serpent_cbc.Tpo -c -o serpent_cbc.o `test -f 'libserpent/serpent_cbc.c' || echo '$(srcdir)/'`libserpent/serpent_cbc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/serpent_cbc.Tpo $(DEPDIR)/serpent_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libserpent/serpent_cbc.c' object='serpent_cbc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o serpent_cbc.o `test -f 'libserpent/serpent_cbc.c' || echo '$(srcdir)/'`libserpent/serpent_cbc.c
-
-serpent_cbc.obj: libserpent/serpent_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT serpent_cbc.obj -MD -MP -MF $(DEPDIR)/serpent_cbc.Tpo -c -o serpent_cbc.obj `if test -f 'libserpent/serpent_cbc.c'; then $(CYGPATH_W) 'libserpent/serpent_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libserpent/serpent_cbc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/serpent_cbc.Tpo $(DEPDIR)/serpent_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libserpent/serpent_cbc.c' object='serpent_cbc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o serpent_cbc.obj `if test -f 'libserpent/serpent_cbc.c'; then $(CYGPATH_W) 'libserpent/serpent_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libserpent/serpent_cbc.c'; fi`
-
-serpent.o: libserpent/serpent.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT serpent.o -MD -MP -MF $(DEPDIR)/serpent.Tpo -c -o serpent.o `test -f 'libserpent/serpent.c' || echo '$(srcdir)/'`libserpent/serpent.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/serpent.Tpo $(DEPDIR)/serpent.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libserpent/serpent.c' object='serpent.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o serpent.o `test -f 'libserpent/serpent.c' || echo '$(srcdir)/'`libserpent/serpent.c
-
-serpent.obj: libserpent/serpent.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT serpent.obj -MD -MP -MF $(DEPDIR)/serpent.Tpo -c -o serpent.obj `if test -f 'libserpent/serpent.c'; then $(CYGPATH_W) 'libserpent/serpent.c'; else $(CYGPATH_W) '$(srcdir)/libserpent/serpent.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/serpent.Tpo $(DEPDIR)/serpent.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libserpent/serpent.c' object='serpent.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o serpent.obj `if test -f 'libserpent/serpent.c'; then $(CYGPATH_W) 'libserpent/serpent.c'; else $(CYGPATH_W) '$(srcdir)/libserpent/serpent.c'; fi`
-
-twofish_cbc.o: libtwofish/twofish_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT twofish_cbc.o -MD -MP -MF $(DEPDIR)/twofish_cbc.Tpo -c -o twofish_cbc.o `test -f 'libtwofish/twofish_cbc.c' || echo '$(srcdir)/'`libtwofish/twofish_cbc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/twofish_cbc.Tpo $(DEPDIR)/twofish_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libtwofish/twofish_cbc.c' object='twofish_cbc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o twofish_cbc.o `test -f 'libtwofish/twofish_cbc.c' || echo '$(srcdir)/'`libtwofish/twofish_cbc.c
-
-twofish_cbc.obj: libtwofish/twofish_cbc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT twofish_cbc.obj -MD -MP -MF $(DEPDIR)/twofish_cbc.Tpo -c -o twofish_cbc.obj `if test -f 'libtwofish/twofish_cbc.c'; then $(CYGPATH_W) 'libtwofish/twofish_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libtwofish/twofish_cbc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/twofish_cbc.Tpo $(DEPDIR)/twofish_cbc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libtwofish/twofish_cbc.c' object='twofish_cbc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o twofish_cbc.obj `if test -f 'libtwofish/twofish_cbc.c'; then $(CYGPATH_W) 'libtwofish/twofish_cbc.c'; else $(CYGPATH_W) '$(srcdir)/libtwofish/twofish_cbc.c'; fi`
-
-twofish.o: libtwofish/twofish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT twofish.o -MD -MP -MF $(DEPDIR)/twofish.Tpo -c -o twofish.o `test -f 'libtwofish/twofish.c' || echo '$(srcdir)/'`libtwofish/twofish.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/twofish.Tpo $(DEPDIR)/twofish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libtwofish/twofish.c' object='twofish.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o twofish.o `test -f 'libtwofish/twofish.c' || echo '$(srcdir)/'`libtwofish/twofish.c
-
-twofish.obj: libtwofish/twofish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT twofish.obj -MD -MP -MF $(DEPDIR)/twofish.Tpo -c -o twofish.obj `if test -f 'libtwofish/twofish.c'; then $(CYGPATH_W) 'libtwofish/twofish.c'; else $(CYGPATH_W) '$(srcdir)/libtwofish/twofish.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/twofish.Tpo $(DEPDIR)/twofish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libtwofish/twofish.c' object='twofish.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o twofish.obj `if test -f 'libtwofish/twofish.c'; then $(CYGPATH_W) 'libtwofish/twofish.c'; else $(CYGPATH_W) '$(srcdir)/libtwofish/twofish.c'; fi`
-
-des_enc.o: libdes/des_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT des_enc.o -MD -MP -MF $(DEPDIR)/des_enc.Tpo -c -o des_enc.o `test -f 'libdes/des_enc.c' || echo '$(srcdir)/'`libdes/des_enc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/des_enc.Tpo $(DEPDIR)/des_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/des_enc.c' object='des_enc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o des_enc.o `test -f 'libdes/des_enc.c' || echo '$(srcdir)/'`libdes/des_enc.c
-
-des_enc.obj: libdes/des_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT des_enc.obj -MD -MP -MF $(DEPDIR)/des_enc.Tpo -c -o des_enc.obj `if test -f 'libdes/des_enc.c'; then $(CYGPATH_W) 'libdes/des_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/des_enc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/des_enc.Tpo $(DEPDIR)/des_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/des_enc.c' object='des_enc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o des_enc.obj `if test -f 'libdes/des_enc.c'; then $(CYGPATH_W) 'libdes/des_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/des_enc.c'; fi`
-
-set_key.o: libdes/set_key.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_key.o -MD -MP -MF $(DEPDIR)/set_key.Tpo -c -o set_key.o `test -f 'libdes/set_key.c' || echo '$(srcdir)/'`libdes/set_key.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/set_key.Tpo $(DEPDIR)/set_key.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/set_key.c' object='set_key.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_key.o `test -f 'libdes/set_key.c' || echo '$(srcdir)/'`libdes/set_key.c
-
-set_key.obj: libdes/set_key.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT set_key.obj -MD -MP -MF $(DEPDIR)/set_key.Tpo -c -o set_key.obj `if test -f 'libdes/set_key.c'; then $(CYGPATH_W) 'libdes/set_key.c'; else $(CYGPATH_W) '$(srcdir)/libdes/set_key.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/set_key.Tpo $(DEPDIR)/set_key.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/set_key.c' object='set_key.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o set_key.obj `if test -f 'libdes/set_key.c'; then $(CYGPATH_W) 'libdes/set_key.c'; else $(CYGPATH_W) '$(srcdir)/libdes/set_key.c'; fi`
-
-fcrypt_b.o: libdes/fcrypt_b.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fcrypt_b.o -MD -MP -MF $(DEPDIR)/fcrypt_b.Tpo -c -o fcrypt_b.o `test -f 'libdes/fcrypt_b.c' || echo '$(srcdir)/'`libdes/fcrypt_b.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fcrypt_b.Tpo $(DEPDIR)/fcrypt_b.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/fcrypt_b.c' object='fcrypt_b.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fcrypt_b.o `test -f 'libdes/fcrypt_b.c' || echo '$(srcdir)/'`libdes/fcrypt_b.c
-
-fcrypt_b.obj: libdes/fcrypt_b.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fcrypt_b.obj -MD -MP -MF $(DEPDIR)/fcrypt_b.Tpo -c -o fcrypt_b.obj `if test -f 'libdes/fcrypt_b.c'; then $(CYGPATH_W) 'libdes/fcrypt_b.c'; else $(CYGPATH_W) '$(srcdir)/libdes/fcrypt_b.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fcrypt_b.Tpo $(DEPDIR)/fcrypt_b.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/fcrypt_b.c' object='fcrypt_b.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fcrypt_b.obj `if test -f 'libdes/fcrypt_b.c'; then $(CYGPATH_W) 'libdes/fcrypt_b.c'; else $(CYGPATH_W) '$(srcdir)/libdes/fcrypt_b.c'; fi`
-
-fcrypt.o: libdes/fcrypt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fcrypt.o -MD -MP -MF $(DEPDIR)/fcrypt.Tpo -c -o fcrypt.o `test -f 'libdes/fcrypt.c' || echo '$(srcdir)/'`libdes/fcrypt.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fcrypt.Tpo $(DEPDIR)/fcrypt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/fcrypt.c' object='fcrypt.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fcrypt.o `test -f 'libdes/fcrypt.c' || echo '$(srcdir)/'`libdes/fcrypt.c
-
-fcrypt.obj: libdes/fcrypt.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fcrypt.obj -MD -MP -MF $(DEPDIR)/fcrypt.Tpo -c -o fcrypt.obj `if test -f 'libdes/fcrypt.c'; then $(CYGPATH_W) 'libdes/fcrypt.c'; else $(CYGPATH_W) '$(srcdir)/libdes/fcrypt.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fcrypt.Tpo $(DEPDIR)/fcrypt.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/fcrypt.c' object='fcrypt.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fcrypt.obj `if test -f 'libdes/fcrypt.c'; then $(CYGPATH_W) 'libdes/fcrypt.c'; else $(CYGPATH_W) '$(srcdir)/libdes/fcrypt.c'; fi`
-
-destest.o: libdes/destest.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT destest.o -MD -MP -MF $(DEPDIR)/destest.Tpo -c -o destest.o `test -f 'libdes/destest.c' || echo '$(srcdir)/'`libdes/destest.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/destest.Tpo $(DEPDIR)/destest.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/destest.c' object='destest.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o destest.o `test -f 'libdes/destest.c' || echo '$(srcdir)/'`libdes/destest.c
-
-destest.obj: libdes/destest.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT destest.obj -MD -MP -MF $(DEPDIR)/destest.Tpo -c -o destest.obj `if test -f 'libdes/destest.c'; then $(CYGPATH_W) 'libdes/destest.c'; else $(CYGPATH_W) '$(srcdir)/libdes/destest.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/destest.Tpo $(DEPDIR)/destest.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/destest.c' object='destest.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o destest.obj `if test -f 'libdes/destest.c'; then $(CYGPATH_W) 'libdes/destest.c'; else $(CYGPATH_W) '$(srcdir)/libdes/destest.c'; fi`
-
-cbc_enc.o: libdes/cbc_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cbc_enc.o -MD -MP -MF $(DEPDIR)/cbc_enc.Tpo -c -o cbc_enc.o `test -f 'libdes/cbc_enc.c' || echo '$(srcdir)/'`libdes/cbc_enc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cbc_enc.Tpo $(DEPDIR)/cbc_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/cbc_enc.c' object='cbc_enc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cbc_enc.o `test -f 'libdes/cbc_enc.c' || echo '$(srcdir)/'`libdes/cbc_enc.c
-
-cbc_enc.obj: libdes/cbc_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cbc_enc.obj -MD -MP -MF $(DEPDIR)/cbc_enc.Tpo -c -o cbc_enc.obj `if test -f 'libdes/cbc_enc.c'; then $(CYGPATH_W) 'libdes/cbc_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/cbc_enc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cbc_enc.Tpo $(DEPDIR)/cbc_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/cbc_enc.c' object='cbc_enc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cbc_enc.obj `if test -f 'libdes/cbc_enc.c'; then $(CYGPATH_W) 'libdes/cbc_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/cbc_enc.c'; fi`
-
-ecb_enc.o: libdes/ecb_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ecb_enc.o -MD -MP -MF $(DEPDIR)/ecb_enc.Tpo -c -o ecb_enc.o `test -f 'libdes/ecb_enc.c' || echo '$(srcdir)/'`libdes/ecb_enc.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ecb_enc.Tpo $(DEPDIR)/ecb_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/ecb_enc.c' object='ecb_enc.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ecb_enc.o `test -f 'libdes/ecb_enc.c' || echo '$(srcdir)/'`libdes/ecb_enc.c
-
-ecb_enc.obj: libdes/ecb_enc.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ecb_enc.obj -MD -MP -MF $(DEPDIR)/ecb_enc.Tpo -c -o ecb_enc.obj `if test -f 'libdes/ecb_enc.c'; then $(CYGPATH_W) 'libdes/ecb_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/ecb_enc.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ecb_enc.Tpo $(DEPDIR)/ecb_enc.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libdes/ecb_enc.c' object='ecb_enc.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ecb_enc.obj `if test -f 'libdes/ecb_enc.c'; then $(CYGPATH_W) 'libdes/ecb_enc.c'; else $(CYGPATH_W) '$(srcdir)/libdes/ecb_enc.c'; fi`
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LIBRARIES)
-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:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am
-
-# 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/libcrypto/include/cbc_generic.h b/src/libcrypto/include/cbc_generic.h
deleted file mode 100644
index 0dd3a77d6..000000000
--- a/src/libcrypto/include/cbc_generic.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef _CBC_GENERIC_H
-#define _CBC_GENERIC_H
-/*
- * CBC macro helpers
- *
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- */
-
-/*
- * Heavily inspired in loop_AES
- */
-#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
-int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
- int ret=ilen, pos; \
- const u_int32_t *iv_i; \
- if ((ilen) % 16) return 0; \
- if (encrypt) { \
- pos=0; \
- while(pos<ilen) { \
- if (pos==0) \
- iv_i=(const u_int32_t*) iv; \
- else \
- iv_i=(const u_int32_t*) (out-16); \
- *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
- *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
- *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
- *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
- enc_func(ctx, (addr_type) out, (addr_type) out); \
- in+=16; \
- out+=16; \
- pos+=16; \
- } \
- } else { \
- pos=ilen-16; \
- in+=pos; \
- out+=pos; \
- while(pos>=0) { \
- dec_func(ctx, (const addr_type) in, (addr_type) out); \
- if (pos==0) \
- iv_i=(const u_int32_t*) (iv); \
- else \
- iv_i=(const u_int32_t*) (in-16); \
- *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
- *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
- *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
- *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
- in-=16; \
- out-=16; \
- pos-=16; \
- } \
- } \
- return ret; \
-}
-#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
-int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
- int ret=ilen, pos; \
- const u_int32_t *iv_i; \
- if ((ilen) % 8) return 0; \
- if (encrypt) { \
- pos=0; \
- while(pos<ilen) { \
- if (pos==0) \
- iv_i=(const u_int32_t*) iv; \
- else \
- iv_i=(const u_int32_t*) (out-8); \
- *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
- *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
- enc_func(ctx, (addr_type)out, (addr_type)out); \
- in+=8; \
- out+=8; \
- pos+=8; \
- } \
- } else { \
- pos=ilen-8; \
- in+=pos; \
- out+=pos; \
- while(pos>=0) { \
- dec_func(ctx, (const addr_type)in, (addr_type)out); \
- if (pos==0) \
- iv_i=(const u_int32_t*) (iv); \
- else \
- iv_i=(const u_int32_t*) (in-8); \
- *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
- *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
- in-=8; \
- out-=8; \
- pos-=8; \
- } \
- } \
- return ret; \
-}
-#define CBC_DECL(name, ctx_type) \
-int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
-/*
-Eg.:
-CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
-CBC_DECL(AES_cbc_encrypt, aes_context);
-*/
-#endif /* _CBC_GENERIC_H */
diff --git a/src/libcrypto/include/hmac_generic.h b/src/libcrypto/include/hmac_generic.h
deleted file mode 100644
index a749228e3..000000000
--- a/src/libcrypto/include/hmac_generic.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _HMAC_GENERIC_H
-#define _HMAC_GENERIC_H
-/*
- * HMAC macro helpers
- *
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- */
-
-#ifndef DIVUP
-#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
-#endif
-#ifndef HMAC_IPAD
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5C
-#endif
-#define HMAC_SET_KEY_IMPL(func_name, hctx_t, blocksize, func_init, func_update) \
-void func_name(hctx_t *hctx, const u_int8_t * key, int keylen) { \
- int i;\
- u_int8_t kb[blocksize]; \
- for (i = 0; i < DIVUP(keylen*8, 8); i++) { \
- kb[i] = key[i] ^ HMAC_IPAD; \
- } \
- for (; i < blocksize; i++) { \
- kb[i] = HMAC_IPAD; \
- } \
- func_init(&hctx->ictx); \
- func_update(&hctx->ictx, kb, blocksize); \
- for (i = 0; i < blocksize; i++) { \
- kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); \
- } \
- func_init(&hctx->octx); \
- func_update(&hctx->octx, kb, blocksize); \
-}
-#define HMAC_HASH_IMPL(func_name, hctx_t, ctx_t, ahlen, func_update, func_result ) \
-void func_name(hctx_t *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen) { \
- ctx_t ctx; \
- ctx=hctx->ictx; \
- if (dat) func_update(&ctx, dat, len); \
- if (hash) { \
- u_int8_t hash_buf[ahlen]; \
- func_result(&ctx, hash_buf, ahlen); \
- ctx=hctx->octx; \
- func_update(&ctx, hash_buf, ahlen); \
- func_result(&ctx, hash, hashlen); \
- memset(&ctx, 0, sizeof (ctx)); \
- memset(&hash_buf, 0, sizeof (hash_buf));\
- } \
-}
-#endif /* _HMAC_GENERIC_H */
diff --git a/src/libcrypto/include/md32_common.h b/src/libcrypto/include/md32_common.h
deleted file mode 100644
index 1a404a458..000000000
--- a/src/libcrypto/include/md32_common.h
+++ /dev/null
@@ -1,607 +0,0 @@
-/* crypto/md32_common.h */
-/* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
-/*
- * This is a generic 32 bit "collector" for message digest algorithms.
- * Whenever needed it collects input character stream into chunks of
- * 32 bit values and invokes a block function that performs actual hash
- * calculations.
- *
- * Porting guide.
- *
- * Obligatory macros:
- *
- * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
- * this macro defines byte order of input stream.
- * HASH_CBLOCK
- * size of a unit chunk HASH_BLOCK operates on.
- * HASH_LONG
- * has to be at lest 32 bit wide, if it's wider, then
- * HASH_LONG_LOG2 *has to* be defined along
- * HASH_CTX
- * context structure that at least contains following
- * members:
- * typedef struct {
- * ...
- * HASH_LONG Nl,Nh;
- * HASH_LONG data[HASH_LBLOCK];
- * int num;
- * ...
- * } HASH_CTX;
- * HASH_UPDATE
- * name of "Update" function, implemented here.
- * HASH_TRANSFORM
- * name of "Transform" function, implemented here.
- * HASH_FINAL
- * name of "Final" function, implemented here.
- * HASH_BLOCK_HOST_ORDER
- * name of "block" function treating *aligned* input message
- * in host byte order, implemented externally.
- * HASH_BLOCK_DATA_ORDER
- * name of "block" function treating *unaligned* input message
- * in original (data) byte order, implemented externally (it
- * actually is optional if data and host are of the same
- * "endianess").
- * HASH_MAKE_STRING
- * macro convering context variables to an ASCII hash string.
- *
- * Optional macros:
- *
- * B_ENDIAN or L_ENDIAN
- * defines host byte-order.
- * HASH_LONG_LOG2
- * defaults to 2 if not states otherwise.
- * HASH_LBLOCK
- * assumed to be HASH_CBLOCK/4 if not stated otherwise.
- * HASH_BLOCK_DATA_ORDER_ALIGNED
- * alternative "block" function capable of treating
- * aligned input message in original (data) order,
- * implemented externally.
- *
- * MD5 example:
- *
- * #define DATA_ORDER_IS_LITTLE_ENDIAN
- *
- * #define HASH_LONG MD5_LONG
- * #define HASH_LONG_LOG2 MD5_LONG_LOG2
- * #define HASH_CTX MD5_CTX
- * #define HASH_CBLOCK MD5_CBLOCK
- * #define HASH_LBLOCK MD5_LBLOCK
- * #define HASH_UPDATE MD5_Update
- * #define HASH_TRANSFORM MD5_Transform
- * #define HASH_FINAL MD5_Final
- * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
- * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
- *
- * <appro@fy.chalmers.se>
- */
-
-#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-#error "DATA_ORDER must be defined!"
-#endif
-
-#ifndef HASH_CBLOCK
-#error "HASH_CBLOCK must be defined!"
-#endif
-#ifndef HASH_LONG
-#error "HASH_LONG must be defined!"
-#endif
-#ifndef HASH_CTX
-#error "HASH_CTX must be defined!"
-#endif
-
-#ifndef HASH_UPDATE
-#error "HASH_UPDATE must be defined!"
-#endif
-#ifndef HASH_TRANSFORM
-#error "HASH_TRANSFORM must be defined!"
-#endif
-#ifndef HASH_FINAL
-#error "HASH_FINAL must be defined!"
-#endif
-
-#ifndef HASH_BLOCK_HOST_ORDER
-#error "HASH_BLOCK_HOST_ORDER must be defined!"
-#endif
-
-#if 0
-/*
- * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
- * isn't defined.
- */
-#ifndef HASH_BLOCK_DATA_ORDER
-#error "HASH_BLOCK_DATA_ORDER must be defined!"
-#endif
-#endif
-
-#ifndef HASH_LBLOCK
-#define HASH_LBLOCK (HASH_CBLOCK/4)
-#endif
-
-#ifndef HASH_LONG_LOG2
-#define HASH_LONG_LOG2 2
-#endif
-
-/*
- * Engage compiler specific rotate intrinsic function if available.
- */
-#undef ROTATE
-#ifndef PEDANTIC
-# if defined(_MSC_VER)
-# define ROTATE(a,n) _lrotl(a,n)
-# elif defined(__MWERKS__)
-# if defined(__POWERPC__)
-# define ROTATE(a,n) __rlwinm(a,n,0,31)
-# elif defined(__MC68K__)
- /* Motorola specific tweak. <appro@fy.chalmers.se> */
-# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
-# else
-# define ROTATE(a,n) __rol(a,n)
-# endif
-# elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
- /*
- * Some GNU C inline assembler templates. Note that these are
- * rotates by *constant* number of bits! But that's exactly
- * what we need here...
- *
- * <appro@fy.chalmers.se>
- */
-# if defined(__i386)
-# define ROTATE(a,n) ({ register unsigned int ret; \
- asm ( \
- "roll %1,%0" \
- : "=r"(ret) \
- : "I"(n), "0"(a) \
- : "cc"); \
- ret; \
- })
-# elif defined(__powerpc) || defined(__ppc)
-# define ROTATE(a,n) ({ register unsigned int ret; \
- asm ( \
- "rlwinm %0,%1,%2,0,31" \
- : "=r"(ret) \
- : "r"(a), "I"(n)); \
- ret; \
- })
-# endif
-# endif
-
-/*
- * Engage compiler specific "fetch in reverse byte order"
- * intrinsic function if available.
- */
-# if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
- /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
-# if defined(__i386) && !defined(I386_ONLY)
-# define BE_FETCH32(a) ({ register unsigned int l=(a);\
- asm ( \
- "bswapl %0" \
- : "=r"(l) : "0"(l)); \
- l; \
- })
-# elif defined(__powerpc)
-# define LE_FETCH32(a) ({ register unsigned int l; \
- asm ( \
- "lwbrx %0,0,%1" \
- : "=r"(l) \
- : "r"(a)); \
- l; \
- })
-
-# elif defined(__sparc) && defined(ULTRASPARC)
-# define LE_FETCH32(a) ({ register unsigned int l; \
- asm ( \
- "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
- : "=r"(l) \
- : "r"(a)); \
- l; \
- })
-# endif
-# endif
-#endif /* PEDANTIC */
-
-#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
-/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
-#ifdef ROTATE
-/* 5 instructions with rotate instruction, else 9 */
-#define REVERSE_FETCH32(a,l) ( \
- l=*(const HASH_LONG *)(a), \
- ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
- )
-#else
-/* 6 instructions with rotate instruction, else 8 */
-#define REVERSE_FETCH32(a,l) ( \
- l=*(const HASH_LONG *)(a), \
- l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
- ROTATE(l,16) \
- )
-/*
- * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
- * It's rewritten as above for two reasons:
- * - RISCs aren't good at long constants and have to explicitely
- * compose 'em with several (well, usually 2) instructions in a
- * register before performing the actual operation and (as you
- * already realized:-) having same constant should inspire the
- * compiler to permanently allocate the only register for it;
- * - most modern CPUs have two ALUs, but usually only one has
- * circuitry for shifts:-( this minor tweak inspires compiler
- * to schedule shift instructions in a better way...
- *
- * <appro@fy.chalmers.se>
- */
-#endif
-#endif
-
-#ifndef ROTATE
-#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-#endif
-
-/*
- * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
- * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
- * and host are of the same "endianess". It's possible to mask
- * this with blank #define HASH_BLOCK_DATA_ORDER though...
- *
- * <appro@fy.chalmers.se>
- */
-#if defined(B_ENDIAN)
-# if defined(DATA_ORDER_IS_BIG_ENDIAN)
-# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-# endif
-# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-# ifndef HOST_FETCH32
-# ifdef LE_FETCH32
-# define HOST_FETCH32(p,l) LE_FETCH32(p)
-# elif defined(REVERSE_FETCH32)
-# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-# endif
-# endif
-# endif
-#elif defined(L_ENDIAN)
-# if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-# endif
-# elif defined(DATA_ORDER_IS_BIG_ENDIAN)
-# ifndef HOST_FETCH32
-# ifdef BE_FETCH32
-# define HOST_FETCH32(p,l) BE_FETCH32(p)
-# elif defined(REVERSE_FETCH32)
-# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-# endif
-# endif
-# endif
-#endif
-
-#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
-#ifndef HASH_BLOCK_DATA_ORDER
-#error "HASH_BLOCK_DATA_ORDER must be defined!"
-#endif
-#endif
-
-#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-
-#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
- l|=(((unsigned long)(*((c)++)))<<16), \
- l|=(((unsigned long)(*((c)++)))<< 8), \
- l|=(((unsigned long)(*((c)++))) ), \
- l)
-#define HOST_p_c2l(c,l,n) { \
- switch (n) { \
- case 0: l =((unsigned long)(*((c)++)))<<24; \
- case 1: l|=((unsigned long)(*((c)++)))<<16; \
- case 2: l|=((unsigned long)(*((c)++)))<< 8; \
- case 3: l|=((unsigned long)(*((c)++))); \
- } }
-#define HOST_p_c2l_p(c,l,sc,len) { \
- switch (sc) { \
- case 0: l =((unsigned long)(*((c)++)))<<24; \
- if (--len == 0) break; \
- case 1: l|=((unsigned long)(*((c)++)))<<16; \
- if (--len == 0) break; \
- case 2: l|=((unsigned long)(*((c)++)))<< 8; \
- } }
-/* NOTE the pointer is not incremented at the end of this */
-#define HOST_c2l_p(c,l,n) { \
- l=0; (c)+=n; \
- switch (n) { \
- case 3: l =((unsigned long)(*(--(c))))<< 8; \
- case 2: l|=((unsigned long)(*(--(c))))<<16; \
- case 1: l|=((unsigned long)(*(--(c))))<<24; \
- } }
-#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16)&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
- *((c)++)=(unsigned char)(((l) )&0xff), \
- l)
-
-#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-
-#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
- l|=(((unsigned long)(*((c)++)))<< 8), \
- l|=(((unsigned long)(*((c)++)))<<16), \
- l|=(((unsigned long)(*((c)++)))<<24), \
- l)
-#define HOST_p_c2l(c,l,n) { \
- switch (n) { \
- case 0: l =((unsigned long)(*((c)++))); \
- case 1: l|=((unsigned long)(*((c)++)))<< 8; \
- case 2: l|=((unsigned long)(*((c)++)))<<16; \
- case 3: l|=((unsigned long)(*((c)++)))<<24; \
- } }
-#define HOST_p_c2l_p(c,l,sc,len) { \
- switch (sc) { \
- case 0: l =((unsigned long)(*((c)++))); \
- if (--len == 0) break; \
- case 1: l|=((unsigned long)(*((c)++)))<< 8; \
- if (--len == 0) break; \
- case 2: l|=((unsigned long)(*((c)++)))<<16; \
- } }
-/* NOTE the pointer is not incremented at the end of this */
-#define HOST_c2l_p(c,l,n) { \
- l=0; (c)+=n; \
- switch (n) { \
- case 3: l =((unsigned long)(*(--(c))))<<16; \
- case 2: l|=((unsigned long)(*(--(c))))<< 8; \
- case 1: l|=((unsigned long)(*(--(c)))); \
- } }
-#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16)&0xff), \
- *((c)++)=(unsigned char)(((l)>>24)&0xff), \
- l)
-
-#endif
-
-/*
- * Time for some action:-)
- */
-
-void HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
- {
- const unsigned char *data=data_;
- register HASH_LONG * p;
- register unsigned long l;
- int sw,sc,ew,ec;
-
- if (len==0) return;
-
- l=(c->Nl+(len<<3))&0xffffffffL;
- /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
- * Wei Dai <weidai@eskimo.com> for pointing it out. */
- if (l < c->Nl) /* overflow */
- c->Nh++;
- c->Nh+=(len>>29);
- c->Nl=l;
-
- if (c->num != 0)
- {
- p=c->data;
- sw=c->num>>2;
- sc=c->num&0x03;
-
- if ((c->num+len) >= HASH_CBLOCK)
- {
- l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
- for (; sw<HASH_LBLOCK; sw++)
- {
- HOST_c2l(data,l); p[sw]=l;
- }
- HASH_BLOCK_HOST_ORDER (c,p,1);
- len-=(HASH_CBLOCK-c->num);
- c->num=0;
- /* drop through and do the rest */
- }
- else
- {
- c->num+=len;
- if ((sc+len) < 4) /* ugly, add char's to a word */
- {
- l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
- }
- else
- {
- ew=(c->num>>2);
- ec=(c->num&0x03);
- l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
- for (; sw < ew; sw++)
- {
- HOST_c2l(data,l); p[sw]=l;
- }
- if (ec)
- {
- HOST_c2l_p(data,l,ec); p[sw]=l;
- }
- }
- return;
- }
- }
-
- sw=len/HASH_CBLOCK;
- if (sw > 0)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- /*
- * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
- * only if sizeof(HASH_LONG)==4.
- */
- if ((((unsigned long)data)%4) == 0)
- {
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- while (sw--)
- {
- memcpy (p=c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
- data+=HASH_CBLOCK;
- len-=HASH_CBLOCK;
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- {
- HASH_BLOCK_DATA_ORDER(c,data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
-#endif
- }
-
- if (len!=0)
- {
- p = c->data;
- c->num = len;
- ew=len>>2; /* words to copy */
- ec=len&0x03;
- for (; ew; ew--,p++)
- {
- HOST_c2l(data,l); *p=l;
- }
- HOST_c2l_p(data,l,ec);
- *p=l;
- }
- }
-
-
-void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- if ((((unsigned long)data)%4) == 0)
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- {
- memcpy (c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- HASH_BLOCK_DATA_ORDER (c,data,1);
-#endif
- }
-
-
-void HASH_FINAL (unsigned char *md, HASH_CTX *c)
- {
- register HASH_LONG *p;
- register unsigned long l;
- register int i,j;
- static const unsigned char end[4]={0x80,0x00,0x00,0x00};
- const unsigned char *cp=end;
-
- /* c->num should definitly have room for at least one more byte. */
- p=c->data;
- i=c->num>>2;
- j=c->num&0x03;
-
-#if 0
- /* purify often complains about the following line as an
- * Uninitialized Memory Read. While this can be true, the
- * following p_c2l macro will reset l when that case is true.
- * This is because j&0x03 contains the number of 'valid' bytes
- * already in p[i]. If and only if j&0x03 == 0, the UMR will
- * occur but this is also the only time p_c2l will do
- * l= *(cp++) instead of l|= *(cp++)
- * Many thanks to Alex Tang <altitude@cic.net> for pickup this
- * 'potential bug' */
-#ifdef PURIFY
- if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
-#endif
- l=p[i];
-#else
- l = (j==0) ? 0 : p[i];
-#endif
- HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
-
- if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
- {
- if (i<HASH_LBLOCK) p[i]=0;
- HASH_BLOCK_HOST_ORDER (c,p,1);
- i=0;
- }
- for (; i<(HASH_LBLOCK-2); i++)
- p[i]=0;
-
-#if defined(DATA_ORDER_IS_BIG_ENDIAN)
- p[HASH_LBLOCK-2]=c->Nh;
- p[HASH_LBLOCK-1]=c->Nl;
-#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
- p[HASH_LBLOCK-2]=c->Nl;
- p[HASH_LBLOCK-1]=c->Nh;
-#endif
- HASH_BLOCK_HOST_ORDER (c,p,1);
-
-#ifndef HASH_MAKE_STRING
-#error "HASH_MAKE_STRING must be defined!"
-#else
- HASH_MAKE_STRING(c,md);
-#endif
-
- c->num=0;
- /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
- * but I'm not worried :-)
- memset((void *)c,0,sizeof(HASH_CTX));
- */
- }
diff --git a/src/libcrypto/libaes/aes.c b/src/libcrypto/libaes/aes.c
deleted file mode 100644
index 1748119ac..000000000
--- a/src/libcrypto/libaes/aes.c
+++ /dev/null
@@ -1,1415 +0,0 @@
-// I retain copyright in this code but I encourage its free use provided
-// that I don't carry any responsibility for the results. I am especially
-// happy to see it used in free and open source software. If you do use
-// it I would appreciate an acknowledgement of its origin in the code or
-// the product that results and I would also appreciate knowing a little
-// about the use to which it is being put. I am grateful to Frank Yellin
-// for some ideas that are used in this implementation.
-//
-// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-//
-// This is an implementation of the AES encryption algorithm (Rijndael)
-// designed by Joan Daemen and Vincent Rijmen. This version is designed
-// to provide both fixed and dynamic block and key lengths and can also
-// run with either big or little endian internal byte order (see aes.h).
-// It inputs block and key lengths in bytes with the legal values being
-// 16, 24 and 32.
-
-/*
- * Modified by Jari Ruusu, May 1 2001
- * - Fixed some compile warnings, code was ok but gcc warned anyway.
- * - Changed basic types: byte -> unsigned char, word -> u_int32_t
- * - Major name space cleanup: Names visible to outside now begin
- * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
- * - Removed C++ and DLL support as part of name space cleanup.
- * - Eliminated unnecessary recomputation of tables. (actual bug fix)
- * - Merged precomputed constant tables to aes.c file.
- * - Removed data alignment restrictions for portability reasons.
- * - Made block and key lengths accept bit count (128/192/256)
- * as well byte count (16/24/32).
- * - Removed all error checks. This change also eliminated the need
- * to preinitialize the context struct to zero.
- * - Removed some totally unused constants.
- */
-
-#include "aes.h"
-
-// CONFIGURATION OPTIONS (see also aes.h)
-//
-// 1. Define UNROLL for full loop unrolling in encryption and decryption.
-// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
-// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
-// 4. Define FF_TABLES to use tables for field multiplies and inverses.
-// Do not enable this without understanding stack space requirements.
-// 5. Define ARRAYS to use arrays to hold the local state block. If this
-// is not defined, individually declared 32-bit words are used.
-// 6. Define FAST_VARIABLE if a high speed variable block implementation
-// is needed (essentially three separate fixed block size code sequences)
-// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
-// version using 1 table (2 kbytes of table space) or 4 tables (8
-// kbytes of table space) for higher speed.
-// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
-// increase by using tables for the last rounds but with more table
-// space (2 or 8 kbytes extra).
-// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
-// slower version is provided.
-// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
-// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
-
-#define UNROLL
-//#define PARTIAL_UNROLL
-
-#define FIXED_TABLES
-//#define FF_TABLES
-//#define ARRAYS
-#define FAST_VARIABLE
-
-//#define ONE_TABLE
-#define FOUR_TABLES
-
-//#define ONE_LR_TABLE
-#define FOUR_LR_TABLES
-
-//#define ONE_IM_TABLE
-#define FOUR_IM_TABLES
-
-#if defined(UNROLL) && defined (PARTIAL_UNROLL)
-#error both UNROLL and PARTIAL_UNROLL are defined
-#endif
-
-#if defined(ONE_TABLE) && defined (FOUR_TABLES)
-#error both ONE_TABLE and FOUR_TABLES are defined
-#endif
-
-#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
-#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
-#endif
-
-#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
-#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
-#endif
-
-#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
-#error an illegal block size has been specified
-#endif
-
-// upr(x,n): rotates bytes within words by n positions, moving bytes
-// to higher index positions with wrap around into low positions
-// ups(x,n): moves bytes by n positions to higher index positions in
-// words but without wrap around
-// bval(x,n): extracts a byte from a word
-
-#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
-#define ups(x,n) ((x) << 8 * (n))
-#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
-#define bytes2word(b0, b1, b2, b3) \
- ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
-
-
-/* little endian processor without data alignment restrictions: AES_LE_OK */
-/* original code: i386 */
-#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
-#define AES_LE_OK 1
-/* added (tested): alpha --jjo */
-#elif defined(__alpha__)|| defined (__alpha)
-#define AES_LE_OK 1
-/* added (tested): ia64 --jjo */
-#elif defined(__ia64__)|| defined (__ia64)
-#define AES_LE_OK 1
-#endif
-
-#ifdef AES_LE_OK
-/* little endian processor without data alignment restrictions */
-#define word_in(x) *(u_int32_t*)(x)
-#define const_word_in(x) *(const u_int32_t*)(x)
-#define word_out(x,v) *(u_int32_t*)(x) = (v)
-#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
-#else
-/* slower but generic big endian or with data alignment restrictions */
-/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
-#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
-#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
-#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
-#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
-#endif
-
-// Disable at least some poor combinations of options
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-#define FIXED_TABLES
-#undef UNROLL
-#undef ONE_LR_TABLE
-#undef FOUR_LR_TABLES
-#undef ONE_IM_TABLE
-#undef FOUR_IM_TABLES
-#elif !defined(FOUR_TABLES)
-#ifdef FOUR_LR_TABLES
-#undef FOUR_LR_TABLES
-#define ONE_LR_TABLE
-#endif
-#ifdef FOUR_IM_TABLES
-#undef FOUR_IM_TABLES
-#define ONE_IM_TABLE
-#endif
-#elif !defined(AES_BLOCK_SIZE)
-#if defined(UNROLL)
-#define PARTIAL_UNROLL
-#undef UNROLL
-#endif
-#endif
-
-// the finite field modular polynomial and elements
-
-#define ff_poly 0x011b
-#define ff_hi 0x80
-
-// multiply four bytes in GF(2^8) by 'x' {02} in parallel
-
-#define m1 0x80808080
-#define m2 0x7f7f7f7f
-#define m3 0x0000001b
-#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
-
-// The following defines provide alternative definitions of FFmulX that might
-// give improved performance if a fast 32-bit multiply is not available. Note
-// that a temporary variable u needs to be defined where FFmulX is used.
-
-// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-// #define m4 0x1b1b1b1b
-// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-
-// perform column mix operation on four bytes in parallel
-
-#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
-
-#if defined(FIXED_TABLES)
-
-// the S-Box table
-
-static const unsigned char s_box[256] =
-{
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-// the inverse S-Box table
-
-static const unsigned char inv_s_box[256] =
-{
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
- 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
- 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
- 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
- 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
- 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
- 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
- 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
- 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
- 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
- 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
- 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
- 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
- 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
- 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
- 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-};
-
-#define w0(p) 0x000000##p
-
-// Number of elements required in this table for different
-// block and key lengths is:
-//
-// Nk = 4 6 8
-// ----------
-// Nb = 4 | 10 8 7
-// 6 | 19 12 11
-// 8 | 29 19 14
-//
-// this table can be a table of bytes if the key schedule
-// code is adjusted accordingly
-
-static const u_int32_t rcon_tab[29] =
-{
- w0(01), w0(02), w0(04), w0(08),
- w0(10), w0(20), w0(40), w0(80),
- w0(1b), w0(36), w0(6c), w0(d8),
- w0(ab), w0(4d), w0(9a), w0(2f),
- w0(5e), w0(bc), w0(63), w0(c6),
- w0(97), w0(35), w0(6a), w0(d4),
- w0(b3), w0(7d), w0(fa), w0(ef),
- w0(c5)
-};
-
-#undef w0
-
-#define r0(p,q,r,s) 0x##p##q##r##s
-#define r1(p,q,r,s) 0x##q##r##s##p
-#define r2(p,q,r,s) 0x##r##s##p##q
-#define r3(p,q,r,s) 0x##s##p##q##r
-#define w0(p) 0x000000##p
-#define w1(p) 0x0000##p##00
-#define w2(p) 0x00##p##0000
-#define w3(p) 0x##p##000000
-
-#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
-
-// data for forward tables (other than last round)
-
-#define f_table \
- r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
- r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
- r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
- r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
- r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
- r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
- r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
- r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
- r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
- r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
- r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
- r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
- r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
- r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
- r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
- r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
- r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
- r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
- r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
- r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
- r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
- r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
- r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
- r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
- r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
- r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
- r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
- r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
- r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
- r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
- r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
- r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
- r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
- r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
- r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
- r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
- r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
- r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
- r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
- r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
- r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
- r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
- r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
- r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
- r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
- r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
- r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
- r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
- r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
- r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
- r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
- r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
- r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
- r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
- r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
- r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
- r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
- r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
- r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
- r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
- r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
- r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
- r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
- r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
-
-// data for inverse tables (other than last round)
-
-#define i_table \
- r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
- r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
- r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
- r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
- r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
- r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
- r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
- r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
- r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
- r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
- r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
- r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
- r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
- r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
- r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
- r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
- r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
- r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
- r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
- r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
- r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
- r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
- r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
- r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
- r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
- r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
- r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
- r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
- r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
- r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
- r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
- r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
- r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
- r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
- r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
- r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
- r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
- r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
- r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
- r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
- r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
- r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
- r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
- r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
- r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
- r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
- r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
- r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
- r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
- r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
- r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
- r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
- r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
- r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
- r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
- r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
- r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
- r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
- r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
- r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
- r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
- r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
- r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
- r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
-
-// generate the required tables in the desired endian format
-
-#undef r
-#define r r0
-
-#if defined(ONE_TABLE)
-static const u_int32_t ft_tab[256] =
- { f_table };
-#elif defined(FOUR_TABLES)
-static const u_int32_t ft_tab[4][256] =
-{ { f_table },
-#undef r
-#define r r1
- { f_table },
-#undef r
-#define r r2
- { f_table },
-#undef r
-#define r r3
- { f_table }
-};
-#endif
-
-#undef r
-#define r r0
-#if defined(ONE_TABLE)
-static const u_int32_t it_tab[256] =
- { i_table };
-#elif defined(FOUR_TABLES)
-static const u_int32_t it_tab[4][256] =
-{ { i_table },
-#undef r
-#define r r1
- { i_table },
-#undef r
-#define r r2
- { i_table },
-#undef r
-#define r r3
- { i_table }
-};
-#endif
-
-#endif
-
-#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
-
-// data for inverse tables (last round)
-
-#define li_table \
- w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
- w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
- w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
- w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
- w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
- w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
- w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
- w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
- w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
- w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
- w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
- w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
- w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
- w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
- w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
- w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
- w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
- w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
- w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
- w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
- w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
- w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
- w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
- w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
- w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
- w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
- w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
- w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
- w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
- w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
- w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
- w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
-
-// generate the required tables in the desired endian format
-
-#undef r
-#define r(p,q,r,s) w0(q)
-#if defined(ONE_LR_TABLE)
-static const u_int32_t fl_tab[256] =
- { f_table };
-#elif defined(FOUR_LR_TABLES)
-static const u_int32_t fl_tab[4][256] =
-{ { f_table },
-#undef r
-#define r(p,q,r,s) w1(q)
- { f_table },
-#undef r
-#define r(p,q,r,s) w2(q)
- { f_table },
-#undef r
-#define r(p,q,r,s) w3(q)
- { f_table }
-};
-#endif
-
-#undef w
-#define w w0
-#if defined(ONE_LR_TABLE)
-static const u_int32_t il_tab[256] =
- { li_table };
-#elif defined(FOUR_LR_TABLES)
-static const u_int32_t il_tab[4][256] =
-{ { li_table },
-#undef w
-#define w w1
- { li_table },
-#undef w
-#define w w2
- { li_table },
-#undef w
-#define w w3
- { li_table }
-};
-#endif
-
-#endif
-
-#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
-
-#define m_table \
- r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
- r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
- r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
- r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
- r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
- r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
- r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
- r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
- r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
- r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
- r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
- r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
- r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
- r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
- r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
- r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
- r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
- r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
- r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
- r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
- r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
- r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
- r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
- r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
- r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
- r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
- r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
- r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
- r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
- r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
- r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
- r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
- r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
- r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
- r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
- r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
- r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
- r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
- r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
- r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
- r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
- r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
- r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
- r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
- r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
- r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
- r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
- r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
- r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
- r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
- r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
- r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
- r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
- r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
- r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
- r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
- r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
- r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
- r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
- r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
- r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
- r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
- r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
- r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
-
-#undef r
-#define r r0
-
-#if defined(ONE_IM_TABLE)
-static const u_int32_t im_tab[256] =
- { m_table };
-#elif defined(FOUR_IM_TABLES)
-static const u_int32_t im_tab[4][256] =
-{ { m_table },
-#undef r
-#define r r1
- { m_table },
-#undef r
-#define r r2
- { m_table },
-#undef r
-#define r r3
- { m_table }
-};
-#endif
-
-#endif
-
-#else
-
-static int tab_gen = 0;
-
-static unsigned char s_box[256]; // the S box
-static unsigned char inv_s_box[256]; // the inverse S box
-static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
-
-#if defined(ONE_TABLE)
-static u_int32_t ft_tab[256];
-static u_int32_t it_tab[256];
-#elif defined(FOUR_TABLES)
-static u_int32_t ft_tab[4][256];
-static u_int32_t it_tab[4][256];
-#endif
-
-#if defined(ONE_LR_TABLE)
-static u_int32_t fl_tab[256];
-static u_int32_t il_tab[256];
-#elif defined(FOUR_LR_TABLES)
-static u_int32_t fl_tab[4][256];
-static u_int32_t il_tab[4][256];
-#endif
-
-#if defined(ONE_IM_TABLE)
-static u_int32_t im_tab[256];
-#elif defined(FOUR_IM_TABLES)
-static u_int32_t im_tab[4][256];
-#endif
-
-// Generate the tables for the dynamic table option
-
-#if !defined(FF_TABLES)
-
-// It will generally be sensible to use tables to compute finite
-// field multiplies and inverses but where memory is scarse this
-// code might sometimes be better.
-
-// return 2 ^ (n - 1) where n is the bit number of the highest bit
-// set in x with x in the range 1 < x < 0x00000200. This form is
-// used so that locals within FFinv can be bytes rather than words
-
-static unsigned char hibit(const u_int32_t x)
-{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
-
- r |= (r >> 2);
- r |= (r >> 4);
- return (r + 1) >> 1;
-}
-
-// return the inverse of the finite field element x
-
-static unsigned char FFinv(const unsigned char x)
-{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
- if(x < 2) return x;
-
- for(;;)
- {
- if(!n1) return v1;
-
- while(n2 >= n1)
- {
- n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
- }
-
- if(!n2) return v2;
-
- while(n1 >= n2)
- {
- n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
- }
- }
-}
-
-// define the finite field multiplies required for Rijndael
-
-#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
-#define FFmul03(x) ((x) ^ FFmul02(x))
-#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
-#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
-#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
-#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
-
-#else
-
-#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
-
-#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
-#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
-#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
-#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
-#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
-#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
-
-#endif
-
-// The forward and inverse affine transformations used in the S-box
-
-#define fwd_affine(x) \
- (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
-
-#define inv_affine(x) \
- (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
-
-static void gen_tabs(void)
-{ u_int32_t i, w;
-
-#if defined(FF_TABLES)
-
- unsigned char pow[512], log[256];
-
- // log and power tables for GF(2^8) finite field with
- // 0x011b as modular polynomial - the simplest primitive
- // root is 0x03, used here to generate the tables
-
- i = 0; w = 1;
- do
- {
- pow[i] = (unsigned char)w;
- pow[i + 255] = (unsigned char)w;
- log[w] = (unsigned char)i++;
- w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
- }
- while (w != 1);
-
-#endif
-
- for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
- {
- rcon_tab[i] = bytes2word(w, 0, 0, 0);
- w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
- }
-
- for(i = 0; i < 256; ++i)
- { unsigned char b;
-
- s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
-
- w = bytes2word(b, 0, 0, 0);
-#if defined(ONE_LR_TABLE)
- fl_tab[i] = w;
-#elif defined(FOUR_LR_TABLES)
- fl_tab[0][i] = w;
- fl_tab[1][i] = upr(w,1);
- fl_tab[2][i] = upr(w,2);
- fl_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(FFmul02(b), b, b, FFmul03(b));
-#if defined(ONE_TABLE)
- ft_tab[i] = w;
-#elif defined(FOUR_TABLES)
- ft_tab[0][i] = w;
- ft_tab[1][i] = upr(w,1);
- ft_tab[2][i] = upr(w,2);
- ft_tab[3][i] = upr(w,3);
-#endif
- inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
-
- w = bytes2word(b, 0, 0, 0);
-#if defined(ONE_LR_TABLE)
- il_tab[i] = w;
-#elif defined(FOUR_LR_TABLES)
- il_tab[0][i] = w;
- il_tab[1][i] = upr(w,1);
- il_tab[2][i] = upr(w,2);
- il_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
-#if defined(ONE_TABLE)
- it_tab[i] = w;
-#elif defined(FOUR_TABLES)
- it_tab[0][i] = w;
- it_tab[1][i] = upr(w,1);
- it_tab[2][i] = upr(w,2);
- it_tab[3][i] = upr(w,3);
-#endif
-#if defined(ONE_IM_TABLE)
- im_tab[b] = w;
-#elif defined(FOUR_IM_TABLES)
- im_tab[0][b] = w;
- im_tab[1][b] = upr(w,1);
- im_tab[2][b] = upr(w,2);
- im_tab[3][b] = upr(w,3);
-#endif
-
- }
-}
-
-#endif
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
- box[bval(vf(x,0,c),rf(0,c))], \
- box[bval(vf(x,1,c),rf(1,c))], \
- box[bval(vf(x,2,c),rf(2,c))], \
- box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- ( tab[bval(vf(x,0,c),rf(0,c))] \
- ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
- ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
- ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- ( tab[0][bval(vf(x,0,c),rf(0,c))] \
- ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
- ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
- ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c) (x)
-#define rf1(r,c) (r)
-#define rf2(r,c) ((r-c)&3)
-
-#if defined(FOUR_LR_TABLES)
-#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
-#elif defined(ONE_LR_TABLE)
-#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
-#else
-#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
-#endif
-
-#if defined(FOUR_IM_TABLES)
-#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
-#elif defined(ONE_IM_TABLE)
-#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
-#else
-#define inv_mcol(x) \
- (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
- f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-#endif
-
-// Subroutine to set the block size (if variable) in bytes, legal
-// values being 16, 24 and 32.
-
-#if defined(AES_BLOCK_SIZE)
-#define nc (AES_BLOCK_SIZE / 4)
-#else
-#define nc (cx->aes_Ncol)
-
-void aes_set_blk(aes_context *cx, int n_bytes)
-{
-#if !defined(FIXED_TABLES)
- if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-#endif
-
- switch(n_bytes) {
- case 32: /* bytes */
- case 256: /* bits */
- nc = 8;
- break;
- case 24: /* bytes */
- case 192: /* bits */
- nc = 6;
- break;
- case 16: /* bytes */
- case 128: /* bits */
- default:
- nc = 4;
- break;
- }
-}
-
-#endif
-
-// Initialise the key schedule from the user supplied key. The key
-// length is now specified in bytes - 16, 24 or 32 as appropriate.
-// This corresponds to bit lengths of 128, 192 and 256 bits, and
-// to Nk values of 4, 6 and 8 respectively.
-
-#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-#define cp(t,f) *t++ = *f++
-
-#if AES_BLOCK_SIZE == 16
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#elif AES_BLOCK_SIZE == 24
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s)
-#elif AES_BLOCK_SIZE == 32
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#else
-
-#define cpy(d,s) \
-switch(nc) \
-{ case 8: cp(d,s); cp(d,s); \
- case 6: cp(d,s); cp(d,s); \
- case 4: cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s); \
-}
-
-#define mix(d,s) \
-switch(nc) \
-{ case 8: mx(d,s); mx(d,s); \
- case 6: mx(d,s); mx(d,s); \
- case 4: mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s); \
-}
-
-#endif
-
-void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
-{ u_int32_t *kf, *kt, rci;
-
-#if !defined(FIXED_TABLES)
- if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-#endif
-
- switch(n_bytes) {
- case 32: /* bytes */
- case 256: /* bits */
- cx->aes_Nkey = 8;
- break;
- case 24: /* bytes */
- case 192: /* bits */
- cx->aes_Nkey = 6;
- break;
- case 16: /* bytes */
- case 128: /* bits */
- default:
- cx->aes_Nkey = 4;
- break;
- }
-
- cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
-
- cx->aes_e_key[0] = const_word_in(in_key );
- cx->aes_e_key[1] = const_word_in(in_key + 4);
- cx->aes_e_key[2] = const_word_in(in_key + 8);
- cx->aes_e_key[3] = const_word_in(in_key + 12);
-
- kf = cx->aes_e_key;
- kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
- rci = 0;
-
- switch(cx->aes_Nkey)
- {
- case 4: do
- { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
- kf[5] = kf[1] ^ kf[4];
- kf[6] = kf[2] ^ kf[5];
- kf[7] = kf[3] ^ kf[6];
- kf += 4;
- }
- while(kf < kt);
- break;
-
- case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
- cx->aes_e_key[5] = const_word_in(in_key + 20);
- do
- { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
- kf[ 7] = kf[1] ^ kf[ 6];
- kf[ 8] = kf[2] ^ kf[ 7];
- kf[ 9] = kf[3] ^ kf[ 8];
- kf[10] = kf[4] ^ kf[ 9];
- kf[11] = kf[5] ^ kf[10];
- kf += 6;
- }
- while(kf < kt);
- break;
-
- case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
- cx->aes_e_key[5] = const_word_in(in_key + 20);
- cx->aes_e_key[6] = const_word_in(in_key + 24);
- cx->aes_e_key[7] = const_word_in(in_key + 28);
- do
- { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
- kf[ 9] = kf[1] ^ kf[ 8];
- kf[10] = kf[2] ^ kf[ 9];
- kf[11] = kf[3] ^ kf[10];
- kf[12] = kf[4] ^ ls_box(kf[11],0);
- kf[13] = kf[5] ^ kf[12];
- kf[14] = kf[6] ^ kf[13];
- kf[15] = kf[7] ^ kf[14];
- kf += 8;
- }
- while (kf < kt);
- break;
- }
-
- if(!f)
- { u_int32_t i;
-
- kt = cx->aes_d_key + nc * cx->aes_Nrnd;
- kf = cx->aes_e_key;
-
- cpy(kt, kf); kt -= 2 * nc;
-
- for(i = 1; i < cx->aes_Nrnd; ++i)
- {
-#if defined(ONE_TABLE) || defined(FOUR_TABLES)
-#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
- u_int32_t f2, f4, f8, f9;
-#endif
- mix(kt, kf);
-#else
- cpy(kt, kf);
-#endif
- kt -= 2 * nc;
- }
-
- cpy(kt, kf);
- }
-}
-
-// y = output word, x = input word, r = row, c = column
-// for r = 0, 1, 2 and 3 = column accessed for row r
-
-#if defined(ARRAYS)
-#define s(x,c) x[c]
-#else
-#define s(x,c) x##c
-#endif
-
-// I am grateful to Frank Yellin for the following constructions
-// which, given the column (c) of the output state variable that
-// is being computed, return the input state variables which are
-// needed for each row (r) of the state
-
-// For the fixed block size options, compilers reduce these two
-// expressions to fixed variable references. For variable block
-// size code conditional clauses will sometimes be returned
-
-#define unused 77 // Sunset Strip
-
-#define fwd_var(x,r,c) \
- ( r==0 ? \
- ( c==0 ? s(x,0) \
- : c==1 ? s(x,1) \
- : c==2 ? s(x,2) \
- : c==3 ? s(x,3) \
- : c==4 ? s(x,4) \
- : c==5 ? s(x,5) \
- : c==6 ? s(x,6) \
- : s(x,7)) \
- : r==1 ? \
- ( c==0 ? s(x,1) \
- : c==1 ? s(x,2) \
- : c==2 ? s(x,3) \
- : c==3 ? nc==4 ? s(x,0) : s(x,4) \
- : c==4 ? s(x,5) \
- : c==5 ? nc==8 ? s(x,6) : s(x,0) \
- : c==6 ? s(x,7) \
- : s(x,0)) \
- : r==2 ? \
- ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
- : c==1 ? nc==8 ? s(x,4) : s(x,3) \
- : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
- : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
- : c==4 ? nc==8 ? s(x,7) : s(x,0) \
- : c==5 ? nc==8 ? s(x,0) : s(x,1) \
- : c==6 ? s(x,1) \
- : s(x,2)) \
- : \
- ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
- : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
- : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
- : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
- : c==4 ? nc==8 ? s(x,0) : s(x,1) \
- : c==5 ? nc==8 ? s(x,1) : s(x,2) \
- : c==6 ? s(x,2) \
- : s(x,3)))
-
-#define inv_var(x,r,c) \
- ( r==0 ? \
- ( c==0 ? s(x,0) \
- : c==1 ? s(x,1) \
- : c==2 ? s(x,2) \
- : c==3 ? s(x,3) \
- : c==4 ? s(x,4) \
- : c==5 ? s(x,5) \
- : c==6 ? s(x,6) \
- : s(x,7)) \
- : r==1 ? \
- ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
- : c==1 ? s(x,0) \
- : c==2 ? s(x,1) \
- : c==3 ? s(x,2) \
- : c==4 ? s(x,3) \
- : c==5 ? s(x,4) \
- : c==6 ? s(x,5) \
- : s(x,6)) \
- : r==2 ? \
- ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
- : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
- : c==2 ? nc==8 ? s(x,7) : s(x,0) \
- : c==3 ? nc==8 ? s(x,0) : s(x,1) \
- : c==4 ? nc==8 ? s(x,1) : s(x,2) \
- : c==5 ? nc==8 ? s(x,2) : s(x,3) \
- : c==6 ? s(x,3) \
- : s(x,4)) \
- : \
- ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
- : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
- : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
- : c==3 ? nc==8 ? s(x,7) : s(x,0) \
- : c==4 ? nc==8 ? s(x,0) : s(x,1) \
- : c==5 ? nc==8 ? s(x,1) : s(x,2) \
- : c==6 ? s(x,2) \
- : s(x,3)))
-
-#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c) word_out(y + 4 * c, s(x,c))
-
-#if defined(FOUR_TABLES)
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(ONE_TABLE)
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(FOUR_LR_TABLES)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(ONE_LR_TABLE)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-#endif
-
-#if AES_BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x) x[4],y[4]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-// the following defines prevent the compiler requiring the declaration
-// of generated but unused variables in the fwd_var and inv_var macros
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif AES_BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x) x[6],y[6]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
- y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
- si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
- so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
- rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x) x[8],y[8]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
- y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5); \
- s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if AES_BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
- si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
- so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
- rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{ case 8: si(y,x,k,7); si(y,x,k,6); \
- case 6: si(y,x,k,5); si(y,x,k,4); \
- case 4: si(y,x,k,3); si(y,x,k,2); \
- si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{ case 8: so(y,x,7); so(y,x,6); \
- case 6: so(y,x,5); so(y,x,4); \
- case 4: so(y,x,3); so(y,x,2); \
- so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-{ u_int32_t locals(b0, b1);
- const u_int32_t *kp = cx->aes_e_key;
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
- u_int32_t f2;
-#endif
-
- state_in(b0, in_blk, kp); kp += nc;
-
-#if defined(UNROLL)
-
- switch(cx->aes_Nrnd)
- {
- case 14: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 12: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 10: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc);
- round(fwd_rnd, b1, b0, kp + 2 * nc);
- round(fwd_rnd, b0, b1, kp + 3 * nc);
- round(fwd_rnd, b1, b0, kp + 4 * nc);
- round(fwd_rnd, b0, b1, kp + 5 * nc);
- round(fwd_rnd, b1, b0, kp + 6 * nc);
- round(fwd_rnd, b0, b1, kp + 7 * nc);
- round(fwd_rnd, b1, b0, kp + 8 * nc);
- round(fwd_lrnd, b0, b1, kp + 9 * nc);
- }
-
-#elif defined(PARTIAL_UNROLL)
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
- {
- round(fwd_rnd, b1, b0, kp);
- round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
- }
-
- round(fwd_rnd, b1, b0, kp);
- round(fwd_lrnd, b0, b1, kp + nc);
- }
-#else
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
- {
- round(fwd_rnd, b1, b0, kp);
- l_copy(b0, b1); kp += nc;
- }
-
- round(fwd_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-}
-
-void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-{ u_int32_t locals(b0, b1);
- const u_int32_t *kp = cx->aes_d_key;
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
- u_int32_t f2, f4, f8, f9;
-#endif
-
- state_in(b0, in_blk, kp); kp += nc;
-
-#if defined(UNROLL)
-
- switch(cx->aes_Nrnd)
- {
- case 14: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 12: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 10: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc);
- round(inv_rnd, b1, b0, kp + 2 * nc);
- round(inv_rnd, b0, b1, kp + 3 * nc);
- round(inv_rnd, b1, b0, kp + 4 * nc);
- round(inv_rnd, b0, b1, kp + 5 * nc);
- round(inv_rnd, b1, b0, kp + 6 * nc);
- round(inv_rnd, b0, b1, kp + 7 * nc);
- round(inv_rnd, b1, b0, kp + 8 * nc);
- round(inv_lrnd, b0, b1, kp + 9 * nc);
- }
-
-#elif defined(PARTIAL_UNROLL)
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
- {
- round(inv_rnd, b1, b0, kp);
- round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
- }
-
- round(inv_rnd, b1, b0, kp);
- round(inv_lrnd, b0, b1, kp + nc);
- }
-#else
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
- {
- round(inv_rnd, b1, b0, kp);
- l_copy(b0, b1); kp += nc;
- }
-
- round(inv_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-}
diff --git a/src/libcrypto/libaes/aes.h b/src/libcrypto/libaes/aes.h
deleted file mode 100644
index 4f1e3b335..000000000
--- a/src/libcrypto/libaes/aes.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// I retain copyright in this code but I encourage its free use provided
-// that I don't carry any responsibility for the results. I am especially
-// happy to see it used in free and open source software. If you do use
-// it I would appreciate an acknowledgement of its origin in the code or
-// the product that results and I would also appreciate knowing a little
-// about the use to which it is being put. I am grateful to Frank Yellin
-// for some ideas that are used in this implementation.
-//
-// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-//
-// This is an implementation of the AES encryption algorithm (Rijndael)
-// designed by Joan Daemen and Vincent Rijmen. This version is designed
-// to provide both fixed and dynamic block and key lengths and can also
-// run with either big or little endian internal byte order (see aes.h).
-// It inputs block and key lengths in bytes with the legal values being
-// 16, 24 and 32.
-
-/*
- * Modified by Jari Ruusu, May 1 2001
- * - Fixed some compile warnings, code was ok but gcc warned anyway.
- * - Changed basic types: byte -> unsigned char, word -> u_int32_t
- * - Major name space cleanup: Names visible to outside now begin
- * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
- * - Removed C++ and DLL support as part of name space cleanup.
- * - Eliminated unnecessary recomputation of tables. (actual bug fix)
- * - Merged precomputed constant tables to aes.c file.
- * - Removed data alignment restrictions for portability reasons.
- * - Made block and key lengths accept bit count (128/192/256)
- * as well byte count (16/24/32).
- * - Removed all error checks. This change also eliminated the need
- * to preinitialize the context struct to zero.
- * - Removed some totally unused constants.
- */
-
-#ifndef _AES_H
-#define _AES_H
-
-#if defined(__linux__) && defined(__KERNEL__)
-# include <linux/types.h>
-#else
-# include <sys/types.h>
-#endif
-
-// CONFIGURATION OPTIONS (see also aes.c)
-//
-// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
-// leave this undefined for dynamically variable block size (this will
-// result in much slower code).
-// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
-// left undefined a slower version providing variable block length is compiled
-
-#define AES_BLOCK_SIZE 16
-
-// The number of key schedule words for different block and key lengths
-// allowing for method of computation which requires the length to be a
-// multiple of the key length
-//
-// Nk = 4 6 8
-// -------------
-// Nb = 4 | 60 60 64
-// 6 | 96 90 96
-// 8 | 120 120 120
-
-#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
-#define AES_KS_LENGTH 120
-#define AES_RC_LENGTH 29
-#else
-#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
-#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
-#endif
-
-typedef struct
-{
- u_int32_t aes_Nkey; // the number of words in the key input block
- u_int32_t aes_Nrnd; // the number of cipher rounds
- u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
- u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
-#if !defined(AES_BLOCK_SIZE)
- u_int32_t aes_Ncol; // the number of columns in the cipher state
-#endif
-} aes_context;
-
-// THE CIPHER INTERFACE
-
-#if !defined(AES_BLOCK_SIZE)
-extern void aes_set_blk(aes_context *, const int);
-#endif
-extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
-extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
-extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
-
-// The block length inputs to aes_set_block and aes_set_key are in numbers
-// of bytes or bits. The calls to subroutines must be made in the above
-// order but multiple calls can be made without repeating earlier calls
-// if their parameters have not changed.
-
-#endif // _AES_H
diff --git a/src/libcrypto/libaes/aes_cbc.c b/src/libcrypto/libaes/aes_cbc.c
deleted file mode 100644
index c406b1622..000000000
--- a/src/libcrypto/libaes/aes_cbc.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-#include "aes_cbc.h"
-#include "cbc_generic.h"
-/* returns bool success */
-int SS_AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
- aes_set_key(aes_ctx, key, keysize, 0);
- return 1;
-}
-CBC_IMPL_BLK16(SS_AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
diff --git a/src/libcrypto/libaes/aes_cbc.h b/src/libcrypto/libaes/aes_cbc.h
deleted file mode 100644
index 65015da6e..000000000
--- a/src/libcrypto/libaes/aes_cbc.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Glue header */
-#include "aes.h"
-int SS_AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
-int SS_AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
diff --git a/src/libcrypto/libaes/aes_xcbc_mac.c b/src/libcrypto/libaes/aes_xcbc_mac.c
deleted file mode 100644
index 89d7bc067..000000000
--- a/src/libcrypto/libaes/aes_xcbc_mac.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <linux/kernel.h>
-#define DEBUG(x)
-#else
-#include <stdio.h>
-#include <sys/types.h>
-#define DEBUG(x) x
-#endif
-
-#include "aes.h"
-#include "aes_xcbc_mac.h"
-
-int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
-{
- int ret=1;
- aes_block kn[3] = {
- { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
- { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
- { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
- };
- aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
- aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
- aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
- aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
- aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
- return ret;
-}
-static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
- int pos=0;
- for (pos=1; pos <= 16; pos++, in++, out++) {
- if (pos <= len)
- *out ^= *in;
- if (pos > len) {
- DEBUG(printf("put 0x80 at pos=%d\n", pos));
- *out ^= 0x80;
- break;
- }
- }
-}
-static void xor_block(aes_block res, const aes_block op) {
- res[0] ^= op[0];
- res[1] ^= op[1];
- res[2] ^= op[2];
- res[3] ^= op[3];
-}
-int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
- int ret=ilen;
- u_int32_t out[4] = { 0, 0, 0, 0 };
- for (; ilen > 16 ; ilen-=16) {
- xor_block(out, (const u_int32_t*) &in[0]);
- aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
- in+=16;
- }
- do_pad_xor((u_int8_t *)&out, in, ilen);
- if (ilen==16) {
- DEBUG(printf("using k3\n"));
- xor_block(out, ctxm->k3);
- }
- else
- {
- DEBUG(printf("using k2\n"));
- xor_block(out, ctxm->k2);
- }
- aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
- return ret;
-}
diff --git a/src/libcrypto/libaes/aes_xcbc_mac.h b/src/libcrypto/libaes/aes_xcbc_mac.h
deleted file mode 100644
index baf438cd4..000000000
--- a/src/libcrypto/libaes/aes_xcbc_mac.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _AES_XCBC_MAC_H
-#define _AES_XCBC_MAC_H
-
-typedef u_int32_t aes_block[4];
-typedef struct {
- aes_context ctx_k1;
- aes_block k2;
- aes_block k3;
-} aes_context_mac;
-int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
-int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
-#endif /* _AES_XCBC_MAC_H */
diff --git a/src/libcrypto/libdes/cbc_enc.c b/src/libcrypto/libdes/cbc_enc.c
deleted file mode 100644
index a06f9f99e..000000000
--- a/src/libcrypto/libdes/cbc_enc.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* crypto/des/cbc_enc.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include "des_locl.h"
-
-void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
-des_cblock (*input);
-des_cblock (*output);
-long length;
-des_key_schedule schedule;
-des_cblock (*ivec);
-int enc;
- {
- register DES_LONG tin0,tin1;
- register DES_LONG tout0,tout1,xor0,xor1;
- register unsigned char *in,*out;
- register long l=length;
- DES_LONG tin[2];
- unsigned char *iv;
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- iv=(unsigned char *)ivec;
-
- if (enc)
- {
- c2l(iv,tout0);
- c2l(iv,tout1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0);
- c2l(in,tin1);
- tin0^=tout0; tin[0]=tin0;
- tin1^=tout1; tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
- tout0=tin[0]; l2c(tout0,out);
- tout1=tin[1]; l2c(tout1,out);
- }
- if (l != -8)
- {
- c2ln(in,tin0,tin1,l+8);
- tin0^=tout0; tin[0]=tin0;
- tin1^=tout1; tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
- tout0=tin[0]; l2c(tout0,out);
- tout1=tin[1]; l2c(tout1,out);
- }
- }
- else
- {
- c2l(iv,xor0);
- c2l(iv,xor1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0); tin[0]=tin0;
- c2l(in,tin1); tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
- tout0=tin[0]^xor0;
- tout1=tin[1]^xor1;
- l2c(tout0,out);
- l2c(tout1,out);
- xor0=tin0;
- xor1=tin1;
- }
- if (l != -8)
- {
- c2l(in,tin0); tin[0]=tin0;
- c2l(in,tin1); tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
- tout0=tin[0]^xor0;
- tout1=tin[1]^xor1;
- l2cn(tout0,tout1,out,l+8);
- /* xor0=tin0;
- xor1=tin1; */
- }
- }
- tin0=tin1=tout0=tout1=xor0=xor1=0;
- tin[0]=tin[1]=0;
- }
-
diff --git a/src/libcrypto/libdes/des.h b/src/libcrypto/libdes/des.h
deleted file mode 100644
index baddf8647..000000000
--- a/src/libcrypto/libdes/des.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/* crypto/des/des.org */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *
- * Always modify des.org since des.h is automatically generated from
- * it during SSLeay configuration.
- *
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- */
-
-#ifndef HEADER_DES_H
-#define HEADER_DES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-/* Must be unsigned int on ia64/Itanium or DES breaks badly */
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-
-#ifndef DES_LONG
-#define DES_LONG u_int32_t
-#endif
-
-typedef unsigned char des_cblock[8];
-typedef struct des_ks_struct
- {
- union {
- des_cblock _;
- /* make sure things are correct size on machines with
- * 8 byte longs */
- DES_LONG pad[2];
- } ks;
-#undef _
-#define _ ks._
- } des_key_schedule[16];
-
-#define DES_KEY_SZ (sizeof(des_cblock))
-#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
-
-#define DES_ENCRYPT 1
-#define DES_DECRYPT 0
-
-#define DES_CBC_MODE 0
-#define DES_PCBC_MODE 1
-
-#define des_ecb2_encrypt(i,o,k1,k2,e) \
- des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
-
-#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
- des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
-
-#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
- des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
-
-#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
- des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
-
-#define C_Block des_cblock
-#define Key_schedule des_key_schedule
-#ifdef KERBEROS
-#define ENCRYPT DES_ENCRYPT
-#define DECRYPT DES_DECRYPT
-#endif
-#define KEY_SZ DES_KEY_SZ
-#define string_to_key des_string_to_key
-#define read_pw_string des_read_pw_string
-#define random_key des_random_key
-#define pcbc_encrypt des_pcbc_encrypt
-#define set_key des_set_key
-#define key_sched des_key_sched
-#define ecb_encrypt des_ecb_encrypt
-#define cbc_encrypt des_cbc_encrypt
-#define ncbc_encrypt des_ncbc_encrypt
-#define xcbc_encrypt des_xcbc_encrypt
-#define cbc_cksum des_cbc_cksum
-#define quad_cksum des_quad_cksum
-
-/* For compatibility with the MIT lib - eay 20/05/92 */
-typedef des_key_schedule bit_64;
-#define des_fixup_key_parity des_set_odd_parity
-#define des_check_key_parity check_parity
-
-extern int des_check_key; /* defaults to false */
-extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
-
-/* The next line is used to disable full ANSI prototypes, if your
- * compiler has problems with the prototypes, make sure this line always
- * evaluates to true :-) */
-#if defined(MSDOS) || defined(__STDC__)
-#undef NOPROTO
-#endif
-#ifndef NOPROTO
-char *des_options(void);
-void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
- des_key_schedule ks1,des_key_schedule ks2,
- des_key_schedule ks3, int enc);
-DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
- long length,des_key_schedule schedule,des_cblock *ivec);
-void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
- des_key_schedule schedule,des_cblock *ivec,int enc);
-void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
- des_key_schedule schedule,des_cblock *ivec,int enc);
-void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
- des_key_schedule schedule,des_cblock *ivec,
- des_cblock *inw,des_cblock *outw,int enc);
-void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
- long length,des_key_schedule schedule,des_cblock *ivec,int enc);
-void des_ecb_encrypt(des_cblock *input,des_cblock *output,
- des_key_schedule ks,int enc);
-void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
-void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
-void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
- des_key_schedule ks2, des_key_schedule ks3);
-void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
- des_key_schedule ks2, des_key_schedule ks3);
-void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
- long length, des_key_schedule ks1, des_key_schedule ks2,
- des_key_schedule ks3, des_cblock *ivec, int enc);
-void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
- long length, des_key_schedule ks1, des_key_schedule ks2,
- des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
-void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
- long length, des_key_schedule ks1, des_key_schedule ks2,
- des_key_schedule ks3, des_cblock *ivec, int *num);
-
-void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
- des_cblock (*out_white));
-
-int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
- des_cblock *iv);
-int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
- des_cblock *iv);
-char *des_fcrypt(const char *buf,const char *salt, char *ret);
-#ifdef PERL5
-char *des_crypt(const char *buf,const char *salt);
-#else
-/* some stupid compilers complain because I have declared char instead
- * of const char */
-#ifndef __KERNEL__
-#ifdef HEADER_DES_LOCL_H
-char *crypt(const char *buf,const char *salt);
-#else /* HEADER_DES_LOCL_H */
-char *crypt(void);
-#endif /* HEADER_DES_LOCL_H */
-#endif /* __KERNEL__ */
-#endif /* PERL5 */
-void des_ofb_encrypt(unsigned char *in,unsigned char *out,
- int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
-void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
- des_key_schedule schedule,des_cblock *ivec,int enc);
-DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
- long length,int out_count,des_cblock *seed);
-void des_random_seed(des_cblock key);
-void des_random_key(des_cblock ret);
-int des_read_password(des_cblock *key,char *prompt,int verify);
-int des_read_2passwords(des_cblock *key1,des_cblock *key2,
- char *prompt,int verify);
-int des_read_pw_string(char *buf,int length,char *prompt,int verify);
-void des_set_odd_parity(des_cblock *key);
-int des_is_weak_key(des_cblock *key);
-int des_set_key(des_cblock *key,des_key_schedule schedule);
-int des_key_sched(des_cblock *key,des_key_schedule schedule);
-void des_string_to_key(char *str,des_cblock *key);
-void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
-void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
- des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
-void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
- des_key_schedule schedule, des_cblock *ivec, int *num);
-int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
-
-/* Extra functions from Mark Murray <mark@grondar.za> */
-/* The following functions are not in the normal unix build or the
- * SSLeay build. When using the SSLeay build, use RAND_seed()
- * and RAND_bytes() instead. */
-int des_new_random_key(des_cblock *key);
-void des_init_random_number_generator(des_cblock *key);
-void des_set_random_generator_seed(des_cblock *key);
-void des_set_sequence_number(des_cblock new_sequence_number);
-void des_generate_random_block(des_cblock *block);
-
-#else
-
-char *des_options();
-void des_ecb3_encrypt();
-DES_LONG des_cbc_cksum();
-void des_cbc_encrypt();
-void des_ncbc_encrypt();
-void des_xcbc_encrypt();
-void des_cfb_encrypt();
-void des_ede3_cfb64_encrypt();
-void des_ede3_ofb64_encrypt();
-void des_ecb_encrypt();
-void des_encrypt();
-void des_encrypt2();
-void des_encrypt3();
-void des_decrypt3();
-void des_ede3_cbc_encrypt();
-int des_enc_read();
-int des_enc_write();
-char *des_fcrypt();
-#ifdef PERL5
-char *des_crypt();
-#else
-char *crypt();
-#endif
-void des_ofb_encrypt();
-void des_pcbc_encrypt();
-DES_LONG des_quad_cksum();
-void des_random_seed();
-void des_random_key();
-int des_read_password();
-int des_read_2passwords();
-int des_read_pw_string();
-void des_set_odd_parity();
-int des_is_weak_key();
-int des_set_key();
-int des_key_sched();
-void des_string_to_key();
-void des_string_to_2keys();
-void des_cfb64_encrypt();
-void des_ofb64_encrypt();
-int des_read_pw();
-void des_xwhite_in2out();
-
-/* Extra functions from Mark Murray <mark@grondar.za> */
-/* The following functions are not in the normal unix build or the
- * SSLeay build. When using the SSLeay build, use RAND_seed()
- * and RAND_bytes() instead. */
-#ifdef FreeBSD
-int des_new_random_key();
-void des_init_random_number_generator();
-void des_set_random_generator_seed();
-void des_set_sequence_number();
-void des_generate_random_block();
-#endif
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/libcrypto/libdes/des_enc.c b/src/libcrypto/libdes/des_enc.c
deleted file mode 100644
index 1e1906d25..000000000
--- a/src/libcrypto/libdes/des_enc.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/* crypto/des/des_enc.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include "des_locl.h"
-
-void des_encrypt(data, ks, enc)
-DES_LONG *data;
-des_key_schedule ks;
-int enc;
- {
- register DES_LONG l,r,t,u;
-#ifdef DES_PTR
- register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-#endif
-#ifndef DES_UNROLL
- register int i;
-#endif
- register DES_LONG *s;
-
- r=data[0];
- l=data[1];
-
- IP(r,l);
- /* Things have been modified so that the initial rotate is
- * done outside the loop. This required the
- * des_SPtrans values in sp.h to be rotated 1 bit to the right.
- * One perl script later and things have a 5% speed up on a sparc2.
- * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
- * for pointing this out. */
- /* clear the top bits on machines with 8byte longs */
- /* shift left by 2 */
- r=ROTATE(r,29)&0xffffffffL;
- l=ROTATE(l,29)&0xffffffffL;
-
- s=(DES_LONG *)ks;
- /* I don't know if it is worth the effort of loop unrolling the
- * inner loop */
- if (enc)
- {
-#ifdef DES_UNROLL
- D_ENCRYPT(l,r, 0); /* 1 */
- D_ENCRYPT(r,l, 2); /* 2 */
- D_ENCRYPT(l,r, 4); /* 3 */
- D_ENCRYPT(r,l, 6); /* 4 */
- D_ENCRYPT(l,r, 8); /* 5 */
- D_ENCRYPT(r,l,10); /* 6 */
- D_ENCRYPT(l,r,12); /* 7 */
- D_ENCRYPT(r,l,14); /* 8 */
- D_ENCRYPT(l,r,16); /* 9 */
- D_ENCRYPT(r,l,18); /* 10 */
- D_ENCRYPT(l,r,20); /* 11 */
- D_ENCRYPT(r,l,22); /* 12 */
- D_ENCRYPT(l,r,24); /* 13 */
- D_ENCRYPT(r,l,26); /* 14 */
- D_ENCRYPT(l,r,28); /* 15 */
- D_ENCRYPT(r,l,30); /* 16 */
-#else
- for (i=0; i<32; i+=8)
- {
- D_ENCRYPT(l,r,i+0); /* 1 */
- D_ENCRYPT(r,l,i+2); /* 2 */
- D_ENCRYPT(l,r,i+4); /* 3 */
- D_ENCRYPT(r,l,i+6); /* 4 */
- }
-#endif
- }
- else
- {
-#ifdef DES_UNROLL
- D_ENCRYPT(l,r,30); /* 16 */
- D_ENCRYPT(r,l,28); /* 15 */
- D_ENCRYPT(l,r,26); /* 14 */
- D_ENCRYPT(r,l,24); /* 13 */
- D_ENCRYPT(l,r,22); /* 12 */
- D_ENCRYPT(r,l,20); /* 11 */
- D_ENCRYPT(l,r,18); /* 10 */
- D_ENCRYPT(r,l,16); /* 9 */
- D_ENCRYPT(l,r,14); /* 8 */
- D_ENCRYPT(r,l,12); /* 7 */
- D_ENCRYPT(l,r,10); /* 6 */
- D_ENCRYPT(r,l, 8); /* 5 */
- D_ENCRYPT(l,r, 6); /* 4 */
- D_ENCRYPT(r,l, 4); /* 3 */
- D_ENCRYPT(l,r, 2); /* 2 */
- D_ENCRYPT(r,l, 0); /* 1 */
-#else
- for (i=30; i>0; i-=8)
- {
- D_ENCRYPT(l,r,i-0); /* 16 */
- D_ENCRYPT(r,l,i-2); /* 15 */
- D_ENCRYPT(l,r,i-4); /* 14 */
- D_ENCRYPT(r,l,i-6); /* 13 */
- }
-#endif
- }
-
- /* rotate and clear the top bits on machines with 8byte longs */
- l=ROTATE(l,3)&0xffffffffL;
- r=ROTATE(r,3)&0xffffffffL;
-
- FP(r,l);
- data[0]=l;
- data[1]=r;
- l=r=t=u=0;
- }
-
-void des_encrypt2(data, ks, enc)
-DES_LONG *data;
-des_key_schedule ks;
-int enc;
- {
- register DES_LONG l,r,t,u;
-#ifdef DES_PTR
- register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-#endif
-#ifndef DES_UNROLL
- register int i;
-#endif
- register DES_LONG *s;
-
- r=data[0];
- l=data[1];
-
- /* Things have been modified so that the initial rotate is
- * done outside the loop. This required the
- * des_SPtrans values in sp.h to be rotated 1 bit to the right.
- * One perl script later and things have a 5% speed up on a sparc2.
- * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
- * for pointing this out. */
- /* clear the top bits on machines with 8byte longs */
- r=ROTATE(r,29)&0xffffffffL;
- l=ROTATE(l,29)&0xffffffffL;
-
- s=(DES_LONG *)ks;
- /* I don't know if it is worth the effort of loop unrolling the
- * inner loop */
- if (enc)
- {
-#ifdef DES_UNROLL
- D_ENCRYPT(l,r, 0); /* 1 */
- D_ENCRYPT(r,l, 2); /* 2 */
- D_ENCRYPT(l,r, 4); /* 3 */
- D_ENCRYPT(r,l, 6); /* 4 */
- D_ENCRYPT(l,r, 8); /* 5 */
- D_ENCRYPT(r,l,10); /* 6 */
- D_ENCRYPT(l,r,12); /* 7 */
- D_ENCRYPT(r,l,14); /* 8 */
- D_ENCRYPT(l,r,16); /* 9 */
- D_ENCRYPT(r,l,18); /* 10 */
- D_ENCRYPT(l,r,20); /* 11 */
- D_ENCRYPT(r,l,22); /* 12 */
- D_ENCRYPT(l,r,24); /* 13 */
- D_ENCRYPT(r,l,26); /* 14 */
- D_ENCRYPT(l,r,28); /* 15 */
- D_ENCRYPT(r,l,30); /* 16 */
-#else
- for (i=0; i<32; i+=8)
- {
- D_ENCRYPT(l,r,i+0); /* 1 */
- D_ENCRYPT(r,l,i+2); /* 2 */
- D_ENCRYPT(l,r,i+4); /* 3 */
- D_ENCRYPT(r,l,i+6); /* 4 */
- }
-#endif
- }
- else
- {
-#ifdef DES_UNROLL
- D_ENCRYPT(l,r,30); /* 16 */
- D_ENCRYPT(r,l,28); /* 15 */
- D_ENCRYPT(l,r,26); /* 14 */
- D_ENCRYPT(r,l,24); /* 13 */
- D_ENCRYPT(l,r,22); /* 12 */
- D_ENCRYPT(r,l,20); /* 11 */
- D_ENCRYPT(l,r,18); /* 10 */
- D_ENCRYPT(r,l,16); /* 9 */
- D_ENCRYPT(l,r,14); /* 8 */
- D_ENCRYPT(r,l,12); /* 7 */
- D_ENCRYPT(l,r,10); /* 6 */
- D_ENCRYPT(r,l, 8); /* 5 */
- D_ENCRYPT(l,r, 6); /* 4 */
- D_ENCRYPT(r,l, 4); /* 3 */
- D_ENCRYPT(l,r, 2); /* 2 */
- D_ENCRYPT(r,l, 0); /* 1 */
-#else
- for (i=30; i>0; i-=8)
- {
- D_ENCRYPT(l,r,i-0); /* 16 */
- D_ENCRYPT(r,l,i-2); /* 15 */
- D_ENCRYPT(l,r,i-4); /* 14 */
- D_ENCRYPT(r,l,i-6); /* 13 */
- }
-#endif
- }
- /* rotate and clear the top bits on machines with 8byte longs */
- data[0]=ROTATE(l,3)&0xffffffffL;
- data[1]=ROTATE(r,3)&0xffffffffL;
- l=r=t=u=0;
- }
-
-void des_encrypt3(data,ks1,ks2,ks3)
-DES_LONG *data;
-des_key_schedule ks1;
-des_key_schedule ks2;
-des_key_schedule ks3;
- {
- register DES_LONG l,r;
-
- l=data[0];
- r=data[1];
- IP(l,r);
- data[0]=l;
- data[1]=r;
- des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
- des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
- des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
- l=data[0];
- r=data[1];
- FP(r,l);
- data[0]=l;
- data[1]=r;
- }
-
-void des_decrypt3(data,ks1,ks2,ks3)
-DES_LONG *data;
-des_key_schedule ks1;
-des_key_schedule ks2;
-des_key_schedule ks3;
- {
- register DES_LONG l,r;
-
- l=data[0];
- r=data[1];
- IP(l,r);
- data[0]=l;
- data[1]=r;
- des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
- des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
- des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
- l=data[0];
- r=data[1];
- FP(r,l);
- data[0]=l;
- data[1]=r;
- }
-
-#ifndef DES_DEFAULT_OPTIONS
-
-void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-des_cblock (*input);
-des_cblock (*output);
-long length;
-des_key_schedule schedule;
-des_cblock (*ivec);
-int enc;
- {
- register DES_LONG tin0,tin1;
- register DES_LONG tout0,tout1,xor0,xor1;
- register unsigned char *in,*out;
- register long l=length;
- DES_LONG tin[2];
- unsigned char *iv;
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- iv=(unsigned char *)ivec;
-
- if (enc)
- {
- c2l(iv,tout0);
- c2l(iv,tout1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0);
- c2l(in,tin1);
- tin0^=tout0; tin[0]=tin0;
- tin1^=tout1; tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
- tout0=tin[0]; l2c(tout0,out);
- tout1=tin[1]; l2c(tout1,out);
- }
- if (l != -8)
- {
- c2ln(in,tin0,tin1,l+8);
- tin0^=tout0; tin[0]=tin0;
- tin1^=tout1; tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
- tout0=tin[0]; l2c(tout0,out);
- tout1=tin[1]; l2c(tout1,out);
- }
- iv=(unsigned char *)ivec;
- l2c(tout0,iv);
- l2c(tout1,iv);
- }
- else
- {
- c2l(iv,xor0);
- c2l(iv,xor1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0); tin[0]=tin0;
- c2l(in,tin1); tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
- tout0=tin[0]^xor0;
- tout1=tin[1]^xor1;
- l2c(tout0,out);
- l2c(tout1,out);
- xor0=tin0;
- xor1=tin1;
- }
- if (l != -8)
- {
- c2l(in,tin0); tin[0]=tin0;
- c2l(in,tin1); tin[1]=tin1;
- des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
- tout0=tin[0]^xor0;
- tout1=tin[1]^xor1;
- l2cn(tout0,tout1,out,l+8);
- xor0=tin0;
- xor1=tin1;
- }
-
- iv=(unsigned char *)ivec;
- l2c(xor0,iv);
- l2c(xor1,iv);
- }
- tin0=tin1=tout0=tout1=xor0=xor1=0;
- tin[0]=tin[1]=0;
- }
-
-void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
-des_cblock (*input);
-des_cblock (*output);
-long length;
-des_key_schedule ks1;
-des_key_schedule ks2;
-des_key_schedule ks3;
-des_cblock (*ivec);
-int enc;
- {
- register DES_LONG tin0,tin1;
- register DES_LONG tout0,tout1,xor0,xor1;
- register unsigned char *in,*out;
- register long l=length;
- DES_LONG tin[2];
- unsigned char *iv;
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- iv=(unsigned char *)ivec;
-
- if (enc)
- {
- c2l(iv,tout0);
- c2l(iv,tout1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0);
- c2l(in,tin1);
- tin0^=tout0;
- tin1^=tout1;
-
- tin[0]=tin0;
- tin[1]=tin1;
- des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
- tout0=tin[0];
- tout1=tin[1];
-
- l2c(tout0,out);
- l2c(tout1,out);
- }
- if (l != -8)
- {
- c2ln(in,tin0,tin1,l+8);
- tin0^=tout0;
- tin1^=tout1;
-
- tin[0]=tin0;
- tin[1]=tin1;
- des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
- tout0=tin[0];
- tout1=tin[1];
-
- l2c(tout0,out);
- l2c(tout1,out);
- }
- iv=(unsigned char *)ivec;
- l2c(tout0,iv);
- l2c(tout1,iv);
- }
- else
- {
- register DES_LONG t0,t1;
-
- c2l(iv,xor0);
- c2l(iv,xor1);
- for (l-=8; l>=0; l-=8)
- {
- c2l(in,tin0);
- c2l(in,tin1);
-
- t0=tin0;
- t1=tin1;
-
- tin[0]=tin0;
- tin[1]=tin1;
- des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
- tout0=tin[0];
- tout1=tin[1];
-
- tout0^=xor0;
- tout1^=xor1;
- l2c(tout0,out);
- l2c(tout1,out);
- xor0=t0;
- xor1=t1;
- }
- if (l != -8)
- {
- c2l(in,tin0);
- c2l(in,tin1);
-
- t0=tin0;
- t1=tin1;
-
- tin[0]=tin0;
- tin[1]=tin1;
- des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
- tout0=tin[0];
- tout1=tin[1];
-
- tout0^=xor0;
- tout1^=xor1;
- l2cn(tout0,tout1,out,l+8);
- xor0=t0;
- xor1=t1;
- }
-
- iv=(unsigned char *)ivec;
- l2c(xor0,iv);
- l2c(xor1,iv);
- }
- tin0=tin1=tout0=tout1=xor0=xor1=0;
- tin[0]=tin[1]=0;
- }
-
-#endif /* DES_DEFAULT_OPTIONS */
diff --git a/src/libcrypto/libdes/des_locl.h b/src/libcrypto/libdes/des_locl.h
deleted file mode 100644
index 4e0b3662f..000000000
--- a/src/libcrypto/libdes/des_locl.h
+++ /dev/null
@@ -1,515 +0,0 @@
-/* crypto/des/des_locl.org */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- *
- * Always modify des_locl.org since des_locl.h is automatically generated from
- * it during SSLeay configuration.
- *
- * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
- */
-
-#ifndef HEADER_DES_LOCL_H
-#define HEADER_DES_LOCL_H
-
-#if defined(WIN32) || defined(WIN16)
-#ifndef MSDOS
-#define MSDOS
-#endif
-#endif
-
-#include "des.h"
-
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#define DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#define DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( sun ) /* Newer Sparc's */
- #define DES_PTR
- #define DES_RISC1
- #define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
- #define DES_PTR
- #define DES_RISC2
- #define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
- #define DES_PTR
- #define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
- #define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
- #define DES_PTR
- #define DES_RISC2
- #define DES_UNROLL
-#elif defined( i386 ) /* x86 boxes, should be gcc */
- #define DES_PTR
- #define DES_RISC1
- #define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-
-#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <io.h>
-#ifndef RAND
-#define RAND
-#endif
-#undef NOPROTO
-#endif
-
-#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
-#ifndef __KERNEL__
-#include <string.h>
-#else
-#include <linux/string.h>
-#endif
-#endif
-
-#ifndef RAND
-#define RAND
-#endif
-
-#ifdef linux
-#undef RAND
-#endif
-
-#ifdef MSDOS
-#define getpid() 2
-#define RAND
-#undef NOPROTO
-#endif
-
-#if defined(NOCONST)
-#define const
-#endif
-
-#ifdef __STDC__
-#undef NOPROTO
-#endif
-
-#ifdef RAND
-#define srandom(s) srand(s)
-#define random rand
-#endif
-
-#define ITERATIONS 16
-#define HALF_ITERATIONS 8
-
-/* used in des_read and des_write */
-#define MAXWRITE (1024*16)
-#define BSIZE (MAXWRITE+4)
-
-#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
- l|=((DES_LONG)(*((c)++)))<< 8L, \
- l|=((DES_LONG)(*((c)++)))<<16L, \
- l|=((DES_LONG)(*((c)++)))<<24L)
-
-/* NOTE - c is not incremented as per c2l */
-#define c2ln(c,l1,l2,n) { \
- c+=n; \
- l1=l2=0; \
- switch (n) { \
- case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
- case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
- case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
- case 5: l2|=((DES_LONG)(*(--(c)))); \
- case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
- case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
- case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
- case 1: l1|=((DES_LONG)(*(--(c)))); \
- } \
- }
-
-#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
- *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-
-/* replacements for htonl and ntohl since I have no idea what to do
- * when faced with machines with 8 byte longs. */
-#define HDRSIZE 4
-
-#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
- l|=((DES_LONG)(*((c)++)))<<16L, \
- l|=((DES_LONG)(*((c)++)))<< 8L, \
- l|=((DES_LONG)(*((c)++))))
-
-#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
- *((c)++)=(unsigned char)(((l) )&0xff))
-
-/* NOTE - c is not incremented as per l2c */
-#define l2cn(l1,l2,c,n) { \
- c+=n; \
- switch (n) { \
- case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
- case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
- case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
- case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
- case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
- case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
- case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
- case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
- } \
- }
-
-#if defined(WIN32)
-#define ROTATE(a,n) (_lrotr(a,n))
-#else
-#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
-#endif
-
-/* Don't worry about the LOAD_DATA() stuff, that is used by
- * fcrypt() to add it's little bit to the front */
-
-#ifdef DES_FCRYPT
-
-#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
- { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
-
-#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
- t=R^(R>>16L); \
- u=t&E0; t&=E1; \
- tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
- tmp=(t<<16); t^=R^s[S+1]; t^=tmp
-#else
-#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
-#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
- u=R^s[S ]; \
- t=R^s[S+1]
-#endif
-
-/* The changes to this macro may help or hinder, depending on the
- * compiler and the achitecture. gcc2 always seems to do well :-).
- * Inspired by Dana How <how@isl.stanford.edu>
- * DO NOT use the alternative version on machines with 8 byte longs.
- * It does not seem to work on the Alpha, even when DES_LONG is 4
- * bytes, probably an issue of accessing non-word aligned objects :-( */
-#ifdef DES_PTR
-
-/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
- * is no reason to not xor all the sub items together. This potentially
- * saves a register since things can be xored directly into L */
-
-#if defined(DES_RISC1) || defined(DES_RISC2)
-#ifdef DES_RISC1
-#define D_ENCRYPT(LL,R,S) { \
- unsigned int u1,u2,u3; \
- LOAD_DATA(R,S,u,t,E0,E1,u1); \
- u2=(int)u>>8L; \
- u1=(int)u&0xfc; \
- u2&=0xfc; \
- t=ROTATE(t,4); \
- u>>=16L; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
- u3=(int)(u>>8L); \
- u1=(int)u&0xfc; \
- u3&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
- u2=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u2&=0xfc; \
- t>>=16L; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
- u3=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u3&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
-#endif
-#ifdef DES_RISC2
-#define D_ENCRYPT(LL,R,S) { \
- unsigned int u1,u2,s1,s2; \
- LOAD_DATA(R,S,u,t,E0,E1,u1); \
- u2=(int)u>>8L; \
- u1=(int)u&0xfc; \
- u2&=0xfc; \
- t=ROTATE(t,4); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
- s1=(int)(u>>16L); \
- s2=(int)(u>>24L); \
- s1&=0xfc; \
- s2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
- u2=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
- s1=(int)(t>>16L); \
- s2=(int)(t>>24L); \
- s1&=0xfc; \
- s2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
-#endif
-#else
-#define D_ENCRYPT(LL,R,S) { \
- LOAD_DATA_tmp(R,S,u,t,E0,E1); \
- t=ROTATE(t,4); \
- LL^= \
- *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
-#endif
-
-#else /* original version */
-
-#if defined(DES_RISC1) || defined(DES_RISC2)
-#ifdef DES_RISC1
-#define D_ENCRYPT(LL,R,S) {\
- unsigned int u1,u2,u3; \
- LOAD_DATA(R,S,u,t,E0,E1,u1); \
- u>>=2L; \
- t=ROTATE(t,6); \
- u2=(int)u>>8L; \
- u1=(int)u&0x3f; \
- u2&=0x3f; \
- u>>=16L; \
- LL^=des_SPtrans[0][u1]; \
- LL^=des_SPtrans[2][u2]; \
- u3=(int)u>>8L; \
- u1=(int)u&0x3f; \
- u3&=0x3f; \
- LL^=des_SPtrans[4][u1]; \
- LL^=des_SPtrans[6][u3]; \
- u2=(int)t>>8L; \
- u1=(int)t&0x3f; \
- u2&=0x3f; \
- t>>=16L; \
- LL^=des_SPtrans[1][u1]; \
- LL^=des_SPtrans[3][u2]; \
- u3=(int)t>>8L; \
- u1=(int)t&0x3f; \
- u3&=0x3f; \
- LL^=des_SPtrans[5][u1]; \
- LL^=des_SPtrans[7][u3]; }
-#endif
-#ifdef DES_RISC2
-#define D_ENCRYPT(LL,R,S) {\
- unsigned int u1,u2,s1,s2; \
- LOAD_DATA(R,S,u,t,E0,E1,u1); \
- u>>=2L; \
- t=ROTATE(t,6); \
- u2=(int)u>>8L; \
- u1=(int)u&0x3f; \
- u2&=0x3f; \
- LL^=des_SPtrans[0][u1]; \
- LL^=des_SPtrans[2][u2]; \
- s1=(int)u>>16L; \
- s2=(int)u>>24L; \
- s1&=0x3f; \
- s2&=0x3f; \
- LL^=des_SPtrans[4][s1]; \
- LL^=des_SPtrans[6][s2]; \
- u2=(int)t>>8L; \
- u1=(int)t&0x3f; \
- u2&=0x3f; \
- LL^=des_SPtrans[1][u1]; \
- LL^=des_SPtrans[3][u2]; \
- s1=(int)t>>16; \
- s2=(int)t>>24L; \
- s1&=0x3f; \
- s2&=0x3f; \
- LL^=des_SPtrans[5][s1]; \
- LL^=des_SPtrans[7][s2]; }
-#endif
-
-#else
-
-#define D_ENCRYPT(LL,R,S) {\
- LOAD_DATA_tmp(R,S,u,t,E0,E1); \
- t=ROTATE(t,4); \
- LL^=\
- des_SPtrans[0][(u>> 2L)&0x3f]^ \
- des_SPtrans[2][(u>>10L)&0x3f]^ \
- des_SPtrans[4][(u>>18L)&0x3f]^ \
- des_SPtrans[6][(u>>26L)&0x3f]^ \
- des_SPtrans[1][(t>> 2L)&0x3f]^ \
- des_SPtrans[3][(t>>10L)&0x3f]^ \
- des_SPtrans[5][(t>>18L)&0x3f]^ \
- des_SPtrans[7][(t>>26L)&0x3f]; }
-#endif
-#endif
-
- /* IP and FP
- * The problem is more of a geometric problem that random bit fiddling.
- 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
- 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
- 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
- 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
-
- 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
- 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
- 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
- 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
-
- The output has been subject to swaps of the form
- 0 1 -> 3 1 but the odd and even bits have been put into
- 2 3 2 0
- different words. The main trick is to remember that
- t=((l>>size)^r)&(mask);
- r^=t;
- l^=(t<<size);
- can be used to swap and move bits between words.
-
- So l = 0 1 2 3 r = 16 17 18 19
- 4 5 6 7 20 21 22 23
- 8 9 10 11 24 25 26 27
- 12 13 14 15 28 29 30 31
- becomes (for size == 2 and mask == 0x3333)
- t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
- 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
- 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
- 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
-
- Thanks for hints from Richard Outerbridge - he told me IP&FP
- could be done in 15 xor, 10 shifts and 5 ands.
- When I finally started to think of the problem in 2D
- I first got ~42 operations without xors. When I remembered
- how to use xors :-) I got it to its final state.
- */
-#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
- (b)^=(t),\
- (a)^=((t)<<(n)))
-
-#define IP(l,r) \
- { \
- register DES_LONG tt; \
- PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
- PERM_OP(l,r,tt,16,0x0000ffffL); \
- PERM_OP(r,l,tt, 2,0x33333333L); \
- PERM_OP(l,r,tt, 8,0x00ff00ffL); \
- PERM_OP(r,l,tt, 1,0x55555555L); \
- }
-
-#define FP(l,r) \
- { \
- register DES_LONG tt; \
- PERM_OP(l,r,tt, 1,0x55555555L); \
- PERM_OP(r,l,tt, 8,0x00ff00ffL); \
- PERM_OP(l,r,tt, 2,0x33333333L); \
- PERM_OP(r,l,tt,16,0x0000ffffL); \
- PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
- }
-
-extern const DES_LONG des_SPtrans[8][64];
-
-#ifndef NOPROTO
-void fcrypt_body(DES_LONG *out,des_key_schedule ks,
- DES_LONG Eswap0, DES_LONG Eswap1);
-#else
-void fcrypt_body();
-#endif
-
-#endif
diff --git a/src/libcrypto/libdes/des_ver.h b/src/libcrypto/libdes/des_ver.h
deleted file mode 100644
index 98352bc0d..000000000
--- a/src/libcrypto/libdes/des_ver.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* crypto/des/des_ver.h */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-extern char *DES_version; /* SSLeay version string */
-extern char *libdes_version; /* old libdes version string */
diff --git a/src/libcrypto/libdes/destest.c b/src/libcrypto/libdes/destest.c
deleted file mode 100644
index ae896499e..000000000
--- a/src/libcrypto/libdes/destest.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/* crypto/des/destest.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
-#ifndef MSDOS
-#define MSDOS
-#endif
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifndef MSDOS
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-#include <string.h>
-#include "des_locl.h"
-
-/* tisk tisk - the test keys don't all have odd parity :-( */
-/* test data */
-#define NUM_TESTS 34
-static unsigned char key_data[NUM_TESTS][8]={
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
- {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
- {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
- {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
- {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
- {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
- {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
- {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
- {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
- {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
- {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
- {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
- {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
- {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
- {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
- {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
- {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
- {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
- {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
- {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
- {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
- {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
- {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
- {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
-
-static unsigned char plain_data[NUM_TESTS][8]={
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
- {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
- {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
- {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
- {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
- {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
- {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
- {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
- {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
- {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
- {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
- {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
- {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
- {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
- {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
- {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
- {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
- {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
- {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
- {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
- {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
- {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
-
-static unsigned char cipher_data[NUM_TESTS][8]={
- {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
- {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
- {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
- {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
- {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
- {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
- {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
- {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
- {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
- {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
- {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
- {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
- {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
- {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
- {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
- {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
- {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
- {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
- {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
- {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
- {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
- {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
- {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
- {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
- {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
- {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
- {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
- {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
- {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
- {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
- {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
- {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
- {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
- {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
-
-static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
- {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
- {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
- {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
- {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
- {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
- {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
- {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
- {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
- {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
- {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
- {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
- {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
- {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
- {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
- {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
- {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
- {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
- {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
- {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
- {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
- {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
- {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
- {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
- {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
- {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
- {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
- {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
- {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
- {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
- {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
- {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
- {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
- {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
-
-static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
-static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-static char cbc_data[40]="7654321 Now is the time for \0001";
-
-static unsigned char cbc_ok[32]={
- 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
- 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
- 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
- 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-
-static unsigned char xcbc_ok[32]={
- 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
- 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
- 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
- 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
- };
-
-static unsigned char cbc3_ok[32]={
- 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
- 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
- 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
- 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
-
-static unsigned char pcbc_ok[32]={
- 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
- 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
- 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
- 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
-
-static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
-static unsigned char plain[24]=
- {
- 0x4e,0x6f,0x77,0x20,0x69,0x73,
- 0x20,0x74,0x68,0x65,0x20,0x74,
- 0x69,0x6d,0x65,0x20,0x66,0x6f,
- 0x72,0x20,0x61,0x6c,0x6c,0x20
- };
-static unsigned char cfb_cipher8[24]= {
- 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
- 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
-static unsigned char cfb_cipher16[24]={
- 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
- 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
-static unsigned char cfb_cipher32[24]={
- 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
- 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
-static unsigned char cfb_cipher48[24]={
- 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
- 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
-static unsigned char cfb_cipher64[24]={
- 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
- 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
-
-static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
-static unsigned char ofb_cipher[24]=
- {
- 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
- 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
- 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
- };
-
-DES_LONG cbc_cksum_ret=0xB462FEF7L;
-unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-
-#ifndef NOPROTO
-static char *pt(unsigned char *p);
-static int cfb_test(int bits, unsigned char *cfb_cipher);
-static int cfb64_test(unsigned char *cfb_cipher);
-static int ede_cfb64_test(unsigned char *cfb_cipher);
-#else
-static char *pt();
-static int cfb_test();
-static int cfb64_test();
-static int ede_cfb64_test();
-#endif
-
-int main(argc,argv)
-int argc;
-char *argv[];
- {
- int i,j,err=0;
- des_cblock in,out,outin,iv3;
- des_key_schedule ks,ks2,ks3;
- unsigned char cbc_in[40];
- unsigned char cbc_out[40];
- DES_LONG cs;
- unsigned char qret[4][4],cret[8];
- DES_LONG lqret[4];
- int num;
- char *str;
-
- printf("Doing ecb\n");
- for (i=0; i<NUM_TESTS; i++)
- {
- if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
- {
- printf("Key error %2d:%d\n",i+1,j);
- err=1;
- }
- memcpy(in,plain_data[i],8);
- memset(out,0,8);
- memset(outin,0,8);
- des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
- des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
-
- if (memcmp(out,cipher_data[i],8) != 0)
- {
- printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
- i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
- pt(out));
- err=1;
- }
- if (memcmp(in,outin,8) != 0)
- {
- printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
- i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
- err=1;
- }
- }
-
-#ifndef LIBDES_LIT
- printf("Doing ede ecb\n");
- for (i=0; i<(NUM_TESTS-1); i++)
- {
- if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
- {
- err=1;
- printf("Key error %2d:%d\n",i+1,j);
- }
- if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
- {
- printf("Key error %2d:%d\n",i+2,j);
- err=1;
- }
- if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
- {
- printf("Key error %2d:%d\n",i+3,j);
- err=1;
- }
- memcpy(in,plain_data[i],8);
- memset(out,0,8);
- memset(outin,0,8);
- des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
- DES_ENCRYPT);
- des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
- DES_DECRYPT);
-
- if (memcmp(out,cipher_ecb2[i],8) != 0)
- {
- printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
- i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
- pt(out));
- err=1;
- }
- if (memcmp(in,outin,8) != 0)
- {
- printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
- i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
- err=1;
- }
- }
-#endif
-
- printf("Doing cbc\n");
- if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- memset(cbc_out,0,40);
- memset(cbc_in,0,40);
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
- des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
- (long)strlen((char *)cbc_data)+1,ks,
- (C_Block *)iv3,DES_ENCRYPT);
- if (memcmp(cbc_out,cbc_ok,32) != 0)
- printf("cbc_encrypt encrypt error\n");
-
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
- des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
- (long)strlen((char *)cbc_data)+1,ks,
- (C_Block *)iv3,DES_DECRYPT);
- if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
- {
- printf("cbc_encrypt decrypt error\n");
- err=1;
- }
-
-#ifndef LIBDES_LIT
- printf("Doing desx cbc\n");
- if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- memset(cbc_out,0,40);
- memset(cbc_in,0,40);
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
- des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
- (long)strlen((char *)cbc_data)+1,ks,
- (C_Block *)iv3,
- (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
- if (memcmp(cbc_out,xcbc_ok,32) != 0)
- {
- printf("des_xcbc_encrypt encrypt error\n");
- }
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
- des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
- (long)strlen((char *)cbc_data)+1,ks,
- (C_Block *)iv3,
- (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
- if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
- {
- printf("des_xcbc_encrypt decrypt error\n");
- err=1;
- }
-#endif
-
- printf("Doing ede cbc\n");
- if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- memset(cbc_out,0,40);
- memset(cbc_in,0,40);
- i=strlen((char *)cbc_data)+1;
- /* i=((i+7)/8)*8; */
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-
- des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
- 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
- des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
- (C_Block *)&(cbc_out[16]),
- (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
- if (memcmp(cbc_out,cbc3_ok,
- (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
- {
- printf("des_ede3_cbc_encrypt encrypt error\n");
- err=1;
- }
-
- memcpy(iv3,cbc_iv,sizeof(cbc_iv));
- des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
- (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
- if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
- {
- printf("des_ede3_cbc_encrypt decrypt error\n");
- err=1;
- }
-
-#ifndef LIBDES_LIT
- printf("Doing pcbc\n");
- if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
- {
- printf("Key error %d\n",j);
- err=1;
- }
- memset(cbc_out,0,40);
- memset(cbc_in,0,40);
- des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
- (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
- if (memcmp(cbc_out,pcbc_ok,32) != 0)
- {
- printf("pcbc_encrypt encrypt error\n");
- err=1;
- }
- des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
- (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
- if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
- {
- printf("pcbc_encrypt decrypt error\n");
- err=1;
- }
-
- printf("Doing ");
- printf("cfb8 ");
- err+=cfb_test(8,cfb_cipher8);
- printf("cfb16 ");
- err+=cfb_test(16,cfb_cipher16);
- printf("cfb32 ");
- err+=cfb_test(32,cfb_cipher32);
- printf("cfb48 ");
- err+=cfb_test(48,cfb_cipher48);
- printf("cfb64 ");
- err+=cfb_test(64,cfb_cipher64);
-
- printf("cfb64() ");
- err+=cfb64_test(cfb_cipher64);
-
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- for (i=0; i<sizeof(plain); i++)
- des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
- 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
- if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
- {
- printf("cfb_encrypt small encrypt error\n");
- err=1;
- }
-
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- for (i=0; i<sizeof(plain); i++)
- des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
- 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
- if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
- {
- printf("cfb_encrypt small decrypt error\n");
- err=1;
- }
-
- printf("ede_cfb64() ");
- err+=ede_cfb64_test(cfb_cipher64);
-
- printf("done\n");
-
- printf("Doing ofb\n");
- des_key_sched((C_Block *)ofb_key,ks);
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
- (C_Block *)ofb_tmp);
- if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
- {
- printf("ofb_encrypt encrypt error\n");
-printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
-ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
-printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
-ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
- err=1;
- }
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
- (C_Block *)ofb_tmp);
- if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
- {
- printf("ofb_encrypt decrypt error\n");
-printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
-ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
-printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-plain[8+0], plain[8+1], plain[8+2], plain[8+3],
-plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
- err=1;
- }
-
- printf("Doing ofb64\n");
- des_key_sched((C_Block *)ofb_key,ks);
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- memset(ofb_buf1,0,sizeof(ofb_buf1));
- memset(ofb_buf2,0,sizeof(ofb_buf1));
- num=0;
- for (i=0; i<sizeof(plain); i++)
- {
- des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
- (C_Block *)ofb_tmp,&num);
- }
- if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
- {
- printf("ofb64_encrypt encrypt error\n");
- err=1;
- }
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- num=0;
- des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
- (C_Block *)ofb_tmp,&num);
- if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
- {
- printf("ofb64_encrypt decrypt error\n");
- err=1;
- }
-
- printf("Doing ede_ofb64\n");
- des_key_sched((C_Block *)ofb_key,ks);
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- memset(ofb_buf1,0,sizeof(ofb_buf1));
- memset(ofb_buf2,0,sizeof(ofb_buf1));
- num=0;
- for (i=0; i<sizeof(plain); i++)
- {
- des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
- (C_Block *)ofb_tmp,&num);
- }
- if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
- {
- printf("ede_ofb64_encrypt encrypt error\n");
- err=1;
- }
- memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
- num=0;
- des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
- ks,ks,(C_Block *)ofb_tmp,&num);
- if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
- {
- printf("ede_ofb64_encrypt decrypt error\n");
- err=1;
- }
-
- printf("Doing cbc_cksum\n");
- des_key_sched((C_Block *)cbc_key,ks);
- cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
- (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
- if (cs != cbc_cksum_ret)
- {
- printf("bad return value (%08lX), should be %08lX\n",
- (unsigned long)cs,(unsigned long)cbc_cksum_ret);
- err=1;
- }
- if (memcmp(cret,cbc_cksum_data,8) != 0)
- {
- printf("bad cbc_cksum block returned\n");
- err=1;
- }
-
- printf("Doing quad_cksum\n");
- cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
- (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
- for (i=0; i<4; i++)
- {
- lqret[i]=0;
- memcpy(&(lqret[i]),&(qret[i][0]),4);
- }
- { /* Big-endian fix */
- static DES_LONG l=1;
- static unsigned char *c=(unsigned char *)&l;
- DES_LONG ll;
-
- if (!c[0])
- {
- ll=lqret[0]^lqret[3];
- lqret[0]^=ll;
- lqret[3]^=ll;
- ll=lqret[1]^lqret[2];
- lqret[1]^=ll;
- lqret[2]^=ll;
- }
- }
- if (cs != 0x70d7a63aL)
- {
- printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
- (unsigned long)cs);
- err=1;
- }
- if (lqret[0] != 0x327eba8dL)
- {
- printf("quad_cksum error, out[0] %08lx is not %08lx\n",
- (unsigned long)lqret[0],0x327eba8dL);
- err=1;
- }
- if (lqret[1] != 0x201a49ccL)
- {
- printf("quad_cksum error, out[1] %08lx is not %08lx\n",
- (unsigned long)lqret[1],0x201a49ccL);
- err=1;
- }
- if (lqret[2] != 0x70d7a63aL)
- {
- printf("quad_cksum error, out[2] %08lx is not %08lx\n",
- (unsigned long)lqret[2],0x70d7a63aL);
- err=1;
- }
- if (lqret[3] != 0x501c2c26L)
- {
- printf("quad_cksum error, out[3] %08lx is not %08lx\n",
- (unsigned long)lqret[3],0x501c2c26L);
- err=1;
- }
-#endif
-
- printf("input word alignment test");
- for (i=0; i<4; i++)
- {
- printf(" %d",i);
- des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
- (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
- DES_ENCRYPT);
- }
- printf("\noutput word alignment test");
- for (i=0; i<4; i++)
- {
- printf(" %d",i);
- des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
- (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
- DES_ENCRYPT);
- }
- printf("\n");
- printf("fast crypt test ");
- str=crypt("testing","ef");
- if (strcmp("efGnQx2725bI2",str) != 0)
- {
- printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
- err=1;
- }
- str=crypt("bca76;23","yA");
- if (strcmp("yA1Rp/1hZXIJk",str) != 0)
- {
- printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
- err=1;
- }
- printf("\n");
- exit(err);
- return(0);
- }
-
-static char *pt(p)
-unsigned char *p;
- {
- static char bufs[10][20];
- static int bnum=0;
- char *ret;
- int i;
- static char *f="0123456789ABCDEF";
-
- ret= &(bufs[bnum++][0]);
- bnum%=10;
- for (i=0; i<8; i++)
- {
- ret[i*2]=f[(p[i]>>4)&0xf];
- ret[i*2+1]=f[p[i]&0xf];
- }
- ret[16]='\0';
- return(ret);
- }
-
-#ifndef LIBDES_LIT
-
-static int cfb_test(bits, cfb_cipher)
-int bits;
-unsigned char *cfb_cipher;
- {
- des_key_schedule ks;
- int i,err=0;
-
- des_key_sched((C_Block *)cfb_key,ks);
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
- (C_Block *)cfb_tmp,DES_ENCRYPT);
- if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
- {
- err=1;
- printf("cfb_encrypt encrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf1[i])));
- }
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
- (C_Block *)cfb_tmp,DES_DECRYPT);
- if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
- {
- err=1;
- printf("cfb_encrypt decrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf1[i])));
- }
- return(err);
- }
-
-static int cfb64_test(cfb_cipher)
-unsigned char *cfb_cipher;
- {
- des_key_schedule ks;
- int err=0,i,n;
-
- des_key_sched((C_Block *)cfb_key,ks);
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- n=0;
- des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
- (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
- des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
- (long)sizeof(plain)-12,ks,
- (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
- if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
- {
- err=1;
- printf("cfb_encrypt encrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf1[i])));
- }
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- n=0;
- des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
- (C_Block *)cfb_tmp,&n,DES_DECRYPT);
- des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
- (long)sizeof(plain)-17,ks,
- (C_Block *)cfb_tmp,&n,DES_DECRYPT);
- if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
- {
- err=1;
- printf("cfb_encrypt decrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf2[i])));
- }
- return(err);
- }
-
-static int ede_cfb64_test(cfb_cipher)
-unsigned char *cfb_cipher;
- {
- des_key_schedule ks;
- int err=0,i,n;
-
- des_key_sched((C_Block *)cfb_key,ks);
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- n=0;
- des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
- (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
- des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
- (long)sizeof(plain)-12,ks,ks,ks,
- (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
- if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
- {
- err=1;
- printf("ede_cfb_encrypt encrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf1[i])));
- }
- memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
- n=0;
- des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
- (C_Block *)cfb_tmp,&n,DES_DECRYPT);
- des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
- (long)sizeof(plain)-17,ks,ks,ks,
- (C_Block *)cfb_tmp,&n,DES_DECRYPT);
- if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
- {
- err=1;
- printf("ede_cfb_encrypt decrypt error\n");
- for (i=0; i<24; i+=8)
- printf("%s\n",pt(&(cfb_buf2[i])));
- }
- return(err);
- }
-
-#endif
-
diff --git a/src/libcrypto/libdes/ecb_enc.c b/src/libcrypto/libdes/ecb_enc.c
deleted file mode 100644
index 0b7afcf3a..000000000
--- a/src/libcrypto/libdes/ecb_enc.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* crypto/des/ecb_enc.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#include "des_locl.h"
-#include "spr.h"
-
-char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
-char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
-
-/* RCSID $Id: ecb_enc.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
-/* This function ifdef'ed out for FreeS/WAN project. */
-#ifdef notdef
-char *des_options()
- {
- static int init=1;
- static char buf[32];
-
- if (init)
- {
- char *ptr,*unroll,*risc,*size;
-
- init=0;
-#ifdef DES_PTR
- ptr="ptr";
-#else
- ptr="idx";
-#endif
-#if defined(DES_RISC1) || defined(DES_RISC2)
-#ifdef DES_RISC1
- risc="risc1";
-#endif
-#ifdef DES_RISC2
- risc="risc2";
-#endif
-#else
- risc="cisc";
-#endif
-#ifdef DES_UNROLL
- unroll="16";
-#else
- unroll="4";
-#endif
- if (sizeof(DES_LONG) != sizeof(long))
- size="int";
- else
- size="long";
- sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
- }
- return(buf);
- }
-#endif
-
-
-void des_ecb_encrypt(input, output, ks, enc)
-des_cblock (*input);
-des_cblock (*output);
-des_key_schedule ks;
-int enc;
- {
- register DES_LONG l;
- register unsigned char *in,*out;
- DES_LONG ll[2];
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- c2l(in,l); ll[0]=l;
- c2l(in,l); ll[1]=l;
- des_encrypt(ll,ks,enc);
- l=ll[0]; l2c(l,out);
- l=ll[1]; l2c(l,out);
- l=ll[0]=ll[1]=0;
- }
-
diff --git a/src/libcrypto/libdes/fcrypt.c b/src/libcrypto/libdes/fcrypt.c
deleted file mode 100644
index 8b9d0495b..000000000
--- a/src/libcrypto/libdes/fcrypt.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* NOCW */
-
-/* This version of crypt has been developed from my MIT compatable
- * DES library.
- * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
- * Eric Young (eay@cryptsoft.com)
- */
-
-/* Modification by Jens Kupferschmidt (Cu)
- * I have included directive PARA for shared memory computers.
- * I have included a directive LONGCRYPT to using this routine to cipher
- * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
- * definition is the maximum of lenght of password and can changed. I have
- * defined 24.
- */
-
-#include "des_locl.h"
-
-/* Added more values to handle illegal salt values the way normal
- * crypt() implementations do. The patch was sent by
- * Bjorn Gronvall <bg@sics.se>
- */
-static unsigned const char con_salt[128]={
-0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
-0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
-0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
-0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
-0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
-0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
-0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
-0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
-0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
-0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
-0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
-0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
-0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
-0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
-0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
-0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
-};
-
-static unsigned const char cov_2char[64]={
-0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
-0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
-0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
-0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
-0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
-0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
-0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
-0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
-};
-
-#ifndef NOPROTO
-void fcrypt_body(DES_LONG *out,des_key_schedule ks,
- DES_LONG Eswap0, DES_LONG Eswap1);
-
-#ifdef PERL5
-char *des_crypt(const char *buf,const char *salt);
-#else
-char *crypt(const char *buf,const char *salt);
-#endif
-#else
-void fcrypt_body();
-#ifdef PERL5
-char *des_crypt();
-#else
-char *crypt();
-#endif
-#endif
-
-#ifdef PERL5
-char *des_crypt(buf,salt)
-#else
-char *crypt(buf,salt)
-#endif
-const char *buf;
-const char *salt;
- {
- static char buff[14];
-
- return(des_fcrypt(buf,salt,buff));
- }
-
-
-char *des_fcrypt(buf,salt,ret)
-const char *buf;
-const char *salt;
-char *ret;
- {
- unsigned int i,j,x,y;
- DES_LONG Eswap0,Eswap1;
- DES_LONG out[2],ll;
- des_cblock key;
- des_key_schedule ks;
- unsigned char bb[9];
- unsigned char *b=bb;
- unsigned char c,u;
-
- /* eay 25/08/92
- * If you call crypt("pwd","*") as often happens when you
- * have * as the pwd field in /etc/passwd, the function
- * returns *\0XXXXXXXXX
- * The \0 makes the string look like * so the pwd "*" would
- * crypt to "*". This was found when replacing the crypt in
- * our shared libraries. People found that the disbled
- * accounts effectivly had no passwd :-(. */
- x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
- Eswap0=con_salt[x]<<2;
- x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
- Eswap1=con_salt[x]<<6;
-
-/* EAY
-r=strlen(buf);
-r=(r+7)/8;
-*/
- for (i=0; i<8; i++)
- {
- c= *(buf++);
- if (!c) break;
- key[i]=(c<<1);
- }
- for (; i<8; i++)
- key[i]=0;
-
- des_set_key((des_cblock *)(key),ks);
- fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
-
- ll=out[0]; l2c(ll,b);
- ll=out[1]; l2c(ll,b);
- y=0;
- u=0x80;
- bb[8]=0;
- for (i=2; i<13; i++)
- {
- c=0;
- for (j=0; j<6; j++)
- {
- c<<=1;
- if (bb[y] & u) c|=1;
- u>>=1;
- if (!u)
- {
- y++;
- u=0x80;
- }
- }
- ret[i]=cov_2char[c];
- }
- ret[13]='\0';
- return(ret);
- }
-
diff --git a/src/libcrypto/libdes/podd.h b/src/libcrypto/libdes/podd.h
deleted file mode 100644
index c00cd6ba0..000000000
--- a/src/libcrypto/libdes/podd.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* crypto/des/podd.h */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-static const unsigned char odd_parity[256]={
- 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
- 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
- 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
- 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
- 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
- 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
- 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
-112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
-128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
-145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
-161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
-176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
-193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
-208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
-224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
-241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
diff --git a/src/libcrypto/libdes/set_key.c b/src/libcrypto/libdes/set_key.c
deleted file mode 100644
index 99ac27348..000000000
--- a/src/libcrypto/libdes/set_key.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* crypto/des/set_key.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* set_key.c v 1.4 eay 24/9/91
- * 1.4 Speed up by 400% :-)
- * 1.3 added register declarations.
- * 1.2 unrolled make_key_sched a bit more
- * 1.1 added norm_expand_bits
- * 1.0 First working version
- */
-#include "des_locl.h"
-#include "podd.h"
-#include "sk.h"
-
-#ifndef NOPROTO
-static int check_parity(des_cblock (*key));
-#else
-static int check_parity();
-#endif
-
-int des_check_key=0;
-
-void des_set_odd_parity(key)
-des_cblock (*key);
- {
- int i;
-
- for (i=0; i<DES_KEY_SZ; i++)
- (*key)[i]=odd_parity[(*key)[i]];
- }
-
-static int check_parity(key)
-des_cblock (*key);
- {
- int i;
-
- for (i=0; i<DES_KEY_SZ; i++)
- {
- if ((*key)[i] != odd_parity[(*key)[i]])
- return(0);
- }
- return(1);
- }
-
-/* Weak and semi week keys as take from
- * %A D.W. Davies
- * %A W.L. Price
- * %T Security for Computer Networks
- * %I John Wiley & Sons
- * %D 1984
- * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
- * (and actual cblock values).
- */
-#define NUM_WEAK_KEY 16
-static des_cblock weak_keys[NUM_WEAK_KEY]={
- /* weak keys */
- {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
- {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
- {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
- {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
- /* semi-weak keys */
- {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
- {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
- {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
- {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
- {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
- {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
- {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
- {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
- {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
- {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
- {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
- {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
-
-int des_is_weak_key(key)
-des_cblock (*key);
- {
- int i;
-
- for (i=0; i<NUM_WEAK_KEY; i++)
- /* Added == 0 to comparision, I obviously don't run
- * this section very often :-(, thanks to
- * engineering@MorningStar.Com for the fix
- * eay 93/06/29
- * Another problem, I was comparing only the first 4
- * bytes, 97/03/18 */
- if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
- return(0);
- }
-
-/* NOW DEFINED IN des_local.h
- * See ecb_encrypt.c for a pseudo description of these macros.
- * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
- * (b)^=(t),\
- * (a)=((a)^((t)<<(n))))
- */
-
-#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
- (a)=(a)^(t)^(t>>(16-(n))))
-
-/* return 0 if key parity is odd (correct),
- * return -1 if key parity error,
- * return -2 if illegal weak key.
- */
-int des_set_key(key, schedule)
-des_cblock (*key);
-des_key_schedule schedule;
- {
- static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
- register DES_LONG c,d,t,s,t2;
- register unsigned char *in;
- register DES_LONG *k;
- register int i;
-
- if (des_check_key)
- {
- if (!check_parity(key))
- return(-1);
-
- if (des_is_weak_key(key))
- return(-2);
- }
-
- k=(DES_LONG *)schedule;
- in=(unsigned char *)key;
-
- c2l(in,c);
- c2l(in,d);
-
- /* do PC1 in 60 simple operations */
-/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
- HPERM_OP(c,t,-2, 0xcccc0000L);
- HPERM_OP(c,t,-1, 0xaaaa0000L);
- HPERM_OP(c,t, 8, 0x00ff0000L);
- HPERM_OP(c,t,-1, 0xaaaa0000L);
- HPERM_OP(d,t,-8, 0xff000000L);
- HPERM_OP(d,t, 8, 0x00ff0000L);
- HPERM_OP(d,t, 2, 0x33330000L);
- d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
- d=(d>>8)|((c&0xf0000000L)>>4);
- c&=0x0fffffffL; */
-
- /* I now do it in 47 simple operations :-)
- * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
- * for the inspiration. :-) */
- PERM_OP (d,c,t,4,0x0f0f0f0fL);
- HPERM_OP(c,t,-2,0xcccc0000L);
- HPERM_OP(d,t,-2,0xcccc0000L);
- PERM_OP (d,c,t,1,0x55555555L);
- PERM_OP (c,d,t,8,0x00ff00ffL);
- PERM_OP (d,c,t,1,0x55555555L);
- d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
- ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
- c&=0x0fffffffL;
-
- for (i=0; i<ITERATIONS; i++)
- {
- if (shifts2[i])
- { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
- else
- { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
- c&=0x0fffffffL;
- d&=0x0fffffffL;
- /* could be a few less shifts but I am to lazy at this
- * point in time to investigate */
- s= des_skb[0][ (c )&0x3f ]|
- des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
- des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
- des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
- ((c>>22L)&0x38)];
- t= des_skb[4][ (d )&0x3f ]|
- des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
- des_skb[6][ (d>>15L)&0x3f ]|
- des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
-
- /* table contained 0213 4657 */
- t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
- *(k++)=ROTATE(t2,30)&0xffffffffL;
-
- t2=((s>>16L)|(t&0xffff0000L));
- *(k++)=ROTATE(t2,26)&0xffffffffL;
- }
- return(0);
- }
-
-int des_key_sched(key, schedule)
-des_cblock (*key);
-des_key_schedule schedule;
- {
- return(des_set_key(key,schedule));
- }
diff --git a/src/libcrypto/libdes/sk.h b/src/libcrypto/libdes/sk.h
deleted file mode 100644
index 240703070..000000000
--- a/src/libcrypto/libdes/sk.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* crypto/des/sk.h */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-static const DES_LONG des_skb[8][64]={
-{
-/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-0x00000000L,0x00000010L,0x20000000L,0x20000010L,
-0x00010000L,0x00010010L,0x20010000L,0x20010010L,
-0x00000800L,0x00000810L,0x20000800L,0x20000810L,
-0x00010800L,0x00010810L,0x20010800L,0x20010810L,
-0x00000020L,0x00000030L,0x20000020L,0x20000030L,
-0x00010020L,0x00010030L,0x20010020L,0x20010030L,
-0x00000820L,0x00000830L,0x20000820L,0x20000830L,
-0x00010820L,0x00010830L,0x20010820L,0x20010830L,
-0x00080000L,0x00080010L,0x20080000L,0x20080010L,
-0x00090000L,0x00090010L,0x20090000L,0x20090010L,
-0x00080800L,0x00080810L,0x20080800L,0x20080810L,
-0x00090800L,0x00090810L,0x20090800L,0x20090810L,
-0x00080020L,0x00080030L,0x20080020L,0x20080030L,
-0x00090020L,0x00090030L,0x20090020L,0x20090030L,
-0x00080820L,0x00080830L,0x20080820L,0x20080830L,
-0x00090820L,0x00090830L,0x20090820L,0x20090830L,
-},{
-/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-0x00000000L,0x02000000L,0x00002000L,0x02002000L,
-0x00200000L,0x02200000L,0x00202000L,0x02202000L,
-0x00000004L,0x02000004L,0x00002004L,0x02002004L,
-0x00200004L,0x02200004L,0x00202004L,0x02202004L,
-0x00000400L,0x02000400L,0x00002400L,0x02002400L,
-0x00200400L,0x02200400L,0x00202400L,0x02202400L,
-0x00000404L,0x02000404L,0x00002404L,0x02002404L,
-0x00200404L,0x02200404L,0x00202404L,0x02202404L,
-0x10000000L,0x12000000L,0x10002000L,0x12002000L,
-0x10200000L,0x12200000L,0x10202000L,0x12202000L,
-0x10000004L,0x12000004L,0x10002004L,0x12002004L,
-0x10200004L,0x12200004L,0x10202004L,0x12202004L,
-0x10000400L,0x12000400L,0x10002400L,0x12002400L,
-0x10200400L,0x12200400L,0x10202400L,0x12202400L,
-0x10000404L,0x12000404L,0x10002404L,0x12002404L,
-0x10200404L,0x12200404L,0x10202404L,0x12202404L,
-},{
-/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-0x00000000L,0x00000001L,0x00040000L,0x00040001L,
-0x01000000L,0x01000001L,0x01040000L,0x01040001L,
-0x00000002L,0x00000003L,0x00040002L,0x00040003L,
-0x01000002L,0x01000003L,0x01040002L,0x01040003L,
-0x00000200L,0x00000201L,0x00040200L,0x00040201L,
-0x01000200L,0x01000201L,0x01040200L,0x01040201L,
-0x00000202L,0x00000203L,0x00040202L,0x00040203L,
-0x01000202L,0x01000203L,0x01040202L,0x01040203L,
-0x08000000L,0x08000001L,0x08040000L,0x08040001L,
-0x09000000L,0x09000001L,0x09040000L,0x09040001L,
-0x08000002L,0x08000003L,0x08040002L,0x08040003L,
-0x09000002L,0x09000003L,0x09040002L,0x09040003L,
-0x08000200L,0x08000201L,0x08040200L,0x08040201L,
-0x09000200L,0x09000201L,0x09040200L,0x09040201L,
-0x08000202L,0x08000203L,0x08040202L,0x08040203L,
-0x09000202L,0x09000203L,0x09040202L,0x09040203L,
-},{
-/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-0x00000000L,0x00100000L,0x00000100L,0x00100100L,
-0x00000008L,0x00100008L,0x00000108L,0x00100108L,
-0x00001000L,0x00101000L,0x00001100L,0x00101100L,
-0x00001008L,0x00101008L,0x00001108L,0x00101108L,
-0x04000000L,0x04100000L,0x04000100L,0x04100100L,
-0x04000008L,0x04100008L,0x04000108L,0x04100108L,
-0x04001000L,0x04101000L,0x04001100L,0x04101100L,
-0x04001008L,0x04101008L,0x04001108L,0x04101108L,
-0x00020000L,0x00120000L,0x00020100L,0x00120100L,
-0x00020008L,0x00120008L,0x00020108L,0x00120108L,
-0x00021000L,0x00121000L,0x00021100L,0x00121100L,
-0x00021008L,0x00121008L,0x00021108L,0x00121108L,
-0x04020000L,0x04120000L,0x04020100L,0x04120100L,
-0x04020008L,0x04120008L,0x04020108L,0x04120108L,
-0x04021000L,0x04121000L,0x04021100L,0x04121100L,
-0x04021008L,0x04121008L,0x04021108L,0x04121108L,
-},{
-/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-0x00000000L,0x10000000L,0x00010000L,0x10010000L,
-0x00000004L,0x10000004L,0x00010004L,0x10010004L,
-0x20000000L,0x30000000L,0x20010000L,0x30010000L,
-0x20000004L,0x30000004L,0x20010004L,0x30010004L,
-0x00100000L,0x10100000L,0x00110000L,0x10110000L,
-0x00100004L,0x10100004L,0x00110004L,0x10110004L,
-0x20100000L,0x30100000L,0x20110000L,0x30110000L,
-0x20100004L,0x30100004L,0x20110004L,0x30110004L,
-0x00001000L,0x10001000L,0x00011000L,0x10011000L,
-0x00001004L,0x10001004L,0x00011004L,0x10011004L,
-0x20001000L,0x30001000L,0x20011000L,0x30011000L,
-0x20001004L,0x30001004L,0x20011004L,0x30011004L,
-0x00101000L,0x10101000L,0x00111000L,0x10111000L,
-0x00101004L,0x10101004L,0x00111004L,0x10111004L,
-0x20101000L,0x30101000L,0x20111000L,0x30111000L,
-0x20101004L,0x30101004L,0x20111004L,0x30111004L,
-},{
-/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-0x00000000L,0x08000000L,0x00000008L,0x08000008L,
-0x00000400L,0x08000400L,0x00000408L,0x08000408L,
-0x00020000L,0x08020000L,0x00020008L,0x08020008L,
-0x00020400L,0x08020400L,0x00020408L,0x08020408L,
-0x00000001L,0x08000001L,0x00000009L,0x08000009L,
-0x00000401L,0x08000401L,0x00000409L,0x08000409L,
-0x00020001L,0x08020001L,0x00020009L,0x08020009L,
-0x00020401L,0x08020401L,0x00020409L,0x08020409L,
-0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
-0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
-0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
-0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
-0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
-0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
-0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
-0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
-},{
-/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-0x00000000L,0x00000100L,0x00080000L,0x00080100L,
-0x01000000L,0x01000100L,0x01080000L,0x01080100L,
-0x00000010L,0x00000110L,0x00080010L,0x00080110L,
-0x01000010L,0x01000110L,0x01080010L,0x01080110L,
-0x00200000L,0x00200100L,0x00280000L,0x00280100L,
-0x01200000L,0x01200100L,0x01280000L,0x01280100L,
-0x00200010L,0x00200110L,0x00280010L,0x00280110L,
-0x01200010L,0x01200110L,0x01280010L,0x01280110L,
-0x00000200L,0x00000300L,0x00080200L,0x00080300L,
-0x01000200L,0x01000300L,0x01080200L,0x01080300L,
-0x00000210L,0x00000310L,0x00080210L,0x00080310L,
-0x01000210L,0x01000310L,0x01080210L,0x01080310L,
-0x00200200L,0x00200300L,0x00280200L,0x00280300L,
-0x01200200L,0x01200300L,0x01280200L,0x01280300L,
-0x00200210L,0x00200310L,0x00280210L,0x00280310L,
-0x01200210L,0x01200310L,0x01280210L,0x01280310L,
-},{
-/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-0x00000000L,0x04000000L,0x00040000L,0x04040000L,
-0x00000002L,0x04000002L,0x00040002L,0x04040002L,
-0x00002000L,0x04002000L,0x00042000L,0x04042000L,
-0x00002002L,0x04002002L,0x00042002L,0x04042002L,
-0x00000020L,0x04000020L,0x00040020L,0x04040020L,
-0x00000022L,0x04000022L,0x00040022L,0x04040022L,
-0x00002020L,0x04002020L,0x00042020L,0x04042020L,
-0x00002022L,0x04002022L,0x00042022L,0x04042022L,
-0x00000800L,0x04000800L,0x00040800L,0x04040800L,
-0x00000802L,0x04000802L,0x00040802L,0x04040802L,
-0x00002800L,0x04002800L,0x00042800L,0x04042800L,
-0x00002802L,0x04002802L,0x00042802L,0x04042802L,
-0x00000820L,0x04000820L,0x00040820L,0x04040820L,
-0x00000822L,0x04000822L,0x00040822L,0x04040822L,
-0x00002820L,0x04002820L,0x00042820L,0x04042820L,
-0x00002822L,0x04002822L,0x00042822L,0x04042822L,
-}};
diff --git a/src/libcrypto/libdes/spr.h b/src/libcrypto/libdes/spr.h
deleted file mode 100644
index a84d6a723..000000000
--- a/src/libcrypto/libdes/spr.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* crypto/des/spr.h */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-const DES_LONG des_SPtrans[8][64]={
-{
-/* nibble 0 */
-0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
-0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
-0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
-0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
-0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
-0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
-0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
-0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
-0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
-0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
-0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
-0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
-0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
-0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
-0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
-0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
-},{
-/* nibble 1 */
-0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
-0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
-0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
-0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
-0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
-0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
-0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
-0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
-0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
-0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
-0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
-0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
-0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
-0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
-0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
-0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
-},{
-/* nibble 2 */
-0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
-0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
-0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
-0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
-0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
-0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
-0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
-0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
-0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
-0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
-0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
-0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
-0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
-0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
-0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
-0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
-},{
-/* nibble 3 */
-0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
-0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
-0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
-0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
-0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
-0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
-0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
-0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
-0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
-0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
-0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
-0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
-0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
-0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
-0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
-0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
-},{
-/* nibble 4 */
-0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
-0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
-0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
-0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
-0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
-0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
-0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
-0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
-0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
-0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
-0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
-0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
-0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
-0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
-0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
-0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
-},{
-/* nibble 5 */
-0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
-0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
-0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
-0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
-0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
-0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
-0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
-0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
-0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
-0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
-0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
-0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
-0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
-0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
-0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
-0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
-},{
-/* nibble 6 */
-0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
-0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
-0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
-0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
-0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
-0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
-0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
-0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
-0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
-0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
-0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
-0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
-0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
-0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
-0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
-0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
-},{
-/* nibble 7 */
-0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
-0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
-0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
-0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
-0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
-0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
-0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
-0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
-0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
-0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
-0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
-0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
-0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
-0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
-0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
-0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
-}};
diff --git a/src/libcrypto/libserpent/serpent.c b/src/libcrypto/libserpent/serpent.c
deleted file mode 100644
index f2cea250e..000000000
--- a/src/libcrypto/libserpent/serpent.c
+++ /dev/null
@@ -1,995 +0,0 @@
-
-/* Optimized implementation of the Serpent AES candidate algorithm
- * Designed by Anderson, Biham and Knudsen and Implemented by
- * Gisle Sælensminde 2000.
- *
- * The implementation is based on the pentium optimised sboxes of
- * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86
- * processors they are efficient on other processors as well, but the speedup
- * isn't so impressive compared to other implementations.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License
- * as published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-#ifdef __KERNEL__
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/byteorder.h>
-#else
-#include <sys/types.h>
-#include <asm/byteorder.h>
-#endif
-
-#include "serpent.h"
-
-#define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))
-#define rotr(reg, val) ((reg >> val) | (reg << (32 - val)))
-
-#ifdef __cpu_to_be32
-#define BLOCK_SWAP
-#define io_swap(x) __cpu_to_be32(x)
-#else
-#undef BLOCK_SWAP
-#endif
-
-/* The sbox functions. The first four parameters is the input bits, and
- * the last is a tempoary. These parameters are also used for output, but
- * the bit order is permuted. The output bit order from S0 is
- * (1 4 2 0 3), where 3 is the (now useless) tempoary.
- */
-
-#define S0(r0,r1,r2,r3,r4) \
- r3 = r3 ^ r0; \
- r4 = r1; \
- r1 = r1 & r3; \
- r4 = r4 ^ r2; \
- r1 = r1 ^ r0; \
- r0 = r0 | r3; \
- r0 = r0 ^ r4; \
- r4 = r4 ^ r3; \
- r3 = r3 ^ r2; \
- r2 = r2 | r1; \
- r2 = r2 ^ r4; \
- r4 = -1 ^ r4; \
- r4 = r4 | r1; \
- r1 = r1 ^ r3; \
- r1 = r1 ^ r4; \
- r3 = r3 | r0; \
- r1 = r1 ^ r3; \
- r4 = r4 ^ r3;
-
-#define S1(r0,r1,r2,r3,r4) \
- r1 = -1 ^ r1; \
- r4 = r0; \
- r0 = r0 ^ r1; \
- r4 = r4 | r1; \
- r4 = r4 ^ r3; \
- r3 = r3 & r0; \
- r2 = r2 ^ r4; \
- r3 = r3 ^ r1; \
- r3 = r3 | r2; \
- r0 = r0 ^ r4; \
- r3 = r3 ^ r0; \
- r1 = r1 & r2; \
- r0 = r0 | r1; \
- r1 = r1 ^ r4; \
- r0 = r0 ^ r2; \
- r4 = r4 | r3; \
- r0 = r0 ^ r4; \
- r4 = -1 ^ r4; \
- r1 = r1 ^ r3; \
- r4 = r4 & r2; \
- r1 = -1 ^ r1; \
- r4 = r4 ^ r0; \
- r1 = r1 ^ r4;
-
-#define S2(r0,r1,r2,r3,r4) \
- r4 = r0; \
- r0 = r0 & r2; \
- r0 = r0 ^ r3; \
- r2 = r2 ^ r1; \
- r2 = r2 ^ r0; \
- r3 = r3 | r4; \
- r3 = r3 ^ r1; \
- r4 = r4 ^ r2; \
- r1 = r3; \
- r3 = r3 | r4; \
- r3 = r3 ^ r0; \
- r0 = r0 & r1; \
- r4 = r4 ^ r0; \
- r1 = r1 ^ r3; \
- r1 = r1 ^ r4; \
- r4 = -1 ^ r4;
-
-#define S3(r0,r1,r2,r3,r4) \
- r4 = r0 ; \
- r0 = r0 | r3; \
- r3 = r3 ^ r1; \
- r1 = r1 & r4; \
- r4 = r4 ^ r2; \
- r2 = r2 ^ r3; \
- r3 = r3 & r0; \
- r4 = r4 | r1; \
- r3 = r3 ^ r4; \
- r0 = r0 ^ r1; \
- r4 = r4 & r0; \
- r1 = r1 ^ r3; \
- r4 = r4 ^ r2; \
- r1 = r1 | r0; \
- r1 = r1 ^ r2; \
- r0 = r0 ^ r3; \
- r2 = r1; \
- r1 = r1 | r3; \
- r1 = r1 ^ r0;
-
-#define S4(r0,r1,r2,r3,r4) \
- r1 = r1 ^ r3; \
- r3 = -1 ^ r3; \
- r2 = r2 ^ r3; \
- r3 = r3 ^ r0; \
- r4 = r1; \
- r1 = r1 & r3; \
- r1 = r1 ^ r2; \
- r4 = r4 ^ r3; \
- r0 = r0 ^ r4; \
- r2 = r2 & r4; \
- r2 = r2 ^ r0; \
- r0 = r0 & r1; \
- r3 = r3 ^ r0; \
- r4 = r4 | r1; \
- r4 = r4 ^ r0; \
- r0 = r0 | r3; \
- r0 = r0 ^ r2; \
- r2 = r2 & r3; \
- r0 = -1 ^ r0; \
- r4 = r4 ^ r2;
-
-#define S5(r0,r1,r2,r3,r4) \
- r0 = r0 ^ r1; \
- r1 = r1 ^ r3; \
- r3 = -1 ^ r3; \
- r4 = r1; \
- r1 = r1 & r0; \
- r2 = r2 ^ r3; \
- r1 = r1 ^ r2; \
- r2 = r2 | r4; \
- r4 = r4 ^ r3; \
- r3 = r3 & r1; \
- r3 = r3 ^ r0; \
- r4 = r4 ^ r1; \
- r4 = r4 ^ r2; \
- r2 = r2 ^ r0; \
- r0 = r0 & r3; \
- r2 = -1 ^ r2; \
- r0 = r0 ^ r4; \
- r4 = r4 | r3; \
- r2 = r2 ^ r4;
-
-#define S6(r0,r1,r2,r3,r4) \
- r2 = -1 ^ r2; \
- r4 = r3; \
- r3 = r3 & r0; \
- r0 = r0 ^ r4; \
- r3 = r3 ^ r2; \
- r2 = r2 | r4; \
- r1 = r1 ^ r3; \
- r2 = r2 ^ r0; \
- r0 = r0 | r1; \
- r2 = r2 ^ r1; \
- r4 = r4 ^ r0; \
- r0 = r0 | r3; \
- r0 = r0 ^ r2; \
- r4 = r4 ^ r3; \
- r4 = r4 ^ r0; \
- r3 = -1 ^ r3; \
- r2 = r2 & r4; \
- r2 = r2 ^ r3;
-
-#define S7(r0,r1,r2,r3,r4) \
- r4 = r2; \
- r2 = r2 & r1; \
- r2 = r2 ^ r3; \
- r3 = r3 & r1; \
- r4 = r4 ^ r2; \
- r2 = r2 ^ r1; \
- r1 = r1 ^ r0; \
- r0 = r0 | r4; \
- r0 = r0 ^ r2; \
- r3 = r3 ^ r1; \
- r2 = r2 ^ r3; \
- r3 = r3 & r0; \
- r3 = r3 ^ r4; \
- r4 = r4 ^ r2; \
- r2 = r2 & r0; \
- r4 = -1 ^ r4; \
- r2 = r2 ^ r4; \
- r4 = r4 & r0; \
- r1 = r1 ^ r3; \
- r4 = r4 ^ r1;
-
-/* The inverse sboxes */
-
-#define I0(r0,r1,r2,r3,r4) \
- r2 = r2 ^ -1; \
- r4 = r1; \
- r1 = r1 | r0; \
- r4 = r4 ^ -1; \
- r1 = r1 ^ r2; \
- r2 = r2 | r4; \
- r1 = r1 ^ r3; \
- r0 = r0 ^ r4; \
- r2 = r2 ^ r0; \
- r0 = r0 & r3; \
- r4 = r4 ^ r0; \
- r0 = r0 | r1; \
- r0 = r0 ^ r2; \
- r3 = r3 ^ r4; \
- r2 = r2 ^ r1; \
- r3 = r3 ^ r0; \
- r3 = r3 ^ r1; \
- r2 = r2 & r3; \
- r4 = r4 ^ r2;
-
-#define I1(r0,r1,r2,r3,r4) \
- r4 = r1; \
- r1 = r1 ^ r3; \
- r3 = r3 & r1; \
- r4 = r4 ^ r2; \
- r3 = r3 ^ r0; \
- r0 = r0 | r1; \
- r2 = r2 ^ r3; \
- r0 = r0 ^ r4; \
- r0 = r0 | r2; \
- r1 = r1 ^ r3; \
- r0 = r0 ^ r1; \
- r1 = r1 | r3; \
- r1 = r1 ^ r0; \
- r4 = r4 ^ -1; \
- r4 = r4 ^ r1; \
- r1 = r1 | r0; \
- r1 = r1 ^ r0; \
- r1 = r1 | r4; \
- r3 = r3 ^ r1;
-
-#define I2(r0,r1,r2,r3,r4) \
- r2 = r2 ^ r3; \
- r3 = r3 ^ r0; \
- r4 = r3; \
- r3 = r3 & r2; \
- r3 = r3 ^ r1; \
- r1 = r1 | r2; \
- r1 = r1 ^ r4; \
- r4 = r4 & r3; \
- r2 = r2 ^ r3; \
- r4 = r4 & r0; \
- r4 = r4 ^ r2; \
- r2 = r2 & r1; \
- r2 = r2 | r0; \
- r3 = r3 ^ -1; \
- r2 = r2 ^ r3; \
- r0 = r0 ^ r3; \
- r0 = r0 & r1; \
- r3 = r3 ^ r4; \
- r3 = r3 ^ r0;
-
-#define I3(r0,r1,r2,r3,r4) \
- r4 = r2; \
- r2 = r2 ^ r1; \
- r0 = r0 ^ r2; \
- r4 = r4 & r2; \
- r4 = r4 ^ r0; \
- r0 = r0 & r1; \
- r1 = r1 ^ r3; \
- r3 = r3 | r4; \
- r2 = r2 ^ r3; \
- r0 = r0 ^ r3; \
- r1 = r1 ^ r4; \
- r3 = r3 & r2; \
- r3 = r3 ^ r1; \
- r1 = r1 ^ r0; \
- r1 = r1 | r2; \
- r0 = r0 ^ r3; \
- r1 = r1 ^ r4; \
- r0 = r0 ^ r1;
-
-#define I4(r0,r1,r2,r3,r4) \
- r4 = r2; \
- r2 = r2 & r3; \
- r2 = r2 ^ r1; \
- r1 = r1 | r3; \
- r1 = r1 & r0; \
- r4 = r4 ^ r2; \
- r4 = r4 ^ r1; \
- r1 = r1 & r2; \
- r0 = r0 ^ -1; \
- r3 = r3 ^ r4; \
- r1 = r1 ^ r3; \
- r3 = r3 & r0; \
- r3 = r3 ^ r2; \
- r0 = r0 ^ r1; \
- r2 = r2 & r0; \
- r3 = r3 ^ r0; \
- r2 = r2 ^ r4; \
- r2 = r2 | r3; \
- r3 = r3 ^ r0; \
- r2 = r2 ^ r1;
-
-#define I5(r0,r1,r2,r3,r4) \
- r1 = r1 ^ -1; \
- r4 = r3; \
- r2 = r2 ^ r1; \
- r3 = r3 | r0; \
- r3 = r3 ^ r2; \
- r2 = r2 | r1; \
- r2 = r2 & r0; \
- r4 = r4 ^ r3; \
- r2 = r2 ^ r4; \
- r4 = r4 | r0; \
- r4 = r4 ^ r1; \
- r1 = r1 & r2; \
- r1 = r1 ^ r3; \
- r4 = r4 ^ r2; \
- r3 = r3 & r4; \
- r4 = r4 ^ r1; \
- r3 = r3 ^ r0; \
- r3 = r3 ^ r4; \
- r4 = r4 ^ -1;
-
-
-#define I6(r0,r1,r2,r3,r4) \
- r0 = r0 ^ r2; \
- r4 = r2; \
- r2 = r2 & r0; \
- r4 = r4 ^ r3; \
- r2 = r2 ^ -1; \
- r3 = r3 ^ r1; \
- r2 = r2 ^ r3; \
- r4 = r4 | r0; \
- r0 = r0 ^ r2; \
- r3 = r3 ^ r4; \
- r4 = r4 ^ r1; \
- r1 = r1 & r3; \
- r1 = r1 ^ r0; \
- r0 = r0 ^ r3; \
- r0 = r0 | r2; \
- r3 = r3 ^ r1; \
- r4 = r4 ^ r0;
-
-#define I7(r0,r1,r2,r3,r4) \
- r4 = r2; \
- r2 = r2 ^ r0; \
- r0 = r0 & r3; \
- r4 = r4 | r3; \
- r2 = r2 ^ -1; \
- r3 = r3 ^ r1; \
- r1 = r1 | r0; \
- r0 = r0 ^ r2; \
- r2 = r2 & r4; \
- r3 = r3 & r4; \
- r1 = r1 ^ r2; \
- r2 = r2 ^ r0; \
- r0 = r0 | r2; \
- r4 = r4 ^ r1; \
- r0 = r0 ^ r3; \
- r3 = r3 ^ r4; \
- r4 = r4 | r0; \
- r3 = r3 ^ r2; \
- r4 = r4 ^ r2;
-
-/* forward and inverse linear transformations */
-
-#define LINTRANS(r0,r1,r2,r3,r4) \
- r0 = rotl(r0, 13); \
- r2 = rotl(r2, 3); \
- r3 = r3 ^ r2; \
- r4 = r0 << 3; \
- r1 = r1 ^ r0; \
- r3 = r3 ^ r4; \
- r1 = r1 ^ r2; \
- r3 = rotl(r3, 7); \
- r1 = rotl(r1, 1); \
- r2 = r2 ^ r3; \
- r4 = r1 << 7; \
- r0 = r0 ^ r1; \
- r2 = r2 ^ r4; \
- r0 = r0 ^ r3; \
- r2 = rotl(r2, 22); \
- r0 = rotl(r0, 5);
-
-#define ILINTRANS(r0,r1,r2,r3,r4) \
- r2 = rotr(r2, 22); \
- r0 = rotr(r0, 5); \
- r2 = r2 ^ r3; \
- r4 = r1 << 7; \
- r0 = r0 ^ r1; \
- r2 = r2 ^ r4; \
- r0 = r0 ^ r3; \
- r3 = rotr(r3, 7); \
- r1 = rotr(r1, 1); \
- r3 = r3 ^ r2; \
- r4 = r0 << 3; \
- r1 = r1 ^ r0; \
- r3 = r3 ^ r4; \
- r1 = r1 ^ r2; \
- r2 = rotr(r2, 3); \
- r0 = rotr(r0, 13);
-
-
-#define KEYMIX(r0,r1,r2,r3,r4,IN) \
- r0 = r0 ^ l_key[IN+8]; \
- r1 = r1 ^ l_key[IN+9]; \
- r2 = r2 ^ l_key[IN+10]; \
- r3 = r3 ^ l_key[IN+11];
-
-#define GETKEY(r0, r1, r2, r3, IN) \
- r0 = l_key[IN+8]; \
- r1 = l_key[IN+9]; \
- r2 = l_key[IN+10]; \
- r3 = l_key[IN+11];
-
-#define SETKEY(r0, r1, r2, r3, IN) \
- l_key[IN+8] = r0; \
- l_key[IN+9] = r1; \
- l_key[IN+10] = r2; \
- l_key[IN+11] = r3;
-
-/* initialise the key schedule from the user supplied key */
-
-int serpent_set_key(serpent_context *cx, const unsigned char *key, int key_len)
-{ const u32 *in_key = (const u32 *)key;
- /* l_key - storage for the key schedule */
- u32 *l_key = cx->keyinfo;
- u32 i,lk,r0,r1,r2,r3,r4;
-
- if (key_len != 16 && key_len != 24 && key_len != 32)
- return -1; /* unsupported key length */
-
- key_len *= 8;
-
- i = 0; lk = (key_len + 31) / 32;
-
- while(i < lk)
- {
-#ifdef BLOCK_SWAP
- l_key[i] = io_swap(in_key[lk - i - 1]);
-#else
- l_key[i] = in_key[i];
-#endif
- i++;
- }
-
- if (key_len < 256)
- {
- while(i < 8)
-
- l_key[i++] = 0;
-
- i = key_len / 32; lk = 1 << key_len % 32;
-
- l_key[i] &= lk - 1;
- l_key[i] |= lk;
- }
-
- for(i = 0; i < 132; ++i)
- {
- lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5]
- ^ l_key[i + 7] ^ 0x9e3779b9 ^ i;
-
- l_key[i + 8] = (lk << 11) | (lk >> 21);
- }
-
- GETKEY(r0, r1, r2, r3, 0);
- S3(r0,r1,r2,r3,r4);
- SETKEY(r1, r2, r3, r4, 0)
-
- GETKEY(r0, r1, r2, r3, 4);
- S2(r0,r1,r2,r3,r4);
- SETKEY(r2, r3, r1, r4, 4)
-
- GETKEY(r0, r1, r2, r3, 8);
- S1(r0,r1,r2,r3,r4);
- SETKEY(r3, r1, r2, r0, 8)
-
- GETKEY(r0, r1, r2, r3, 12);
- S0(r0,r1,r2,r3,r4);
- SETKEY(r1, r4, r2, r0, 12)
-
- GETKEY(r0, r1, r2, r3, 16);
- S7(r0,r1,r2,r3,r4);
- SETKEY(r2, r4, r3, r0, 16)
-
- GETKEY(r0, r1, r2, r3, 20);
- S6(r0,r1,r2,r3,r4)
- SETKEY(r0, r1, r4, r2, 20)
-
- GETKEY(r0, r1, r2, r3, 24);
- S5(r0,r1,r2,r3,r4);
- SETKEY(r1, r3, r0, r2, 24)
-
- GETKEY(r0, r1, r2, r3, 28);
- S4(r0,r1,r2,r3,r4)
- SETKEY(r1, r4, r0, r3, 28)
-
- GETKEY(r0, r1, r2, r3, 32);
- S3(r0,r1,r2,r3,r4);
- SETKEY(r1, r2, r3, r4, 32)
-
- GETKEY(r0, r1, r2, r3, 36);
- S2(r0,r1,r2,r3,r4);
- SETKEY(r2, r3, r1, r4, 36)
-
- GETKEY(r0, r1, r2, r3, 40);
- S1(r0,r1,r2,r3,r4);
- SETKEY(r3, r1, r2, r0, 40)
-
- GETKEY(r0, r1, r2, r3, 44);
- S0(r0,r1,r2,r3,r4);
- SETKEY(r1, r4, r2, r0, 44)
-
- GETKEY(r0, r1, r2, r3, 48);
- S7(r0,r1,r2,r3,r4);
- SETKEY(r2, r4, r3, r0, 48)
-
- GETKEY(r0, r1, r2, r3, 52);
- S6(r0,r1,r2,r3,r4)
- SETKEY(r0, r1, r4, r2, 52)
-
- GETKEY(r0, r1, r2, r3, 56);
- S5(r0,r1,r2,r3,r4);
- SETKEY(r1, r3, r0, r2, 56)
-
- GETKEY(r0, r1, r2, r3, 60);
- S4(r0,r1,r2,r3,r4)
- SETKEY(r1, r4, r0, r3, 60)
-
- GETKEY(r0, r1, r2, r3, 64);
- S3(r0,r1,r2,r3,r4);
- SETKEY(r1, r2, r3, r4, 64)
-
- GETKEY(r0, r1, r2, r3, 68);
- S2(r0,r1,r2,r3,r4);
- SETKEY(r2, r3, r1, r4, 68)
-
- GETKEY(r0, r1, r2, r3, 72);
- S1(r0,r1,r2,r3,r4);
- SETKEY(r3, r1, r2, r0, 72)
-
- GETKEY(r0, r1, r2, r3, 76);
- S0(r0,r1,r2,r3,r4);
- SETKEY(r1, r4, r2, r0, 76)
-
- GETKEY(r0, r1, r2, r3, 80);
- S7(r0,r1,r2,r3,r4);
- SETKEY(r2, r4, r3, r0, 80)
-
- GETKEY(r0, r1, r2, r3, 84);
- S6(r0,r1,r2,r3,r4)
- SETKEY(r0, r1, r4, r2, 84)
-
- GETKEY(r0, r1, r2, r3, 88);
- S5(r0,r1,r2,r3,r4);
- SETKEY(r1, r3, r0, r2, 88)
-
- GETKEY(r0, r1, r2, r3, 92);
- S4(r0,r1,r2,r3,r4)
- SETKEY(r1, r4, r0, r3, 92)
-
- GETKEY(r0, r1, r2, r3, 96);
- S3(r0,r1,r2,r3,r4);
- SETKEY(r1, r2, r3, r4, 96)
-
- GETKEY(r0, r1, r2, r3, 100);
- S2(r0,r1,r2,r3,r4);
- SETKEY(r2, r3, r1, r4, 100)
-
- GETKEY(r0, r1, r2, r3, 104);
- S1(r0,r1,r2,r3,r4);
- SETKEY(r3, r1, r2, r0, 104)
-
- GETKEY(r0, r1, r2, r3, 108);
- S0(r0,r1,r2,r3,r4);
- SETKEY(r1, r4, r2, r0, 108)
-
- GETKEY(r0, r1, r2, r3, 112);
- S7(r0,r1,r2,r3,r4);
- SETKEY(r2, r4, r3, r0, 112)
-
- GETKEY(r0, r1, r2, r3, 116);
- S6(r0,r1,r2,r3,r4)
- SETKEY(r0, r1, r4, r2, 116)
-
- GETKEY(r0, r1, r2, r3, 120);
- S5(r0,r1,r2,r3,r4);
- SETKEY(r1, r3, r0, r2, 120)
-
- GETKEY(r0, r1, r2, r3, 124);
- S4(r0,r1,r2,r3,r4)
- SETKEY(r1, r4, r0, r3, 124)
-
- GETKEY(r0, r1, r2, r3, 128);
- S3(r0,r1,r2,r3,r4);
- SETKEY(r1, r2, r3, r4, 128)
-
- return 0;
-};
-
-/* Encryption and decryption functions. The rounds are fully inlined.
- * The sboxes alters the bit order of the output, and the altered
- * bit ordrer is used progressivly. */
-
-/* encrypt a block of text */
-
-int serpent_encrypt(serpent_context *cx, const u8 *in,
- u8 *out)
-{ u32 *l_key = cx->keyinfo;
- const u32 *in_blk = (const u32 *) in;
- u32 *out_blk = (u32 *) out;
- u32 r0,r1,r2,r3,r4;
-
-#ifdef BLOCK_SWAP
- r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
- r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
-#else
- r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
-#endif
-
- /* round 1 */
- KEYMIX(r0,r1,r2,r3,r4,0);
- S0(r0,r1,r2,r3,r4);
- LINTRANS(r1,r4,r2,r0,r3);
-
- /* round 2 */
- KEYMIX(r1,r4,r2,r0,r3,4);
- S1(r1,r4,r2,r0,r3);
- LINTRANS(r0,r4,r2,r1,r3);
-
- /* round 3 */
- KEYMIX(r0,r4,r2,r1,r3,8);
- S2(r0,r4,r2,r1,r3);
- LINTRANS(r2,r1,r4,r3,r0);
-
- /* round 4 */
- KEYMIX(r2,r1,r4,r3,r0,12);
- S3(r2,r1,r4,r3,r0);
- LINTRANS(r1,r4,r3,r0,r2);
-
- /* round 5 */
- KEYMIX(r1,r4,r3,r0,r2,16);
- S4(r1,r4,r3,r0,r2)
- LINTRANS(r4,r2,r1,r0,r3);
-
- /* round 6 */
- KEYMIX(r4,r2,r1,r0,r3,20);
- S5(r4,r2,r1,r0,r3);
- LINTRANS(r2,r0,r4,r1,r3);
-
- /* round 7 */
- KEYMIX(r2,r0,r4,r1,r3,24);
- S6(r2,r0,r4,r1,r3)
- LINTRANS(r2,r0,r3,r4,r1);
-
- /* round 8 */
- KEYMIX(r2,r0,r3,r4,r1,28);
- S7(r2,r0,r3,r4,r1);
- LINTRANS(r3,r1,r4,r2,r0);
-
- /* round 9 */
- KEYMIX(r3,r1,r4,r2,r0,32);
- S0(r3,r1,r4,r2,r0);
- LINTRANS(r1,r0,r4,r3,r2);
-
- /* round 10 */
- KEYMIX(r1,r0,r4,r3,r2,36);
- S1(r1,r0,r4,r3,r2);
- LINTRANS(r3,r0,r4,r1,r2);
-
- /* round 11 */
- KEYMIX(r3,r0,r4,r1,r2,40);
- S2(r3,r0,r4,r1,r2);
- LINTRANS(r4,r1,r0,r2,r3);
-
- /* round 12 */
- KEYMIX(r4,r1,r0,r2,r3,44);
- S3(r4,r1,r0,r2,r3);
- LINTRANS(r1,r0,r2,r3,r4);
-
- /* round 13 */
- KEYMIX(r1,r0,r2,r3,r4,48);
- S4(r1,r0,r2,r3,r4)
- LINTRANS(r0,r4,r1,r3,r2);
-
- /* round 14 */
- KEYMIX(r0,r4,r1,r3,r2,52);
- S5(r0,r4,r1,r3,r2);
- LINTRANS(r4,r3,r0,r1,r2);
-
- /* round 15 */
- KEYMIX(r4,r3,r0,r1,r2,56);
- S6(r4,r3,r0,r1,r2)
- LINTRANS(r4,r3,r2,r0,r1);
-
- /* round 16 */
- KEYMIX(r4,r3,r2,r0,r1,60);
- S7(r4,r3,r2,r0,r1);
- LINTRANS(r2,r1,r0,r4,r3);
-
- /* round 17 */
- KEYMIX(r2,r1,r0,r4,r3,64);
- S0(r2,r1,r0,r4,r3);
- LINTRANS(r1,r3,r0,r2,r4);
-
- /* round 18 */
- KEYMIX(r1,r3,r0,r2,r4,68);
- S1(r1,r3,r0,r2,r4);
- LINTRANS(r2,r3,r0,r1,r4);
-
- /* round 19 */
- KEYMIX(r2,r3,r0,r1,r4,72);
- S2(r2,r3,r0,r1,r4);
- LINTRANS(r0,r1,r3,r4,r2);
-
- /* round 20 */
- KEYMIX(r0,r1,r3,r4,r2,76);
- S3(r0,r1,r3,r4,r2);
- LINTRANS(r1,r3,r4,r2,r0);
-
- /* round 21 */
- KEYMIX(r1,r3,r4,r2,r0,80);
- S4(r1,r3,r4,r2,r0)
- LINTRANS(r3,r0,r1,r2,r4);
-
- /* round 22 */
- KEYMIX(r3,r0,r1,r2,r4,84);
- S5(r3,r0,r1,r2,r4);
- LINTRANS(r0,r2,r3,r1,r4);
-
- /* round 23 */
- KEYMIX(r0,r2,r3,r1,r4,88);
- S6(r0,r2,r3,r1,r4)
- LINTRANS(r0,r2,r4,r3,r1);
-
- /* round 24 */
- KEYMIX(r0,r2,r4,r3,r1,92);
- S7(r0,r2,r4,r3,r1);
- LINTRANS(r4,r1,r3,r0,r2);
-
- /* round 25 */
- KEYMIX(r4,r1,r3,r0,r2,96);
- S0(r4,r1,r3,r0,r2);
- LINTRANS(r1,r2,r3,r4,r0);
-
- /* round 26 */
- KEYMIX(r1,r2,r3,r4,r0,100);
- S1(r1,r2,r3,r4,r0);
- LINTRANS(r4,r2,r3,r1,r0);
-
- /* round 27 */
- KEYMIX(r4,r2,r3,r1,r0,104);
- S2(r4,r2,r3,r1,r0);
- LINTRANS(r3,r1,r2,r0,r4);
-
- /* round 28 */
- KEYMIX(r3,r1,r2,r0,r4,108);
- S3(r3,r1,r2,r0,r4);
- LINTRANS(r1,r2,r0,r4,r3);
-
- /* round 29 */
- KEYMIX(r1,r2,r0,r4,r3,112);
- S4(r1,r2,r0,r4,r3)
- LINTRANS(r2,r3,r1,r4,r0);
-
- /* round 30 */
- KEYMIX(r2,r3,r1,r4,r0,116);
- S5(r2,r3,r1,r4,r0);
- LINTRANS(r3,r4,r2,r1,r0);
-
- /* round 31 */
- KEYMIX(r3,r4,r2,r1,r0,120);
- S6(r3,r4,r2,r1,r0)
- LINTRANS(r3,r4,r0,r2,r1);
-
- /* round 32 */
- KEYMIX(r3,r4,r0,r2,r1,124);
- S7(r3,r4,r0,r2,r1);
- KEYMIX(r0,r1,r2,r3,r4,128);
-
-
-#ifdef BLOCK_SWAP
- out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
- out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
-#else
- out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
-#endif
- return 0;
-};
-
-/* decrypt a block of text */
-
-int serpent_decrypt(serpent_context *cx, const u8 *in,
- u8 *out)
-{ u32 *l_key = cx->keyinfo;
- const u32 *in_blk = (const u32 *)in;
- u32 *out_blk = (u32 *)out;
- u32 r0,r1,r2,r3,r4;
-
-#ifdef BLOCK_SWAP
- r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
- r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
-#else
- r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
-#endif
-
- /* round 1 */
- KEYMIX(r0,r1,r2,r3,r4,128);
- I7(r0,r1,r2,r3,r4);
- KEYMIX(r3,r0,r1,r4,r2,124);
-
- /* round 2 */
- ILINTRANS(r3,r0,r1,r4,r2);
- I6(r3,r0,r1,r4,r2);
- KEYMIX(r0,r1,r2,r4,r3,120);
-
- /* round 3 */
- ILINTRANS(r0,r1,r2,r4,r3);
- I5(r0,r1,r2,r4,r3);
- KEYMIX(r1,r3,r4,r2,r0,116);
-
- /* round 4 */
- ILINTRANS(r1,r3,r4,r2,r0);
- I4(r1,r3,r4,r2,r0);
- KEYMIX(r1,r2,r4,r0,r3,112);
-
- /* round 5 */
- ILINTRANS(r1,r2,r4,r0,r3);
- I3(r1,r2,r4,r0,r3);
- KEYMIX(r4,r2,r0,r1,r3,108);
-
- /* round 6 */
- ILINTRANS(r4,r2,r0,r1,r3);
- I2(r4,r2,r0,r1,r3);
- KEYMIX(r2,r3,r0,r1,r4,104);
-
- /* round 7 */
- ILINTRANS(r2,r3,r0,r1,r4);
- I1(r2,r3,r0,r1,r4);
- KEYMIX(r4,r2,r1,r0,r3,100);
-
- /* round 8 */
- ILINTRANS(r4,r2,r1,r0,r3);
- I0(r4,r2,r1,r0,r3);
- KEYMIX(r4,r3,r2,r0,r1,96);
-
- /* round 9 */
- ILINTRANS(r4,r3,r2,r0,r1);
- I7(r4,r3,r2,r0,r1);
- KEYMIX(r0,r4,r3,r1,r2,92);
-
- /* round 10 */
- ILINTRANS(r0,r4,r3,r1,r2);
- I6(r0,r4,r3,r1,r2);
- KEYMIX(r4,r3,r2,r1,r0,88);
-
- /* round 11 */
- ILINTRANS(r4,r3,r2,r1,r0);
- I5(r4,r3,r2,r1,r0);
- KEYMIX(r3,r0,r1,r2,r4,84);
-
- /* round 12 */
- ILINTRANS(r3,r0,r1,r2,r4);
- I4(r3,r0,r1,r2,r4);
- KEYMIX(r3,r2,r1,r4,r0,80);
-
- /* round 13 */
- ILINTRANS(r3,r2,r1,r4,r0);
- I3(r3,r2,r1,r4,r0);
- KEYMIX(r1,r2,r4,r3,r0,76);
-
- /* round 14 */
- ILINTRANS(r1,r2,r4,r3,r0);
- I2(r1,r2,r4,r3,r0);
- KEYMIX(r2,r0,r4,r3,r1,72);
-
- /* round 15 */
- ILINTRANS(r2,r0,r4,r3,r1);
- I1(r2,r0,r4,r3,r1);
- KEYMIX(r1,r2,r3,r4,r0,68);
-
- /* round 16 */
- ILINTRANS(r1,r2,r3,r4,r0);
- I0(r1,r2,r3,r4,r0);
- KEYMIX(r1,r0,r2,r4,r3,64);
-
- /* round 17 */
- ILINTRANS(r1,r0,r2,r4,r3);
- I7(r1,r0,r2,r4,r3);
- KEYMIX(r4,r1,r0,r3,r2,60);
-
- /* round 18 */
- ILINTRANS(r4,r1,r0,r3,r2);
- I6(r4,r1,r0,r3,r2);
- KEYMIX(r1,r0,r2,r3,r4,56);
-
- /* round 19 */
- ILINTRANS(r1,r0,r2,r3,r4);
- I5(r1,r0,r2,r3,r4);
- KEYMIX(r0,r4,r3,r2,r1,52);
-
- /* round 20 */
- ILINTRANS(r0,r4,r3,r2,r1);
- I4(r0,r4,r3,r2,r1);
- KEYMIX(r0,r2,r3,r1,r4,48);
-
- /* round 21 */
- ILINTRANS(r0,r2,r3,r1,r4);
- I3(r0,r2,r3,r1,r4);
- KEYMIX(r3,r2,r1,r0,r4,44);
-
- /* round 22 */
- ILINTRANS(r3,r2,r1,r0,r4);
- I2(r3,r2,r1,r0,r4);
- KEYMIX(r2,r4,r1,r0,r3,40);
-
- /* round 23 */
- ILINTRANS(r2,r4,r1,r0,r3);
- I1(r2,r4,r1,r0,r3);
- KEYMIX(r3,r2,r0,r1,r4,36);
-
- /* round 24 */
- ILINTRANS(r3,r2,r0,r1,r4);
- I0(r3,r2,r0,r1,r4);
- KEYMIX(r3,r4,r2,r1,r0,32);
-
- /* round 25 */
- ILINTRANS(r3,r4,r2,r1,r0);
- I7(r3,r4,r2,r1,r0);
- KEYMIX(r1,r3,r4,r0,r2,28);
-
- /* round 26 */
- ILINTRANS(r1,r3,r4,r0,r2);
- I6(r1,r3,r4,r0,r2);
- KEYMIX(r3,r4,r2,r0,r1,24);
-
- /* round 27 */
- ILINTRANS(r3,r4,r2,r0,r1);
- I5(r3,r4,r2,r0,r1);
- KEYMIX(r4,r1,r0,r2,r3,20);
-
- /* round 28 */
- ILINTRANS(r4,r1,r0,r2,r3);
- I4(r4,r1,r0,r2,r3);
- KEYMIX(r4,r2,r0,r3,r1,16);
-
- /* round 29 */
- ILINTRANS(r4,r2,r0,r3,r1);
- I3(r4,r2,r0,r3,r1);
- KEYMIX(r0,r2,r3,r4,r1,12);
-
- /* round 30 */
- ILINTRANS(r0,r2,r3,r4,r1);
- I2(r0,r2,r3,r4,r1);
- KEYMIX(r2,r1,r3,r4,r0,8);
-
- /* round 31 */
- ILINTRANS(r2,r1,r3,r4,r0);
- I1(r2,r1,r3,r4,r0);
- KEYMIX(r0,r2,r4,r3,r1,4);
-
- /* round 32 */
- ILINTRANS(r0,r2,r4,r3,r1);
- I0(r0,r2,r4,r3,r1);
- KEYMIX(r0,r1,r2,r3,r4,0);
-
-#ifdef BLOCK_SWAP
- out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
- out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
-#else
- out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
-#endif
- return 0;
-};
-
-
diff --git a/src/libcrypto/libserpent/serpent.h b/src/libcrypto/libserpent/serpent.h
deleted file mode 100644
index 6357f5bfa..000000000
--- a/src/libcrypto/libserpent/serpent.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef SERPENT_H
-#define SERPENT_H
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#define u32 u_int32_t
-#define u8 u_int8_t
-#endif
-struct serpent_context {
- u32 keyinfo[140]; /* storage for the key schedule */
-};
-typedef struct serpent_context serpent_context;
-int serpent_set_key(serpent_context *ctx, const u8 * in_key, int key_len);
-int serpent_decrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
-int serpent_encrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
-#endif /* SERPENT_H */
diff --git a/src/libcrypto/libserpent/serpent_cbc.c b/src/libcrypto/libserpent/serpent_cbc.c
deleted file mode 100644
index 3b546278a..000000000
--- a/src/libcrypto/libserpent/serpent_cbc.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-#include "serpent_cbc.h"
-#include "cbc_generic.h"
-CBC_IMPL_BLK16(serpent_cbc_encrypt, serpent_context, u_int8_t *, serpent_encrypt, serpent_decrypt);
diff --git a/src/libcrypto/libserpent/serpent_cbc.h b/src/libcrypto/libserpent/serpent_cbc.h
deleted file mode 100644
index 3064fa3bc..000000000
--- a/src/libcrypto/libserpent/serpent_cbc.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Glue header */
-#include "serpent.h"
-int serpent_cbc_encrypt(serpent_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
diff --git a/src/libcrypto/libsha2/hmac_sha2.c b/src/libcrypto/libsha2/hmac_sha2.c
deleted file mode 100644
index ad107eb62..000000000
--- a/src/libcrypto/libsha2/hmac_sha2.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <linux/string.h>
-#else
-#include <sys/types.h>
-#include <string.h>
-#endif
-#include "hmac_generic.h"
-#include "sha2.h"
-#include "hmac_sha2.h"
-
-void inline sha256_result(sha256_context *ctx, u_int8_t * hash, int hashlen) {
- sha256_final(ctx);
- memcpy(hash, &ctx->sha_out[0], hashlen);
-}
-void inline sha512_result(sha512_context *ctx, u_int8_t * hash, int hashlen) {
- sha512_final(ctx);
- memcpy(hash, &ctx->sha_out[0], hashlen);
-}
-HMAC_SET_KEY_IMPL (sha256_hmac_set_key,
- sha256_hmac_context, SHA256_BLOCKSIZE,
- sha256_init, sha256_write)
-HMAC_HASH_IMPL (sha256_hmac_hash,
- sha256_hmac_context, sha256_context, SHA256_HASHLEN,
- sha256_write, sha256_result)
-
-HMAC_SET_KEY_IMPL (sha512_hmac_set_key,
- sha512_hmac_context, SHA512_BLOCKSIZE,
- sha512_init, sha512_write)
-HMAC_HASH_IMPL (sha512_hmac_hash,
- sha512_hmac_context, sha512_context, SHA512_HASHLEN,
- sha512_write, sha512_result)
diff --git a/src/libcrypto/libsha2/hmac_sha2.h b/src/libcrypto/libsha2/hmac_sha2.h
deleted file mode 100644
index b7f8c747c..000000000
--- a/src/libcrypto/libsha2/hmac_sha2.h
+++ /dev/null
@@ -1,17 +0,0 @@
-typedef struct {
- sha256_context ictx,octx;
-} sha256_hmac_context;
-typedef struct {
- sha512_context ictx,octx;
-} sha512_hmac_context;
-#define SHA256_BLOCKSIZE 64
-#define SHA256_HASHLEN 32
-#define SHA384_BLOCKSIZE 128 /* XXX ok? */
-#define SHA384_HASHLEN 48
-#define SHA512_BLOCKSIZE 128
-#define SHA512_HASHLEN 64
-
-void sha256_hmac_hash(sha256_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen);
-void sha256_hmac_set_key(sha256_hmac_context *hctx, const u_int8_t * key, int keylen);
-void sha512_hmac_hash(sha512_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen);
-void sha512_hmac_set_key(sha512_hmac_context *hctx, const u_int8_t * key, int keylen);
diff --git a/src/libcrypto/libsha2/sha2.c b/src/libcrypto/libsha2/sha2.c
deleted file mode 100644
index 4debdad67..000000000
--- a/src/libcrypto/libsha2/sha2.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * sha512.c
- *
- * Written by Jari Ruusu, April 16 2001
- *
- * Copyright 2001 by Jari Ruusu.
- * Redistribution of this file is permitted under the GNU Public License.
- */
-
-#ifdef __KERNEL__
-#include <linux/string.h>
-#include <linux/types.h>
-#else
-#include <string.h>
-#include <sys/types.h>
-#endif
-#include "sha2.h"
-
-/* Define one or more of these. If none is defined, you get all of them */
-#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED)
-# define SHA256_NEEDED 1
-# define SHA512_NEEDED 1
-# define SHA384_NEEDED 1
-#endif
-
-#if defined(SHA256_NEEDED)
-static const u_int32_t sha256_hashInit[8] = {
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
- 0x1f83d9ab, 0x5be0cd19
-};
-static const u_int32_t sha256_K[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-#endif
-
-#if defined(SHA512_NEEDED)
-static const u_int64_t sha512_hashInit[8] = {
- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
- 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
-};
-#endif
-
-#if defined(SHA384_NEEDED)
-static const u_int64_t sha384_hashInit[8] = {
- 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
- 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
- 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
-};
-#endif
-
-#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
-static const u_int64_t sha512_K[80] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
- 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
- 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
- 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
- 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
- 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
- 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
- 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
- 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
- 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
- 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
- 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
- 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
- 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
- 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
- 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
- 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
- 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
- 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
- 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
- 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
-};
-#endif
-
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-#define R(x,y) ((y) >> (x))
-
-#if defined(SHA256_NEEDED)
-void sha256_init(sha256_context *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_bufCnt = 0;
-}
-
-#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
-#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
-#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
-#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
-#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
-
-static void sha256_transform(sha256_context *ctx, const unsigned char *datap)
-{
- register int j;
- u_int32_t a, b, c, d, e, f, g, h;
- u_int32_t T1, T2, W[64], Wm2, Wm15;
-
- /* read the data, big endian byte order */
- j = 0;
- do {
- W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
- (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
- datap += 4;
- } while(++j < 16);
-
- /* initialize variables a...h */
- a = ctx->sha_H[0];
- b = ctx->sha_H[1];
- c = ctx->sha_H[2];
- d = ctx->sha_H[3];
- e = ctx->sha_H[4];
- f = ctx->sha_H[5];
- g = ctx->sha_H[6];
- h = ctx->sha_H[7];
-
- /* apply compression function */
- j = 0;
- do {
- if(j >= 16) {
- Wm2 = W[j - 2];
- Wm15 = W[j - 15];
- W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
- }
- T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
- T2 = uSig0(a) + Maj(a,b,c);
- h = g; g = f; f = e;
- e = d + T1;
- d = c; c = b; b = a;
- a = T1 + T2;
- } while(++j < 64);
-
- /* compute intermediate hash value */
- ctx->sha_H[0] += a;
- ctx->sha_H[1] += b;
- ctx->sha_H[2] += c;
- ctx->sha_H[3] += d;
- ctx->sha_H[4] += e;
- ctx->sha_H[5] += f;
- ctx->sha_H[6] += g;
- ctx->sha_H[7] += h;
-
- ctx->sha_blocks++;
-}
-
-void sha256_write(sha256_context *ctx, const unsigned char *datap, int length)
-{
- while(length > 0) {
- if(!ctx->sha_bufCnt) {
- while(length >= sizeof(ctx->sha_out)) {
- sha256_transform(ctx, datap);
- datap += sizeof(ctx->sha_out);
- length -= sizeof(ctx->sha_out);
- }
- if(!length) return;
- }
- ctx->sha_out[ctx->sha_bufCnt] = *datap++;
- length--;
- if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
- sha256_transform(ctx, &ctx->sha_out[0]);
- ctx->sha_bufCnt = 0;
- }
- }
-}
-
-void sha256_final(sha256_context *ctx)
-{
- register int j;
- u_int64_t bitLength;
- u_int32_t i;
- unsigned char padByte, *datap;
-
- bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
- padByte = 0x80;
- sha256_write(ctx, &padByte, 1);
-
- /* pad extra space with zeroes */
- padByte = 0;
- while(ctx->sha_bufCnt != 56) {
- sha256_write(ctx, &padByte, 1);
- }
-
- /* write bit length, big endian byte order */
- ctx->sha_out[56] = bitLength >> 56;
- ctx->sha_out[57] = bitLength >> 48;
- ctx->sha_out[58] = bitLength >> 40;
- ctx->sha_out[59] = bitLength >> 32;
- ctx->sha_out[60] = bitLength >> 24;
- ctx->sha_out[61] = bitLength >> 16;
- ctx->sha_out[62] = bitLength >> 8;
- ctx->sha_out[63] = bitLength;
- sha256_transform(ctx, &ctx->sha_out[0]);
-
- /* return results in ctx->sha_out[0...31] */
- datap = &ctx->sha_out[0];
- j = 0;
- do {
- i = ctx->sha_H[j];
- datap[0] = i >> 24;
- datap[1] = i >> 16;
- datap[2] = i >> 8;
- datap[3] = i;
- datap += 4;
- } while(++j < 8);
-
- /* clear sensitive information */
- memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32);
-}
-
-void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
-{
- sha256_context ctx;
-
- if(ole < 1) return;
- memset(ob, 0, ole);
- if(ole > 32) ole = 32;
- sha256_init(&ctx);
- sha256_write(&ctx, ib, ile);
- sha256_final(&ctx);
- memcpy(ob, &ctx.sha_out[0], ole);
- memset(&ctx, 0, sizeof(ctx));
-}
-
-#endif
-
-#if defined(SHA512_NEEDED)
-void sha512_init(sha512_context *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-#endif
-
-#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
-#undef S
-#undef uSig0
-#undef uSig1
-#undef lSig0
-#undef lSig1
-#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
-#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
-#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
-#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
-#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
-
-static void sha512_transform(sha512_context *ctx, const unsigned char *datap)
-{
- register int j;
- u_int64_t a, b, c, d, e, f, g, h;
- u_int64_t T1, T2, W[80], Wm2, Wm15;
-
- /* read the data, big endian byte order */
- j = 0;
- do {
- W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
- (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
- (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
- (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
- datap += 8;
- } while(++j < 16);
-
- /* initialize variables a...h */
- a = ctx->sha_H[0];
- b = ctx->sha_H[1];
- c = ctx->sha_H[2];
- d = ctx->sha_H[3];
- e = ctx->sha_H[4];
- f = ctx->sha_H[5];
- g = ctx->sha_H[6];
- h = ctx->sha_H[7];
-
- /* apply compression function */
- j = 0;
- do {
- if(j >= 16) {
- Wm2 = W[j - 2];
- Wm15 = W[j - 15];
- W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
- }
- T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
- T2 = uSig0(a) + Maj(a,b,c);
- h = g; g = f; f = e;
- e = d + T1;
- d = c; c = b; b = a;
- a = T1 + T2;
- } while(++j < 80);
-
- /* compute intermediate hash value */
- ctx->sha_H[0] += a;
- ctx->sha_H[1] += b;
- ctx->sha_H[2] += c;
- ctx->sha_H[3] += d;
- ctx->sha_H[4] += e;
- ctx->sha_H[5] += f;
- ctx->sha_H[6] += g;
- ctx->sha_H[7] += h;
-
- ctx->sha_blocks++;
- if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
-}
-
-void sha512_write(sha512_context *ctx, const unsigned char *datap, int length)
-{
- while(length > 0) {
- if(!ctx->sha_bufCnt) {
- while(length >= sizeof(ctx->sha_out)) {
- sha512_transform(ctx, datap);
- datap += sizeof(ctx->sha_out);
- length -= sizeof(ctx->sha_out);
- }
- if(!length) return;
- }
- ctx->sha_out[ctx->sha_bufCnt] = *datap++;
- length--;
- if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
- sha512_transform(ctx, &ctx->sha_out[0]);
- ctx->sha_bufCnt = 0;
- }
- }
-}
-
-void sha512_final(sha512_context *ctx)
-{
- register int j;
- u_int64_t bitLength, bitLengthMSB;
- u_int64_t i;
- unsigned char padByte, *datap;
-
- bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
- bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
- padByte = 0x80;
- sha512_write(ctx, &padByte, 1);
-
- /* pad extra space with zeroes */
- padByte = 0;
- while(ctx->sha_bufCnt != 112) {
- sha512_write(ctx, &padByte, 1);
- }
-
- /* write bit length, big endian byte order */
- ctx->sha_out[112] = bitLengthMSB >> 56;
- ctx->sha_out[113] = bitLengthMSB >> 48;
- ctx->sha_out[114] = bitLengthMSB >> 40;
- ctx->sha_out[115] = bitLengthMSB >> 32;
- ctx->sha_out[116] = bitLengthMSB >> 24;
- ctx->sha_out[117] = bitLengthMSB >> 16;
- ctx->sha_out[118] = bitLengthMSB >> 8;
- ctx->sha_out[119] = bitLengthMSB;
- ctx->sha_out[120] = bitLength >> 56;
- ctx->sha_out[121] = bitLength >> 48;
- ctx->sha_out[122] = bitLength >> 40;
- ctx->sha_out[123] = bitLength >> 32;
- ctx->sha_out[124] = bitLength >> 24;
- ctx->sha_out[125] = bitLength >> 16;
- ctx->sha_out[126] = bitLength >> 8;
- ctx->sha_out[127] = bitLength;
- sha512_transform(ctx, &ctx->sha_out[0]);
-
- /* return results in ctx->sha_out[0...63] */
- datap = &ctx->sha_out[0];
- j = 0;
- do {
- i = ctx->sha_H[j];
- datap[0] = i >> 56;
- datap[1] = i >> 48;
- datap[2] = i >> 40;
- datap[3] = i >> 32;
- datap[4] = i >> 24;
- datap[5] = i >> 16;
- datap[6] = i >> 8;
- datap[7] = i;
- datap += 8;
- } while(++j < 8);
-
- /* clear sensitive information */
- memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64);
-}
-
-void sha512_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
-{
- sha512_context ctx;
-
- if(ole < 1) return;
- memset(ob, 0, ole);
- if(ole > 64) ole = 64;
- sha512_init(&ctx);
- sha512_write(&ctx, ib, ile);
- sha512_final(&ctx);
- memcpy(ob, &ctx.sha_out[0], ole);
- memset(&ctx, 0, sizeof(ctx));
-}
-#endif
-
-#if defined(SHA384_NEEDED)
-void sha384_init(sha512_context *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-
-void sha384_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
-{
- sha512_context ctx;
-
- if(ole < 1) return;
- memset(ob, 0, ole);
- if(ole > 48) ole = 48;
- sha384_init(&ctx);
- sha512_write(&ctx, ib, ile);
- sha512_final(&ctx);
- memcpy(ob, &ctx.sha_out[0], ole);
- memset(&ctx, 0, sizeof(ctx));
-}
-#endif
diff --git a/src/libcrypto/libsha2/sha2.h b/src/libcrypto/libsha2/sha2.h
deleted file mode 100644
index 2dc03cfa8..000000000
--- a/src/libcrypto/libsha2/sha2.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _SHA2_H
-#define _SHA2_H
-/*
- * sha512.h
- *
- * Written by Jari Ruusu, April 16 2001
- *
- * Copyright 2001 by Jari Ruusu.
- * Redistribution of this file is permitted under the GNU Public License.
- */
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-
-typedef struct {
- unsigned char sha_out[64]; /* results are here, bytes 0...31 */
- u_int32_t sha_H[8];
- u_int64_t sha_blocks;
- int sha_bufCnt;
-} sha256_context;
-
-typedef struct {
- unsigned char sha_out[128]; /* results are here, bytes 0...63 */
- u_int64_t sha_H[8];
- u_int64_t sha_blocks;
- u_int64_t sha_blocksMSB;
- int sha_bufCnt;
-} sha512_context;
-
-/* no sha384_context, use sha512_context */
-
-/* 256 bit hash, provides 128 bits of security against collision attacks */
-extern void sha256_init(sha256_context *);
-extern void sha256_write(sha256_context *, const unsigned char *, int);
-extern void sha256_final(sha256_context *);
-extern void sha256_hash_buffer(unsigned char *, int, unsigned char *, int);
-
-/* 512 bit hash, provides 256 bits of security against collision attacks */
-extern void sha512_init(sha512_context *);
-extern void sha512_write(sha512_context *, const unsigned char *, int);
-extern void sha512_final(sha512_context *);
-extern void sha512_hash_buffer(unsigned char *, int, unsigned char *, int);
-
-/* 384 bit hash, provides 192 bits of security against collision attacks */
-extern void sha384_init(sha512_context *);
-/* no sha384_write(), use sha512_write() */
-/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47] */
-extern void sha384_hash_buffer(unsigned char *, int, unsigned char *, int);
-#endif /* _SHA2_H */
diff --git a/src/libcrypto/libtwofish/twofish.c b/src/libcrypto/libtwofish/twofish.c
deleted file mode 100644
index 0e01a92d2..000000000
--- a/src/libcrypto/libtwofish/twofish.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/* NOTE: This implementation has been changed from the original
- * source. See ChangeLog for more information.
- * Maintained by Marc Mutz <Marc@Mutz.com>
- */
-
-/* Twofish for GPG
- * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
- * 256-bit key length added March 20, 1999
- * Some modifications to reduce the text size by Werner Koch, April, 1998
- *
- * The original author has disclaimed all copyright interest in this
- * code and thus putting it in the public domain.
- *
- * This code is a "clean room" implementation, written from the paper
- * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
- * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
- * through http://www.counterpane.com/twofish.html
- *
- * For background information on multiplication in finite fields, used for
- * the matrix operations in the key schedule, see the book _Contemporary
- * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
- * Third Edition.
- *
- * Only the 128- and 256-bit key sizes are supported. This code is intended
- * for GNU C on a 32-bit system, but it should work almost anywhere. Loops
- * are unrolled, precomputation tables are used, etc., for maximum speed at
- * some cost in memory consumption. */
-
-#ifdef __KERNEL__
-#include <linux/init.h>
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#define u8 u_int8_t
-#define u32 u_int32_t
-#endif
-
-#if 0 /* shouldn't this be #ifdef rotl32 ?
- * Look at wordops.h: It includes asm/wordops.h.
- * Anyway, we have to search in the macros for rot's,
- * since they seem to be defined in a generic way. */
-#define rotl rotl32
-#define rotr rotr32
-#else
-#define rotl generic_rotl32
-#define rotr generic_rotr32
-#endif
-
-#include "twofish.h"
-/* The large precomputed tables for the Twofish cipher (twofish.c)
- * Taken from the same source as twofish.c
- * Marc Mutz <Marc@Mutz.com>
- */
-
-/* These two tables are the q0 and q1 permutations, exactly as described in
- * the Twofish paper. */
-
-static const u8 q0[256] = {
- 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
- 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
- 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
- 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
- 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
- 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
- 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
- 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
- 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
- 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
- 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
- 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
- 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
- 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
- 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
- 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
- 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
- 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
- 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
- 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
- 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
- 0x4A, 0x5E, 0xC1, 0xE0
-};
-
-static const u8 q1[256] = {
- 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
- 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
- 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
- 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
- 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
- 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
- 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
- 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
- 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
- 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
- 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
- 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
- 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
- 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
- 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
- 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
- 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
- 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
- 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
- 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
- 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
- 0x55, 0x09, 0xBE, 0x91
-};
-
-/* These MDS tables are actually tables of MDS composed with q0 and q1,
- * because it is only ever used that way and we can save some time by
- * precomputing. Of course the main saving comes from precomputing the
- * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
- * things up in these tables we reduce the matrix multiply to four lookups
- * and three XORs. Semi-formally, the definition of these tables is:
- * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
- * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
- * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
- * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
- * by Schneier et al, and I'm casually glossing over the byte/word
- * conversion issues. */
-
-static const u32 mds[4][256] = {
- {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
- 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
- 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
- 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
- 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
- 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
- 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
- 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
- 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
- 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
- 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
- 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
- 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
- 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
- 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
- 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
- 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
- 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
- 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
- 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
- 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
- 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
- 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
- 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
- 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
- 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
- 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
- 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
- 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
- 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
- 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
- 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
- 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
- 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
- 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
- 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
- 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
- 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
- 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
- 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
- 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
- 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
- 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
-
- {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
- 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
- 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
- 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
- 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
- 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
- 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
- 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
- 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
- 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
- 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
- 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
- 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
- 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
- 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
- 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
- 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
- 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
- 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
- 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
- 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
- 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
- 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
- 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
- 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
- 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
- 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
- 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
- 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
- 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
- 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
- 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
- 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
- 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
- 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
- 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
- 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
- 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
- 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
- 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
- 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
- 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
- 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
-
- {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
- 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
- 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
- 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
- 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
- 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
- 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
- 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
- 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
- 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
- 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
- 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
- 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
- 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
- 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
- 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
- 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
- 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
- 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
- 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
- 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
- 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
- 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
- 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
- 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
- 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
- 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
- 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
- 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
- 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
- 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
- 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
- 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
- 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
- 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
- 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
- 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
- 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
- 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
- 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
- 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
- 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
- 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
-
- {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
- 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
- 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
- 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
- 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
- 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
- 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
- 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
- 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
- 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
- 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
- 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
- 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
- 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
- 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
- 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
- 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
- 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
- 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
- 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
- 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
- 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
- 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
- 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
- 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
- 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
- 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
- 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
- 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
- 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
- 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
- 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
- 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
- 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
- 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
- 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
- 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
- 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
- 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
- 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
- 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
- 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
- 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
-};
-
-/* The exp_to_poly and poly_to_exp tables are used to perform efficient
- * operations in GF(2^8) represented as GF(2)[x]/w(x) where
- * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
- * definition of the RS matrix in the key schedule. Elements of that field
- * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
- * which can be represented naturally by bytes (just substitute x=2). In that
- * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
- * multiplication is inefficient without hardware support. To multiply
- * faster, I make use of the fact x is a generator for the nonzero elements,
- * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
- * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
- * *not* polynomial notation. So if I want to compute pq where p and q are
- * in GF(2^8), I can just say:
- * 1. if p=0 or q=0 then pq=0
- * 2. otherwise, find m and n such that p=x^m and q=x^n
- * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
- * The translations in steps 2 and 3 are looked up in the tables
- * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
- * in action, look at the CALC_S macro. As additional wrinkles, note that
- * one of my operands is always a constant, so the poly_to_exp lookup on it
- * is done in advance; I included the original values in the comments so
- * readers can have some chance of recognizing that this *is* the RS matrix
- * from the Twofish paper. I've only included the table entries I actually
- * need; I never do a lookup on a variable input of zero and the biggest
- * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
- * never sum to more than 491. I'm repeating part of the exp_to_poly table
- * so that I don't have to do mod-255 reduction in the exponent arithmetic.
- * Since I know my constant operands are never zero, I only have to worry
- * about zero values in the variable operand, and I do it with a simple
- * conditional branch. I know conditionals are expensive, but I couldn't
- * see a non-horrible way of avoiding them, and I did manage to group the
- * statements so that each if covers four group multiplications. */
-
-static const u8 poly_to_exp[255] = {
- 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
- 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
- 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
- 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
- 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
- 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
- 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
- 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
- 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
- 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
- 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
- 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
- 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
- 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
- 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
- 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
- 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
- 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
- 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
- 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
- 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
- 0x85, 0xC8, 0xA1
-};
-
-static const u8 exp_to_poly[492] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
- 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
- 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
- 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
- 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
- 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
- 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
- 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
- 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
- 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
- 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
- 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
- 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
- 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
- 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
- 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
- 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
- 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
- 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
- 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
- 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
- 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
- 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
- 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
- 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
- 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
- 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
- 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
- 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
- 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
- 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
- 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
- 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
- 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
- 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
- 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
- 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
- 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
- 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
- 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
- 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
-};
-
-
-/* The table constants are indices of
- * S-box entries, preprocessed through q0 and q1. */
-static const u8 calc_sb_tbl[512] = {
- 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
- 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
- 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
- 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
- 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
- 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
- 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
- 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
- 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
- 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
- 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
- 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
- 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
- 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
- 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
- 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
- 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
- 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
- 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
- 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
- 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
- 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
- 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
- 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
- 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
- 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
- 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
- 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
- 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
- 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
- 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
- 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
- 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
- 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
- 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
- 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
- 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
- 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
- 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
- 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
- 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
- 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
- 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
- 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
- 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
- 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
- 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
- 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
- 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
- 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
- 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
- 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
- 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
- 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
- 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
- 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
- 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
- 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
- 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
- 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
- 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
- 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
- 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
- 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
-};
-
-/* Macro to perform one column of the RS matrix multiplication. The
- * parameters a, b, c, and d are the four bytes of output; i is the index
- * of the key bytes, and w, x, y, and z, are the column of constants from
- * the RS matrix, preprocessed through the poly_to_exp table. */
-
-#define CALC_S(a, b, c, d, i, w, x, y, z) \
- if (key[i]) { \
- tmp = poly_to_exp[key[i] - 1]; \
- (a) ^= exp_to_poly[tmp + (w)]; \
- (b) ^= exp_to_poly[tmp + (x)]; \
- (c) ^= exp_to_poly[tmp + (y)]; \
- (d) ^= exp_to_poly[tmp + (z)]; \
- }
-
-/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
- * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
- * four S-boxes, where i is the index of the entry to compute, and a and b
- * are the index numbers preprocessed through the q0 and q1 tables
- * respectively. */
-
-#define CALC_SB_2(i, a, b) \
- ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
- ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
- ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
- ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
-
-/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
-
-#define CALC_SB192_2(i, a, b) \
- ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
- ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
- ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
- ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
-
-/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
-
-#define CALC_SB256_2(i, a, b) \
- ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
- ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
- ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
- ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
-
-/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
- * last two stages of the h() function for a given index (either 2i or 2i+1).
- * a, b, c, and d are the four bytes going into the last two stages. For
- * 128-bit keys, this is the entire h() function and a and c are the index
- * preprocessed through q0 and q1 respectively; for longer keys they are the
- * output of previous stages. j is the index of the first key byte to use.
- * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
- * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
- * rotations. Its parameters are: a, the array to write the results into,
- * j, the index of the first output entry, k and l, the preprocessed indices
- * for index 2i, and m and n, the preprocessed indices for index 2i+1.
- * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
- * additional lookup-and-XOR stage. The parameters a, b, c and d are the
- * four bytes going into the last three stages. For 192-bit keys, c = d
- * are the index preprocessed through q0, and a = b are the index
- * preprocessed through q1; j is the index of the first key byte to use.
- * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
- * instead of CALC_K_2.
- * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
- * additional lookup-and-XOR stage. The parameters a and b are the index
- * preprocessed through q0 and q1 respectively; j is the index of the first
- * key byte to use. CALC_K256 is identical to CALC_K but for using the
- * CALC_K256_2 macro instead of CALC_K_2. */
-
-#define CALC_K_2(a, b, c, d, j) \
- mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
- ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
- ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
- ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
-
-#define CALC_K(a, j, k, l, m, n) \
- x = CALC_K_2 (k, l, k, l, 0); \
- y = CALC_K_2 (m, n, m, n, 4); \
- y = (y << 8) + (y >> 24); \
- x += y; y += x; ctx->a[j] = x; \
- ctx->a[(j) + 1] = (y << 9) + (y >> 23)
-
-#define CALC_K192_2(a, b, c, d, j) \
- CALC_K_2 (q0[a ^ key[(j) + 16]], \
- q1[b ^ key[(j) + 17]], \
- q0[c ^ key[(j) + 18]], \
- q1[d ^ key[(j) + 19]], j)
-
-#define CALC_K192(a, j, k, l, m, n) \
- x = CALC_K192_2 (l, l, k, k, 0); \
- y = CALC_K192_2 (n, n, m, m, 4); \
- y = (y << 8) + (y >> 24); \
- x += y; y += x; ctx->a[j] = x; \
- ctx->a[(j) + 1] = (y << 9) + (y >> 23)
-
-#define CALC_K256_2(a, b, j) \
- CALC_K192_2 (q1[b ^ key[(j) + 24]], \
- q1[a ^ key[(j) + 25]], \
- q0[a ^ key[(j) + 26]], \
- q0[b ^ key[(j) + 27]], j)
-
-#define CALC_K256(a, j, k, l, m, n) \
- x = CALC_K256_2 (k, l, 0); \
- y = CALC_K256_2 (m, n, 4); \
- y = (y << 8) + (y >> 24); \
- x += y; y += x; ctx->a[j] = x; \
- ctx->a[(j) + 1] = (y << 9) + (y >> 23)
-
-/* Perform the key setup. */
-
-int twofish_set_key (TWOFISH_context *ctx,
- const unsigned char *key, int key_len)
-{
-
- int i, j, k;
-
- /* Temporaries for CALC_K. */
- u32 x, y;
-
- /* The S vector used to key the S-boxes, split up into individual bytes.
- * 128-bit keys use only sa through sh; 256-bit use all of them. */
- u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
- u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
-
- /* Temporary for CALC_S. */
- u8 tmp;
-
- /* Check key length. */
- if (key_len != 16 && key_len != 24 && key_len != 32)
- return -1; /* unsupported key length */
-
- /* Compute the first two words of the S vector. The magic numbers are
- * the entries of the RS matrix, preprocessed through poly_to_exp. The
- * numbers in the comments are the original (polynomial form) matrix
- * entries. */
- CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
- CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
- CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
- CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
- CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
- CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
- CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
- CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
- CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
- CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
- CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
- CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
- CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
- CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
- CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
- CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-
- if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
- /* Calculate the third word of the S vector */
- CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
- CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
- CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
- CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
- CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
- CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
- CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
- CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
- }
-
- if (key_len == 32) { /* 256-bit key */
- /* Calculate the fourth word of the S vector */
- CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
- CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
- CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
- CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
- CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
- CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
- CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
- CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
-
- /* Compute the S-boxes. */
- for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
- CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
- }
-
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
- } else if (key_len == 24) { /* 192-bit key */
- /* Compute the S-boxes. */
- for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
- CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
- }
-
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
- } else { /* 128-bit key */
- /* Compute the S-boxes. */
- for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
- CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
- }
-
- /* Calculate whitening and round subkeys. The constants are
- * indices of subkeys, preprocessed through q0 and q1. */
- CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
- CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
- CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
- CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
- CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
- CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
- CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
- CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
- CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
- CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
- CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
- CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
- CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
- CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
- CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
- CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
- CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
- CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
- CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
- CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
- }
-
- return 0;
-}
-
-/* Macros to compute the g() function in the encryption and decryption
- * rounds. G1 is the straight g() function; G2 includes the 8-bit
- * rotation for the high 32-bit word. */
-
-#define G1(a) \
- (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
- ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
-
-#define G2(b) \
- (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
- ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
-
-/* Encryption and decryption Feistel rounds. Each one calls the two g()
- * macros, does the PHT, and performs the XOR and the appropriate bit
- * rotations. The parameters are the round number (used to select subkeys),
- * and the four 32-bit chunks of the text. */
-
-#define ENCROUND(n, a, b, c, d) \
- x = G1 (a); y = G2 (b); \
- x += y; y += x + ctx->k[2 * (n) + 1]; \
- (c) ^= x + ctx->k[2 * (n)]; \
- (c) = ((c) >> 1) + ((c) << 31); \
- (d) = (((d) << 1)+((d) >> 31)) ^ y
-
-#define DECROUND(n, a, b, c, d) \
- x = G1 (a); y = G2 (b); \
- x += y; y += x; \
- (d) ^= y + ctx->k[2 * (n) + 1]; \
- (d) = ((d) >> 1) + ((d) << 31); \
- (c) = (((c) << 1)+((c) >> 31)); \
- (c) ^= (x + ctx->k[2 * (n)])
-
-/* Encryption and decryption cycles; each one is simply two Feistel rounds
- * with the 32-bit chunks re-ordered to simulate the "swap" */
-
-#define ENCCYCLE(n) \
- ENCROUND (2 * (n), a, b, c, d); \
- ENCROUND (2 * (n) + 1, c, d, a, b)
-
-#define DECCYCLE(n) \
- DECROUND (2 * (n) + 1, c, d, a, b); \
- DECROUND (2 * (n), a, b, c, d)
-
-/* Macros to convert the input and output bytes into 32-bit words,
- * and simultaneously perform the whitening step. INPACK packs word
- * number n into the variable named by x, using whitening subkey number m.
- * OUTUNPACK unpacks word number n from the variable named by x, using
- * whitening subkey number m. */
-
-#define INPACK(n, x, m) \
- x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
- ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
-
-#define OUTUNPACK(n, x, m) \
- x ^= ctx->w[m]; \
- out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
- out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
-
-/* Encrypt one block. in and out may be the same. */
-
-int twofish_encrypt (TWOFISH_context *ctx,
- const u8 *in, u8 *out)
-{
- /* The four 32-bit chunks of the text. */
- u32 a, b, c, d;
-
- /* Temporaries used by the round function. */
- u32 x, y;
-
- /* Input whitening and packing. */
- INPACK (0, a, 0);
- INPACK (1, b, 1);
- INPACK (2, c, 2);
- INPACK (3, d, 3);
-
- /* Encryption Feistel cycles. */
- ENCCYCLE (0);
- ENCCYCLE (1);
- ENCCYCLE (2);
- ENCCYCLE (3);
- ENCCYCLE (4);
- ENCCYCLE (5);
- ENCCYCLE (6);
- ENCCYCLE (7);
-
- /* Output whitening and unpacking. */
- OUTUNPACK (0, c, 4);
- OUTUNPACK (1, d, 5);
- OUTUNPACK (2, a, 6);
- OUTUNPACK (3, b, 7);
-
- return 0;
-}
-
-/* Decrypt one block. in and out may be the same. */
-
-int twofish_decrypt (TWOFISH_context *ctx,
- const u8 *in, u8 *out)
-{
- /* The four 32-bit chunks of the text. */
- u32 a, b, c, d;
-
- /* Temporaries used by the round function. */
- u32 x, y;
-
- /* Input whitening and packing. */
- INPACK (0, c, 4);
- INPACK (1, d, 5);
- INPACK (2, a, 6);
- INPACK (3, b, 7);
-
- /* Encryption Feistel cycles. */
- DECCYCLE (7);
- DECCYCLE (6);
- DECCYCLE (5);
- DECCYCLE (4);
- DECCYCLE (3);
- DECCYCLE (2);
- DECCYCLE (1);
- DECCYCLE (0);
-
- /* Output whitening and unpacking. */
- OUTUNPACK (0, a, 0);
- OUTUNPACK (1, b, 1);
- OUTUNPACK (2, c, 2);
- OUTUNPACK (3, d, 3);
-
- return 0;
-}
-
-/* eof */
diff --git a/src/libcrypto/libtwofish/twofish.h b/src/libcrypto/libtwofish/twofish.h
deleted file mode 100644
index 9b289f265..000000000
--- a/src/libcrypto/libtwofish/twofish.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef TWOFISH_H
-#define TWOFISH_H
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-/* Structure for an expanded Twofish key. s contains the key-dependent
- * S-boxes composed with the MDS matrix; w contains the eight "whitening"
- * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
- * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
-typedef struct {
- u_int32_t s[4][256], w[8], k[32];
-} TWOFISH_context;
-
-typedef TWOFISH_context twofish_context;
-int twofish_set_key(twofish_context *tf_ctx, const u_int8_t * in_key, int key_len);
-int twofish_encrypt(twofish_context *tf_ctx, const u_int8_t * in, u_int8_t * out);
-int twofish_decrypt(twofish_context * tf_ctx, const u_int8_t * in, u_int8_t * out);
-#endif /* TWOFISH_H */
diff --git a/src/libcrypto/libtwofish/twofish_cbc.c b/src/libcrypto/libtwofish/twofish_cbc.c
deleted file mode 100644
index 6e5cf9025..000000000
--- a/src/libcrypto/libtwofish/twofish_cbc.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-#include "twofish_cbc.h"
-#include "cbc_generic.h"
-CBC_IMPL_BLK16(twofish_cbc_encrypt, twofish_context, u_int8_t *, twofish_encrypt, twofish_decrypt);
diff --git a/src/libcrypto/libtwofish/twofish_cbc.h b/src/libcrypto/libtwofish/twofish_cbc.h
deleted file mode 100644
index 9fdea3526..000000000
--- a/src/libcrypto/libtwofish/twofish_cbc.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* Glue header */
-#include "twofish.h"
-int twofish_cbc_encrypt(twofish_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t* iv, int encrypt);
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index f56322500..98f5ddd88 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -85,6 +85,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -107,6 +108,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -118,6 +122,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -131,6 +136,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -191,6 +198,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -202,6 +210,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -223,8 +232,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -320,7 +329,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libfast/context.h b/src/libfast/context.h
index 3f21ea6f2..48b3c5e23 100644
--- a/src/libfast/context.h
+++ b/src/libfast/context.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: context.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libfast/controller.h b/src/libfast/controller.h
index 9bfb04bab..55ba6f58a 100644
--- a/src/libfast/controller.h
+++ b/src/libfast/controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libfast/dispatcher.c b/src/libfast/dispatcher.c
index e87fd246f..35ae55814 100644
--- a/src/libfast/dispatcher.c
+++ b/src/libfast/dispatcher.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: dispatcher.c 3672 2008-03-27 10:24:37Z martin $
*/
#include "dispatcher.h"
diff --git a/src/libfast/dispatcher.h b/src/libfast/dispatcher.h
index bcd1712ce..5b4e3f947 100644
--- a/src/libfast/dispatcher.h
+++ b/src/libfast/dispatcher.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: dispatcher.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libfast/filter.h b/src/libfast/filter.h
index 614a2ef58..d2602db9d 100644
--- a/src/libfast/filter.h
+++ b/src/libfast/filter.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/*
diff --git a/src/libfast/request.c b/src/libfast/request.c
index ec022d41e..96dfab8e7 100644
--- a/src/libfast/request.c
+++ b/src/libfast/request.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: request.c 3531 2008-03-06 09:50:56Z martin $
*/
#define _GNU_SOURCE
diff --git a/src/libfast/request.h b/src/libfast/request.h
index 25fa5fc60..b9ea88830 100644
--- a/src/libfast/request.h
+++ b/src/libfast/request.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: request.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libfast/session.c b/src/libfast/session.c
index cb2e736b8..455c8d5e1 100644
--- a/src/libfast/session.c
+++ b/src/libfast/session.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: session.c 4060 2008-06-11 14:11:01Z martin $
*/
#define _GNU_SOURCE
diff --git a/src/libfast/session.h b/src/libfast/session.h
index a782a8fe4..524e60f46 100644
--- a/src/libfast/session.h
+++ b/src/libfast/session.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: session.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libfreeswan/Makefile.am b/src/libfreeswan/Makefile.am
index d916fca17..44dd31577 100644
--- a/src/libfreeswan/Makefile.am
+++ b/src/libfreeswan/Makefile.am
@@ -1,19 +1,19 @@
noinst_LIBRARIES = libfreeswan.a
libfreeswan_a_SOURCES = addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
atosa.c atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
- goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipcomp.h \
- ipsec_ah.h ipsec_alg.h ipsec_encap.h ipsec_eroute.h ipsec_errs.h \
- ipsec_esp.h ipsec_ipe4.h ipsec_kversion.h ipsec_life.h ipsec_md5h.h \
- ipsec_param.h ipsec_policy.h ipsec_proto.h ipsec_radij.h ipsec_rcv.h \
- ipsec_sa.h ipsec_sha1.h ipsec_stats.h ipsec_tunnel.h ipsec_xform.h \
- ipsec_xmit.h keyblobtoid.c optionsfrom.c pfkey_v2_build.c pfkey_v2_debug.c \
- pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c prng.c radij.h rangetoa.c \
+ goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
+ keyblobtoid.c pfkey_v2_build.c pfkey_v2_debug.c \
+ pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c prng.c rangetoa.c \
pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c satoa.c \
satot.c subnetof.c subnettoa.c subnettot.c \
subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
- ultoa.c ultot.c version.c
-INCLUDES = -I$(top_srcdir)/src/pluto
+ ultoa.c ultot.c
+
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/pluto
+
dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atosa.3 atoul.3 goodmask.3 initaddr.3 initsubnet.3 \
- keyblobtoid.3 optionsfrom.3 portof.3 prng.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
- ttoaddr.3 ttodata.3 ttosa.3 ttoul.3 version.3
+ keyblobtoid.3 portof.3 prng.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
+ ttoaddr.3 ttodata.3 ttosa.3 ttoul.3
diff --git a/src/libfreeswan/Makefile.in b/src/libfreeswan/Makefile.in
index c973358ed..37c32b9fa 100644
--- a/src/libfreeswan/Makefile.in
+++ b/src/libfreeswan/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -51,15 +51,15 @@ am_libfreeswan_a_OBJECTS = addrtoa.$(OBJEXT) addrtot.$(OBJEXT) \
atoul.$(OBJEXT) copyright.$(OBJEXT) datatot.$(OBJEXT) \
goodmask.$(OBJEXT) initaddr.$(OBJEXT) initsaid.$(OBJEXT) \
initsubnet.$(OBJEXT) keyblobtoid.$(OBJEXT) \
- optionsfrom.$(OBJEXT) pfkey_v2_build.$(OBJEXT) \
- pfkey_v2_debug.$(OBJEXT) pfkey_v2_ext_bits.$(OBJEXT) \
- pfkey_v2_parse.$(OBJEXT) portof.$(OBJEXT) prng.$(OBJEXT) \
- rangetoa.$(OBJEXT) rangetosubnet.$(OBJEXT) sameaddr.$(OBJEXT) \
- satoa.$(OBJEXT) satot.$(OBJEXT) subnetof.$(OBJEXT) \
- subnettoa.$(OBJEXT) subnettot.$(OBJEXT) subnettypeof.$(OBJEXT) \
- ttoaddr.$(OBJEXT) ttodata.$(OBJEXT) ttoprotoport.$(OBJEXT) \
- ttosa.$(OBJEXT) ttosubnet.$(OBJEXT) ttoul.$(OBJEXT) \
- ultoa.$(OBJEXT) ultot.$(OBJEXT) version.$(OBJEXT)
+ pfkey_v2_build.$(OBJEXT) pfkey_v2_debug.$(OBJEXT) \
+ pfkey_v2_ext_bits.$(OBJEXT) pfkey_v2_parse.$(OBJEXT) \
+ portof.$(OBJEXT) prng.$(OBJEXT) rangetoa.$(OBJEXT) \
+ rangetosubnet.$(OBJEXT) sameaddr.$(OBJEXT) satoa.$(OBJEXT) \
+ satot.$(OBJEXT) subnetof.$(OBJEXT) subnettoa.$(OBJEXT) \
+ subnettot.$(OBJEXT) subnettypeof.$(OBJEXT) ttoaddr.$(OBJEXT) \
+ ttodata.$(OBJEXT) ttoprotoport.$(OBJEXT) ttosa.$(OBJEXT) \
+ ttosubnet.$(OBJEXT) ttoul.$(OBJEXT) ultoa.$(OBJEXT) \
+ ultot.$(OBJEXT)
libfreeswan_a_OBJECTS = $(am_libfreeswan_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -97,6 +97,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -119,6 +120,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -130,6 +134,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -143,6 +148,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -203,6 +210,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -214,6 +222,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,22 +230,21 @@ xml_LIBS = @xml_LIBS@
noinst_LIBRARIES = libfreeswan.a
libfreeswan_a_SOURCES = addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
atosa.c atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
- goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipcomp.h \
- ipsec_ah.h ipsec_alg.h ipsec_encap.h ipsec_eroute.h ipsec_errs.h \
- ipsec_esp.h ipsec_ipe4.h ipsec_kversion.h ipsec_life.h ipsec_md5h.h \
- ipsec_param.h ipsec_policy.h ipsec_proto.h ipsec_radij.h ipsec_rcv.h \
- ipsec_sa.h ipsec_sha1.h ipsec_stats.h ipsec_tunnel.h ipsec_xform.h \
- ipsec_xmit.h keyblobtoid.c optionsfrom.c pfkey_v2_build.c pfkey_v2_debug.c \
- pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c prng.c radij.h rangetoa.c \
+ goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
+ keyblobtoid.c pfkey_v2_build.c pfkey_v2_debug.c \
+ pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c prng.c rangetoa.c \
pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c satoa.c \
satot.c subnetof.c subnettoa.c subnettot.c \
subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
- ultoa.c ultot.c version.c
+ ultoa.c ultot.c
+
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/pluto
-INCLUDES = -I$(top_srcdir)/src/pluto
dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atosa.3 atoul.3 goodmask.3 initaddr.3 initsubnet.3 \
- keyblobtoid.3 optionsfrom.3 portof.3 prng.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
- ttoaddr.3 ttodata.3 ttosa.3 ttoul.3 version.3
+ keyblobtoid.3 portof.3 prng.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
+ ttoaddr.3 ttodata.3 ttosa.3 ttoul.3
all: all-am
@@ -246,8 +254,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -301,7 +309,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initsaid.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initsubnet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyblobtoid.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey_v2_build.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey_v2_debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pfkey_v2_ext_bits.Po@am__quote@
@@ -325,7 +332,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttoul.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ultoa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ultot.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -364,8 +370,8 @@ install-man3: $(man3_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
@@ -404,7 +410,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libfreeswan/addrtoa.c b/src/libfreeswan/addrtoa.c
index bb5d239ab..7acfa5ded 100644
--- a/src/libfreeswan/addrtoa.c
+++ b/src/libfreeswan/addrtoa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: addrtoa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/addrtot.c b/src/libfreeswan/addrtot.c
index 700553b40..6efdfccca 100644
--- a/src/libfreeswan/addrtot.c
+++ b/src/libfreeswan/addrtot.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: addrtot.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/addrtypeof.c b/src/libfreeswan/addrtypeof.c
index 8d68be12b..f402eca70 100644
--- a/src/libfreeswan/addrtypeof.c
+++ b/src/libfreeswan/addrtypeof.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: addrtypeof.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/anyaddr.3 b/src/libfreeswan/anyaddr.3
index 556627f7d..58789cf6c 100644
--- a/src/libfreeswan/anyaddr.3
+++ b/src/libfreeswan/anyaddr.3
@@ -1,5 +1,4 @@
.TH IPSEC_ANYADDR 3 "8 Sept 2000"
-.\" RCSID $Id: anyaddr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec anyaddr \- get "any" address
.br
diff --git a/src/libfreeswan/anyaddr.c b/src/libfreeswan/anyaddr.c
index 12100f07e..2e9fa2787 100644
--- a/src/libfreeswan/anyaddr.c
+++ b/src/libfreeswan/anyaddr.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: anyaddr.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/atoaddr.3 b/src/libfreeswan/atoaddr.3
index 617609325..fce8884e4 100644
--- a/src/libfreeswan/atoaddr.3
+++ b/src/libfreeswan/atoaddr.3
@@ -1,5 +1,4 @@
.TH IPSEC_ATOADDR 3 "11 June 2001"
-.\" RCSID $Id: atoaddr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec atoaddr, addrtoa \- convert Internet addresses to and from ASCII
.br
diff --git a/src/libfreeswan/atoaddr.c b/src/libfreeswan/atoaddr.c
index 1af90cd63..dd73be7f3 100644
--- a/src/libfreeswan/atoaddr.c
+++ b/src/libfreeswan/atoaddr.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: atoaddr.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/atoasr.3 b/src/libfreeswan/atoasr.3
index 8be2fa274..0b9a5fea3 100644
--- a/src/libfreeswan/atoasr.3
+++ b/src/libfreeswan/atoasr.3
@@ -1,5 +1,4 @@
.TH IPSEC_ATOASR 3 "11 June 2001"
-.\" RCSID $Id: atoasr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec atoasr \- convert ASCII to Internet address, subnet, or range
.br
diff --git a/src/libfreeswan/atoasr.c b/src/libfreeswan/atoasr.c
index 03b7c5b7f..ef8412fe8 100644
--- a/src/libfreeswan/atoasr.c
+++ b/src/libfreeswan/atoasr.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: atoasr.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/atosa.3 b/src/libfreeswan/atosa.3
index cd2205bfe..f57fcf1e9 100644
--- a/src/libfreeswan/atosa.3
+++ b/src/libfreeswan/atosa.3
@@ -1,5 +1,4 @@
.TH IPSEC_ATOSA 3 "11 June 2001"
-.\" RCSID $Id: atosa.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec atosa, satoa \- convert IPsec Security Association IDs to and from ASCII
.SH SYNOPSIS
diff --git a/src/libfreeswan/atosa.c b/src/libfreeswan/atosa.c
index f49931716..aeb5742e1 100644
--- a/src/libfreeswan/atosa.c
+++ b/src/libfreeswan/atosa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: atosa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/atosubnet.c b/src/libfreeswan/atosubnet.c
index 3411e9e05..a123a39da 100644
--- a/src/libfreeswan/atosubnet.c
+++ b/src/libfreeswan/atosubnet.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: atosubnet.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/atoul.3 b/src/libfreeswan/atoul.3
index 2d710cbc9..6737b6b54 100644
--- a/src/libfreeswan/atoul.3
+++ b/src/libfreeswan/atoul.3
@@ -1,5 +1,4 @@
.TH IPSEC_ATOUL 3 "11 June 2001"
-.\" RCSID $Id: atoul.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec atoul, ultoa \- convert unsigned-long numbers to and from ASCII
.SH SYNOPSIS
diff --git a/src/libfreeswan/atoul.c b/src/libfreeswan/atoul.c
index a3bf07a60..7e51de8fe 100644
--- a/src/libfreeswan/atoul.c
+++ b/src/libfreeswan/atoul.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: atoul.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/copyright.c b/src/libfreeswan/copyright.c
index 3c382160a..65585b62e 100644
--- a/src/libfreeswan/copyright.c
+++ b/src/libfreeswan/copyright.c
@@ -11,14 +11,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: copyright.c 4181 2008-07-16 12:28:29Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
static const char *co[] = {
- "Copyright (C) 1999-2008 Henry Spencer, Richard Guy Briggs,",
+ "Copyright (C) 1999-2009 Henry Spencer, Richard Guy Briggs,",
" D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,",
" Michael Richardson, Angelos D. Keromytis, John Ioannidis,",
"",
diff --git a/src/libfreeswan/datatot.c b/src/libfreeswan/datatot.c
index cefe09ef0..b18d4b050 100644
--- a/src/libfreeswan/datatot.c
+++ b/src/libfreeswan/datatot.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: datatot.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/freeswan.h b/src/libfreeswan/freeswan.h
index cbb8e2db4..cb14cd678 100644
--- a/src/libfreeswan/freeswan.h
+++ b/src/libfreeswan/freeswan.h
@@ -13,24 +13,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: freeswan.h 4632 2008-11-11 18:37:19Z martin $
*/
#define _FREESWAN_H /* seen it, no need to see it again */
-
-
-/*
- * We've just got to have some datatypes defined... And annoyingly, just
- * where we get them depends on whether we're in userland or not.
- */
-#ifdef __KERNEL__
-
-# include <linux/types.h>
-# include <linux/in.h>
-
-#else /* __KERNEL__ */
-
+# include <sys/types.h>
# include <stdio.h>
# include <netinet/in.h>
@@ -41,25 +27,13 @@
# define DEBUG_NO_STATIC static
-#endif /* __KERNEL__ */
-
#include <ipsec_param.h>
-
+#include <utils.h>
/*
- * Grab the kernel version to see if we have NET_21, and therefore
- * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
- * we aren't really testing if the kernel has IPv6, but rather if the
- * the include files do.
+ * We assume header files have IPv6 (i.e. kernel version >= 2.1.0)
*/
-#include <linux/version.h>
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
#define NET_21
-#endif
#ifndef IPPROTO_COMP
# define IPPROTO_COMP 108
@@ -84,28 +58,6 @@
* use their definitions directly, they are subject to change!
*/
-/* first, some quick fakes in case we're on an old system with no IPv6 */
-#ifndef s6_addr16
-struct in6_addr {
- union
- {
- __u8 u6_addr8[16];
- __u16 u6_addr16[8];
- __u32 u6_addr32[4];
- } in6_u;
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-};
-struct sockaddr_in6 {
- unsigned short int sin6_family; /* AF_INET6 */
- __u16 sin6_port; /* Transport layer port # */
- __u32 sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- __u32 sin6_scope_id; /* scope id (new in RFC2553) */
-};
-#endif /* !s6_addr16 */
-
/* then the main types */
typedef struct {
union {
@@ -119,11 +71,7 @@ typedef struct {
} ip_subnet;
/* and the SA ID stuff */
-#ifdef __KERNEL__
-typedef __u32 ipsec_spi_t;
-#else
typedef u_int32_t ipsec_spi_t;
-#endif
typedef struct { /* to identify an SA, we need: */
ip_address dst; /* A. destination host */
ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
@@ -147,7 +95,6 @@ struct sa_id { /* old v4-only version */
};
/* misc */
-typedef const char *err_t; /* error message, or NULL for success */
struct prng { /* pseudo-random-number-generator guts */
unsigned char sbox[256];
int i, j;
@@ -160,6 +107,8 @@ struct prng { /* pseudo-random-number-generator guts */
*/
typedef uint32_t IPsecSAref_t;
+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
+
#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
@@ -220,7 +169,7 @@ size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
size_t mlen, char *dst, size_t dstlen);
#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
- int *has_port_wildcard);
+ bool *has_port_wildcard);
/* initializations */
void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
@@ -269,8 +218,6 @@ unsigned long prng_count(struct prng *prng);
void prng_final(struct prng *prng);
/* odds and ends */
-const char *ipsec_version_code(void);
-const char *ipsec_version_string(void);
const char **ipsec_copyright_notice(void);
const char *dns_string_rr(int rr, char *buf, int bufsize);
@@ -436,19 +383,6 @@ bitstomask(
int n
);
-
-
-/*
- * general utilities
- */
-
-#ifndef __KERNEL__
-/* option pickup from files (userland only because of use of FILE) */
-const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
- int optind, FILE *errorreport);
-#define ignore_result(call) { if (call); }
-#endif
-
/*
* Debugging levels for pfkey_lib_debug
*/
diff --git a/src/libfreeswan/goodmask.3 b/src/libfreeswan/goodmask.3
index eeff2f25d..b76d431ca 100644
--- a/src/libfreeswan/goodmask.3
+++ b/src/libfreeswan/goodmask.3
@@ -1,5 +1,4 @@
.TH IPSEC_GOODMASK 3 "11 June 2001"
-.\" RCSID $Id: goodmask.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec goodmask \- is this Internet subnet mask a valid one?
.br
diff --git a/src/libfreeswan/goodmask.c b/src/libfreeswan/goodmask.c
index 318a2879f..a2d51de0c 100644
--- a/src/libfreeswan/goodmask.c
+++ b/src/libfreeswan/goodmask.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: goodmask.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/initaddr.3 b/src/libfreeswan/initaddr.3
index bcbd3f88b..071e507aa 100644
--- a/src/libfreeswan/initaddr.3
+++ b/src/libfreeswan/initaddr.3
@@ -1,5 +1,4 @@
.TH IPSEC_INITADDR 3 "11 Sept 2000"
-.\" RCSID $Id: initaddr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec initaddr \- initialize an ip_address
.br
diff --git a/src/libfreeswan/initaddr.c b/src/libfreeswan/initaddr.c
index 99870ded2..c30efb812 100644
--- a/src/libfreeswan/initaddr.c
+++ b/src/libfreeswan/initaddr.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: initaddr.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/initsaid.c b/src/libfreeswan/initsaid.c
index 43156e96e..fb8187422 100644
--- a/src/libfreeswan/initsaid.c
+++ b/src/libfreeswan/initsaid.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: initsaid.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/initsubnet.3 b/src/libfreeswan/initsubnet.3
index aaf2a64d5..3545fd426 100644
--- a/src/libfreeswan/initsubnet.3
+++ b/src/libfreeswan/initsubnet.3
@@ -1,5 +1,4 @@
.TH IPSEC_INITSUBNET 3 "12 March 2002"
-.\" RCSID $Id: initsubnet.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec initsubnet \- initialize an ip_subnet
.br
diff --git a/src/libfreeswan/initsubnet.c b/src/libfreeswan/initsubnet.c
index f2d8b4dc8..0e19098c5 100644
--- a/src/libfreeswan/initsubnet.c
+++ b/src/libfreeswan/initsubnet.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: initsubnet.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/internal.h b/src/libfreeswan/internal.h
index 921e47835..fa24f7d2d 100644
--- a/src/libfreeswan/internal.h
+++ b/src/libfreeswan/internal.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: internal.h 3265 2007-10-08 19:52:55Z andreas $
*/
#ifndef ABITS
@@ -35,47 +33,14 @@
#define PASSTHROUGHDST 0
#endif
-/*
- * Headers, greatly complicated by stupid and unnecessary inconsistencies
- * between the user environment and the kernel environment. These are done
- * here so that this mess need exist in only one place.
- *
- * It may seem like a -I or two could avoid most of this, but on closer
- * inspection it is not quite that easy.
- */
-
-/* things that need to come from one place or the other, depending */
-#ifdef __KERNEL__
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#define assert(foo) /* nothing */
-#else
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
-#endif
-
-/* things that exist only in userland */
-#ifndef __KERNEL__
-
-/* You'd think this would be okay in the kernel too -- it's just a */
-/* bunch of constants -- but no, in RH5.1 it screws up other things. */
-/* (Credit: Mike Warfield tracked this problem down. Thanks Mike!) */
-/* Fortunately, we don't need it in the kernel subset of the library. */
#include <limits.h>
-
-/* header files for things that should never be called in kernel */
#include <netdb.h>
-
-/* memory allocation, currently user-only, macro-ized just in case */
#include <stdlib.h>
#define MALLOC(n) malloc(n)
#define FREE(p) free(p)
-#endif /* __KERNEL__ */
-
diff --git a/src/libfreeswan/ipcomp.h b/src/libfreeswan/ipcomp.h
deleted file mode 100644
index 57f8cc7cc..000000000
--- a/src/libfreeswan/ipcomp.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * IPCOMP zlib interface code.
- * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
- * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
-
- RCSID $Id: ipcomp.h 3265 2007-10-08 19:52:55Z andreas $
-
- */
-
-/* SSS */
-
-#ifndef _IPCOMP_H
-#define _IPCOMP_H
-
-/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
-#ifndef IPCOMP_PREFIX
-#define IPCOMP_PREFIX
-#endif /* IPCOMP_PREFIX */
-
-#ifndef IPPROTO_COMP
-#define IPPROTO_COMP 108
-#endif /* IPPROTO_COMP */
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int sysctl_ipsec_debug_ipcomp;
-#endif /* CONFIG_IPSEC_DEBUG */
-
-struct ipcomphdr { /* IPCOMP header */
- __u8 ipcomp_nh; /* Next header (protocol) */
- __u8 ipcomp_flags; /* Reserved, must be 0 */
- __u16 ipcomp_cpi; /* Compression Parameter Index */
-};
-
-extern struct inet_protocol comp_protocol;
-extern int sysctl_ipsec_debug_ipcomp;
-
-#define IPCOMP_UNCOMPRESSABLE 0x000000001
-#define IPCOMP_COMPRESSIONERROR 0x000000002
-#define IPCOMP_PARMERROR 0x000000004
-#define IPCOMP_DECOMPRESSIONERROR 0x000000008
-
-#define IPCOMP_ADAPT_INITIAL_TRIES 8
-#define IPCOMP_ADAPT_INITIAL_SKIP 4
-#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
-#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
-
-/* Function prototypes */
-struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-
-#endif /* _IPCOMP_H */
diff --git a/src/libfreeswan/ipsec_ah.h b/src/libfreeswan/ipsec_ah.h
deleted file mode 100644
index aa34ce798..000000000
--- a/src/libfreeswan/ipsec_ah.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Authentication Header declarations
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_ah.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#include "ipsec_md5h.h"
-#include "ipsec_sha1.h"
-
-#ifndef IPPROTO_AH
-#define IPPROTO_AH 51
-#endif /* IPPROTO_AH */
-
-#define AH_FLENGTH 12 /* size of fixed part */
-#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
-#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
-
-#define AHMD596_KLEN 16 /* MD5 128 bits key */
-#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
-
-#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
-#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
-
-#define AHMD596_BLKLEN 64 /* MD5 block length */
-#define AHSHA196_BLKLEN 64 /* SHA1 block length */
-#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
-#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
-#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
-
-#define AH_BLKLEN_MAX 128 /* keep up to date! */
-
-#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
-#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
-#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
-
-#define DB_AH_PKTRX 0x0001
-#define DB_AH_PKTRX2 0x0002
-#define DB_AH_DMP 0x0004
-#define DB_AH_IPSA 0x0010
-#define DB_AH_XF 0x0020
-#define DB_AH_INAU 0x0040
-#define DB_AH_REPLAY 0x0100
-
-#ifdef __KERNEL__
-
-/* General HMAC algorithm is described in RFC 2104 */
-
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5C
-
-struct md5_ctx {
- MD5_CTX ictx; /* context after H(K XOR ipad) */
- MD5_CTX octx; /* context after H(K XOR opad) */
-};
-
-struct sha1_ctx {
- SHA1_CTX ictx; /* context after H(K XOR ipad) */
- SHA1_CTX octx; /* context after H(K XOR opad) */
-};
-
-struct auth_alg {
- void (*init)(void *ctx);
- void (*update)(void *ctx, unsigned char *bytes, __u32 len);
- void (*final)(unsigned char *hash, void *ctx);
- int hashlen;
-};
-
-extern struct inet_protocol ah_protocol;
-
-struct options;
-
-extern int
-ah_rcv(struct sk_buff *skb,
- struct device *dev,
- struct options *opt,
- __u32 daddr,
- unsigned short len,
- __u32 saddr,
- int redo,
- struct inet_protocol *protocol);
-
-struct ahhdr /* Generic AH header */
-{
- __u8 ah_nh; /* Next header (protocol) */
- __u8 ah_hl; /* AH length, in 32-bit words */
- __u16 ah_rv; /* reserved, must be 0 */
- __u32 ah_spi; /* Security Parameters Index */
- __u32 ah_rpl; /* Replay prevention */
- __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
-};
-#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
- * and the ah_hl, says how many bytes after that
- * to cover. */
-
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int debug_ah;
-#endif /* CONFIG_IPSEC_DEBUG */
-#endif /* __KERNEL__ */
diff --git a/src/libfreeswan/ipsec_alg.h b/src/libfreeswan/ipsec_alg.h
deleted file mode 100644
index 6b85be645..000000000
--- a/src/libfreeswan/ipsec_alg.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Modular extensions service and registration functions interface
- *
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
- *
- * $Id: ipsec_alg.h 3265 2007-10-08 19:52:55Z andreas $
- *
- */
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- */
-#ifndef IPSEC_ALG_H
-#define IPSEC_ALG_H
-
-/*
- * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
- * *BUT* its a compiler variable.
- */
-#if (__GNUC__ >= 3)
-#ifndef __FUNCTION__
-#define __FUNCTION__ __func__
-#endif
-#endif
-
-/* Version 0.8.1-0 */
-#define IPSEC_ALG_VERSION 0x00080100
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <asm/atomic.h>
-/*
- * The following structs are used via pointers in ipsec_alg object to
- * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
- * module development
- */
-struct ipsec_sa;
-struct esp;
-
-/**************************************
- *
- * Main registration object
- *
- *************************************/
-#define IPSEC_ALG_VERSION_QUAD(v) \
- (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
-/*
- * Main ipsec_alg objects: "OOPrograming wannabe"
- * Hierachy (carefully handled with _minimal_ cast'ing):
- *
- * ipsec_alg+
- * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
- * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
- */
-
-/***************************************************************
- *
- * INTERFACE object: struct ipsec_alg
- *
- ***************************************************************/
-
-/*
- * common part for every struct ipsec_alg_*
- * (sortof poor's man OOP)
- */
-#define IPSEC_ALG_STRUCT_COMMON \
- unsigned ixt_version; /* only allow this version (or 'near')*/ \
- struct list_head ixt_list; /* dlinked list */ \
- struct module *ixt_module; /* THIS_MODULE */ \
- unsigned ixt_state; /* state flags */ \
- atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
- char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
- void *ixt_data; /* private for algo implementation */ \
- uint8_t ixt_blocksize; /* blocksize in bytes */ \
- \
- /* THIS IS A COPY of struct supported (lib/pfkey.h) \
- * please keep in sync until we migrate 'supported' stuff \
- * to ipsec_alg \
- */ \
- uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \
- uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \
- uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \
- uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \
- uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */
-
-#define ixt_support ixt_alg_type
-
-#define IPSEC_ALG_ST_SUPP 0x01
-#define IPSEC_ALG_ST_REGISTERED 0x02
-#define IPSEC_ALG_ST_EXCL 0x04
-struct ipsec_alg {
- IPSEC_ALG_STRUCT_COMMON
-};
-/*
- * Note the const in cbc_encrypt IV arg:
- * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
- */
-struct ipsec_alg_enc {
- IPSEC_ALG_STRUCT_COMMON
- unsigned ixt_e_keylen; /* raw key length in bytes */
- unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
- int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
- __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
- void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
- int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
-};
-struct ipsec_alg_auth {
- IPSEC_ALG_STRUCT_COMMON
- unsigned ixt_a_keylen; /* raw key length in bytes */
- unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
- unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
- int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
- int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
-};
-/*
- * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
- * to avoid header coupling for true constants
- * about headers ... "cp is your friend" --Linus
- */
-#define IPSEC_ALG_TYPE_AUTH 14
-#define IPSEC_ALG_TYPE_ENCRYPT 15
-
-/***************************************************************
- *
- * INTERFACE for module loading,testing, and unloading
- *
- ***************************************************************/
-/* - registration calls */
-int register_ipsec_alg(struct ipsec_alg *);
-int unregister_ipsec_alg(struct ipsec_alg *);
-/* - optional (simple test) for algos */
-int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
-/* inline wrappers (usefull for type validation */
-static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
- return register_ipsec_alg((struct ipsec_alg*)ixt);
-}
-static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
- return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-}
-static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
- return register_ipsec_alg((struct ipsec_alg*)ixt);
-}
-static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
- return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-}
-
-/*****************************************************************
- *
- * INTERFACE for ENC services: key creation, encrypt function
- *
- *****************************************************************/
-
-#define IPSEC_ALG_ENCRYPT 1
-#define IPSEC_ALG_DECRYPT 0
-
-/* encryption key context creation function */
-int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
-/*
- * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
- * 0 or ERR<0
- */
-int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
-
-/***************************************************************
- *
- * INTERFACE for AUTH services: key creation, hash functions
- *
- ***************************************************************/
-int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
-int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
-#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
-
-/* only called from ipsec_init.c */
-int ipsec_alg_init(void);
-
-/* algo module glue for static algos */
-void ipsec_alg_static_init(void);
-typedef int (*ipsec_alg_init_func_t) (void);
-
-/**********************************************
- *
- * INTERFACE for ipsec_sa init and wipe
- *
- **********************************************/
-
-/* returns true if ipsec_sa has ipsec_alg obj attached */
-/*
- * Initializes ipsec_sa's ipsec_alg object, using already loaded
- * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
- */
-int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
-/*
- * Destroys ipsec_sa's ipsec_alg object
- * unlinking ipsec_alg objects
- */
-int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
-
-/**********************************************
- *
- * 2.2 backport for some 2.4 useful module stuff
- *
- **********************************************/
-#ifdef MODULE
-#ifndef THIS_MODULE
-#define THIS_MODULE (&__this_module)
-#endif
-#ifndef module_init
-typedef int (*__init_module_func_t)(void);
-typedef void (*__cleanup_module_func_t)(void);
-
-#define module_init(x) \
- int init_module(void) __attribute__((alias(#x))); \
- static inline __init_module_func_t __init_module_inline(void) \
- { return x; }
-#define module_exit(x) \
- void cleanup_module(void) __attribute__((alias(#x))); \
- static inline __cleanup_module_func_t __cleanup_module_inline(void) \
- { return x; }
-#endif
-
-#define IPSEC_ALG_MODULE_INIT( func_name ) \
- static int func_name(void); \
- module_init(func_name); \
- static int __init func_name(void)
-#define IPSEC_ALG_MODULE_EXIT( func_name ) \
- static void func_name(void); \
- module_exit(func_name); \
- static void __exit func_name(void)
-#else /* not MODULE */
-#ifndef THIS_MODULE
-#define THIS_MODULE NULL
-#endif
-/*
- * I only want module_init() magic
- * when algo.c file *is THE MODULE*, in all other
- * cases, initialization is called explicitely from ipsec_alg_init()
- */
-#define IPSEC_ALG_MODULE_INIT( func_name ) \
- extern int func_name(void); \
- int func_name(void)
-#define IPSEC_ALG_MODULE_EXIT( func_name ) \
- extern void func_name(void); \
- void func_name(void)
-#endif
-
-#endif /* IPSEC_ALG_H */
diff --git a/src/libfreeswan/ipsec_encap.h b/src/libfreeswan/ipsec_encap.h
deleted file mode 100644
index 4f8d2e9a0..000000000
--- a/src/libfreeswan/ipsec_encap.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * declarations relevant to encapsulation-like operations
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_encap.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#ifndef _IPSEC_ENCAP_H_
-
-#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
- /* (2 * sizeof(struct in_addr)) */
- /* sizeof(struct sockaddr_encap)
- - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
-
-struct sockaddr_encap
-{
- __u8 sen_len; /* length */
- __u8 sen_family; /* AF_ENCAP */
- __u16 sen_type; /* see SENT_* */
- union
- {
- struct /* SENT_IP4 */
- {
- struct in_addr Src;
- struct in_addr Dst;
- __u8 Proto;
- __u16 Sport;
- __u16 Dport;
- } Sip4;
- } Sen;
-};
-
-#define sen_ip_src Sen.Sip4.Src
-#define sen_ip_dst Sen.Sip4.Dst
-#define sen_proto Sen.Sip4.Proto
-#define sen_sport Sen.Sip4.Sport
-#define sen_dport Sen.Sip4.Dport
-
-#ifndef AF_ENCAP
-#define AF_ENCAP 26
-#endif /* AF_ENCAP */
-
-#define _IPSEC_ENCAP_H_
-#endif /* _IPSEC_ENCAP_H_ */
diff --git a/src/libfreeswan/ipsec_eroute.h b/src/libfreeswan/ipsec_eroute.h
deleted file mode 100644
index 60af0f09b..000000000
--- a/src/libfreeswan/ipsec_eroute.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * @(#) declarations of eroute structures
- *
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
- * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_eroute.h 3265 2007-10-08 19:52:55Z andreas $
- *
- * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
- *
- */
-
-#ifndef _IPSEC_EROUTE_H_
-
-#include "radij.h"
-#include "ipsec_encap.h"
-#include "ipsec_radij.h"
-
-/*
- * The "type" is really part of the address as far as the routing
- * system is concerned. By using only one bit in the type field
- * for each type, we sort-of make sure that different types of
- * encapsulation addresses won't be matched against the wrong type.
- */
-
-/*
- * An entry in the radix tree
- */
-
-struct rjtentry
-{
- struct radij_node rd_nodes[2]; /* tree glue, and other values */
-#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
-#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
- short rd_flags;
- short rd_count;
-};
-
-struct ident
-{
- __u16 type; /* identity type */
- __u64 id; /* identity id */
- __u8 len; /* identity len */
- caddr_t data; /* identity data */
-};
-
-/*
- * An encapsulation route consists of a pointer to a
- * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
- */
-
-struct eroute
-{
- struct rjtentry er_rjt;
- struct sa_id er_said;
- uint32_t er_pid;
- uint32_t er_count;
- uint64_t er_lasttime;
- struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
- struct sockaddr_encap er_emask;
- struct ident er_ident_s;
- struct ident er_ident_d;
- struct sk_buff* er_first;
- struct sk_buff* er_last;
-};
-
-#define er_dst er_said.dst
-#define er_spi er_said.spi
-
-#define _IPSEC_EROUTE_H_
-#endif /* _IPSEC_EROUTE_H_ */
diff --git a/src/libfreeswan/ipsec_errs.h b/src/libfreeswan/ipsec_errs.h
deleted file mode 100644
index da7646870..000000000
--- a/src/libfreeswan/ipsec_errs.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * @(#) definition of ipsec_errs structure
- *
- * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_errs.h 3265 2007-10-08 19:52:55Z andreas $
- *
- */
-
-/*
- * This file describes the errors/statistics that FreeSWAN collects.
- *
- */
-
-struct ipsec_errs {
- __u32 ips_alg_errs; /* number of algorithm errors */
- __u32 ips_auth_errs; /* # of authentication errors */
- __u32 ips_encsize_errs; /* # of encryption size errors*/
- __u32 ips_encpad_errs; /* # of encryption pad errors*/
- __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-};
diff --git a/src/libfreeswan/ipsec_esp.h b/src/libfreeswan/ipsec_esp.h
deleted file mode 100644
index af1b488f2..000000000
--- a/src/libfreeswan/ipsec_esp.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_esp.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#include "freeswan/ipsec_md5h.h"
-#include "freeswan/ipsec_sha1.h"
-
-#include "crypto/des.h"
-
-#ifndef IPPROTO_ESP
-#define IPPROTO_ESP 50
-#endif /* IPPROTO_ESP */
-
-#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
-
-#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
-#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
-#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
-#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
-#define EMT_ESPDES_IV_SZ 8 /* IV size */
-#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
-
-#define ESP_IV_MAXSZ 16 /* This is _critical_ */
-#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
-
-#define DB_ES_PKTRX 0x0001
-#define DB_ES_PKTRX2 0x0002
-#define DB_ES_IPSA 0x0010
-#define DB_ES_XF 0x0020
-#define DB_ES_IPAD 0x0040
-#define DB_ES_INAU 0x0080
-#define DB_ES_OINFO 0x0100
-#define DB_ES_OINFO2 0x0200
-#define DB_ES_OH 0x0400
-#define DB_ES_REPLAY 0x0800
-
-#ifdef __KERNEL__
-struct des_eks {
- des_key_schedule ks;
-};
-
-extern struct inet_protocol esp_protocol;
-
-struct options;
-
-extern int
-esp_rcv(struct sk_buff *skb,
- struct device *dev,
- struct options *opt,
- __u32 daddr,
- unsigned short len,
- __u32 saddr,
- int redo,
- struct inet_protocol *protocol);
-
-/* Only for 64 bits IVs, eg. ESP_3DES :P */
-struct esphdr
-{
- __u32 esp_spi; /* Security Parameters Index */
- __u32 esp_rpl; /* Replay counter */
- __u8 esp_iv[8]; /* iv */
-};
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int debug_esp;
-#endif /* CONFIG_IPSEC_DEBUG */
-#endif /* __KERNEL__ */
diff --git a/src/libfreeswan/ipsec_kversion.h b/src/libfreeswan/ipsec_kversion.h
deleted file mode 100644
index 4a94021a2..000000000
--- a/src/libfreeswan/ipsec_kversion.h
+++ /dev/null
@@ -1,191 +0,0 @@
-#ifndef _FREESWAN_KVERSIONS_H
-/*
- * header file for FreeS/WAN library functions
- * Copyright (C) 1998, 1999, 2000 Henry Spencer.
- * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- *
- * RCSID $Id: ipsec_kversion.h 3265 2007-10-08 19:52:55Z andreas $
- */
-#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */
-
-/*
- * this file contains a series of atomic defines that depend upon
- * kernel version numbers. The kernel versions are arranged
- * in version-order number (which is often not chronological)
- * and each clause enables or disables a feature.
- */
-
-/*
- * First, assorted kernel-version-dependent trickery.
- */
-#include <linux/version.h>
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-#define HEADER_CACHE_BIND_21
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-#define SPINLOCK
-#define PROC_FS_21
-#define NETLINK_SOCK
-#define NET_21
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
-#define net_device_stats enet_statistics
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-#define SPINLOCK_23
-#define NETDEV_23
-# ifndef CONFIG_IP_ALIAS
-# define CONFIG_IP_ALIAS
-# endif
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/netlink.h>
-# ifdef NETLINK_XFRM
-# define NETDEV_25
-# endif
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
-#define PROC_FS_2325
-#undef PROC_FS_21
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
-#define PROC_NO_DUMMY
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
-#define SKB_COPY_EXPAND
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
-#define IP_SELECT_IDENT
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
-#define SKB_RESET_NFCT
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
-#define IP_SELECT_IDENT_NEW
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
-#define IPH_is_SKB_PULLED
-#define SKB_COW_NEW
-#define PROTO_HANDLER_SINGLE_PARM
-#define IP_FRAGMENT_LINEARIZE 1
-#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-# ifdef REDHAT_BOGOSITY
-# define IP_SELECT_IDENT_NEW
-# define IPH_is_SKB_PULLED
-# define SKB_COW_NEW
-# define PROTO_HANDLER_SINGLE_PARM
-# endif /* REDHAT_BOGOSITY */
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
-#define MALLOC_SLAB
-#define LINUX_KERNEL_HAS_SNPRINTF
-#endif
-
-#ifdef NET_21
-# include <linux/in6.h>
-#else
- /* old kernel in.h has some IPv6 stuff, but not quite enough */
-# define s6_addr16 s6_addr
-# define AF_INET6 10
-# define uint8_t __u8
-# define uint16_t __u16
-# define uint32_t __u32
-# define uint64_t __u64
-#endif
-
-#ifdef NET_21
-# define ipsec_kfree_skb(a) kfree_skb(a)
-#else /* NET_21 */
-# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
-#endif /* NET_21 */
-
-#ifdef NETDEV_23
-# define device net_device
-# define ipsec_dev_get dev_get_by_name
-# define __ipsec_dev_get __dev_get_by_name
-# define ipsec_dev_put(x) dev_put(x)
-# define __ipsec_dev_put(x) __dev_put(x)
-# define ipsec_dev_hold(x) dev_hold(x)
-#else /* NETDEV_23 */
-# define ipsec_dev_get dev_get
-# define __ipsec_dev_put(x)
-# define ipsec_dev_put(x)
-# define ipsec_dev_hold(x)
-#endif /* NETDEV_23 */
-
-#ifndef SPINLOCK
-# include <linux/bios32.h>
- /* simulate spin locks and read/write locks */
- typedef struct {
- volatile char lock;
- } spinlock_t;
-
- typedef struct {
- volatile unsigned int lock;
- } rwlock_t;
-
-# define spin_lock_init(x) { (x)->lock = 0;}
-# define rw_lock_init(x) { (x)->lock = 0; }
-
-# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
-# define spin_lock_irq(x) { cli(); spin_lock(x);}
-# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
-
-# define spin_unlock(x) { (x)->lock=0;}
-# define spin_unlock_irq(x) { spin_unlock(x); sti();}
-# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
-
-# define read_lock(x) spin_lock(x)
-# define read_lock_irq(x) spin_lock_irq(x)
-# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-
-# define read_unlock(x) spin_unlock(x)
-# define read_unlock_irq(x) spin_unlock_irq(x)
-# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-
-# define write_lock(x) spin_lock(x)
-# define write_lock_irq(x) spin_lock_irq(x)
-# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-
-# define write_unlock(x) spin_unlock(x)
-# define write_unlock_irq(x) spin_unlock_irq(x)
-# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-#endif /* !SPINLOCK */
-
-#ifndef SPINLOCK_23
-# define spin_lock_bh(x) spin_lock_irq(x)
-# define spin_unlock_bh(x) spin_unlock_irq(x)
-
-# define read_lock_bh(x) read_lock_irq(x)
-# define read_unlock_bh(x) read_unlock_irq(x)
-
-# define write_lock_bh(x) write_lock_irq(x)
-# define write_unlock_bh(x) write_unlock_irq(x)
-#endif /* !SPINLOCK_23 */
-
-#endif /* _FREESWAN_KVERSIONS_H */
diff --git a/src/libfreeswan/ipsec_life.h b/src/libfreeswan/ipsec_life.h
deleted file mode 100644
index 3508e007f..000000000
--- a/src/libfreeswan/ipsec_life.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Definitions relevant to IPSEC lifetimes
- * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_life.h 3265 2007-10-08 19:52:55Z andreas $
- *
- * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
- *
- */
-
-/*
- * This file describes the book keeping fields for the
- * IPsec Security Association Structure. ("ipsec_sa")
- *
- * This structure is never allocated directly by kernel code,
- * (it is always a static/auto or is part of a structure)
- * so it does not have a reference count.
- *
- */
-
-#ifndef _IPSEC_LIFE_H_
-
-/*
- * _count is total count.
- * _hard is hard limit (kill SA after this number)
- * _soft is soft limit (try to renew SA after this number)
- * _last is used in some special cases.
- *
- */
-
-struct ipsec_lifetime64
-{
- __u64 ipl_count;
- __u64 ipl_soft;
- __u64 ipl_hard;
- __u64 ipl_last;
-};
-
-struct ipsec_lifetimes
-{
- /* number of bytes processed */
- struct ipsec_lifetime64 ipl_bytes;
-
- /* number of packets processed */
- struct ipsec_lifetime64 ipl_packets;
-
- /* time since SA was added */
- struct ipsec_lifetime64 ipl_addtime;
-
- /* time since SA was first used */
- struct ipsec_lifetime64 ipl_usetime;
-
- /* from rfc2367:
- * For CURRENT, the number of different connections,
- * endpoints, or flows that the association has been
- * allocated towards. For HARD and SOFT, the number of
- * these the association may be allocated towards
- * before it expires. The concept of a connection,
- * flow, or endpoint is system specific.
- *
- * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
- * They are maintained for PF_KEY compatibility.
- */
- struct ipsec_lifetime64 ipl_allocations;
-};
-
-enum ipsec_life_alive {
- ipsec_life_harddied = -1,
- ipsec_life_softdied = 0,
- ipsec_life_okay = 1
-};
-
-enum ipsec_life_type {
- ipsec_life_timebased = 1,
- ipsec_life_countbased= 0
-};
-
-#define _IPSEC_LIFE_H_
-#endif /* _IPSEC_LIFE_H_ */
diff --git a/src/libfreeswan/ipsec_md5h.h b/src/libfreeswan/ipsec_md5h.h
deleted file mode 100644
index ea98218a6..000000000
--- a/src/libfreeswan/ipsec_md5h.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * RCSID $Id: ipsec_md5h.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-/*
- * The rest of this file is Copyright RSA DSI. See the following comments
- * for the full Copyright notice.
- */
-
-#ifndef _IPSEC_MD5H_H_
-#define _IPSEC_MD5H_H_
-
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
- The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#define PROTOTYPES 1
-#endif /* !PROTOTYPES */
-
-/* POINTER defines a generic pointer type */
-typedef __u8 *POINTER;
-
-/* UINT2 defines a two byte word */
-typedef __u16 UINT2;
-
-/* UINT4 defines a four byte word */
-typedef __u32 UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else /* PROTOTYPES */
-#define PROTO_LIST(list) ()
-#endif /* PROTOTYPES */
-
-
-/* MD5.H - header file for MD5C.C
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-void MD5Init PROTO_LIST ((void *));
-void MD5Update PROTO_LIST
- ((void *, unsigned char *, __u32));
-void MD5Final PROTO_LIST ((unsigned char [16], void *));
-
-#endif /* _IPSEC_MD5H_H_ */
diff --git a/src/libfreeswan/ipsec_param.h b/src/libfreeswan/ipsec_param.h
index 209244c59..b0ee845a5 100644
--- a/src/libfreeswan/ipsec_param.h
+++ b/src/libfreeswan/ipsec_param.h
@@ -13,9 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ipsec_param.h 3265 2007-10-08 19:52:55Z andreas $
- *
*/
/*
@@ -28,40 +25,6 @@
#ifndef _IPSEC_PARAM_H_
-#ifdef __KERNEL__
-#include "ipsec_kversion.h"
-
-/* Set number of ipsecX virtual devices here. */
-/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
-/* It must also be reasonable so as not to overload the memory and CPU */
-/* constraints of the host. */
-#define IPSEC_NUM_IF 4
-/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
-/* With "ipsec" being 5 characters, that means 10 is the max field width */
-/* but machine memory and CPU constraints are not likely to tollerate */
-/* more than 3 digits. The default is one digit. */
-/* Update: userland scripts get upset if they can't find "ipsec0", so */
-/* for now, no "0"-padding should be used (which would have been helpful */
-/* to make text-searches work */
-#define IPSEC_DEV_FORMAT "ipsec%d"
-/* For, say, 500 virtual ipsec devices, I would recommend: */
-/* #define IPSEC_NUM_IF 500 */
-/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
-/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
-
-/* use dynamic ipsecX device allocation */
-#ifndef CONFIG_IPSEC_DYNDEV
-#define CONFIG_IPSEC_DYNDEV 1
-#endif /* CONFIG_IPSEC_DYNDEV */
-
-
-#ifdef CONFIG_IPSEC_BIGGATE
-# define SADB_HASHMOD 8069
-#else /* CONFIG_IPSEC_BIGGATE */
-# define SADB_HASHMOD 257
-#endif /* CONFIG_IPSEC_BIGGATE */
-#endif /* __KERNEL__ */
-
/*
* This is for the SA reference table. This number is related to the
* maximum number of SAs that KLIPS can concurrently deal with, plus enough
@@ -87,140 +50,5 @@
# define IPSEC_SA_REF_CODE 1
#endif
-#ifdef __KERNEL__
-/* This is defined for 2.4, but not 2.2.... */
-#ifndef ARPHRD_VOID
-# define ARPHRD_VOID 0xFFFF
-#endif
-
-/*
- * Worry about PROC_FS stuff
- */
-#if defined(PROC_FS_2325)
-/* kernel 2.4 */
-# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
-# define IPSEC_PROCFS_DEBUG_NO_STATIC
-# define IPSEC_PROC_SUBDIRS
-#else
-/* kernel <2.4 */
-# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
-
-# ifndef PROC_NO_DUMMY
-# define IPSEC_PROC_LAST_ARG , int dummy
-# else
-# define IPSEC_PROC_LAST_ARG
-# endif /* !PROC_NO_DUMMY */
-#endif /* PROC_FS_2325 */
-
-#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
-/* GNU CPP specific! */
-# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
-#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
-
-#ifdef SPINLOCK
-# ifdef SPINLOCK_23
-# include <linux/spinlock.h> /* *lock* */
-# else /* SPINLOCK_23 */
-# include <asm/spinlock.h> /* *lock* */
-# endif /* SPINLOCK_23 */
-#endif /* SPINLOCK */
-
-#ifndef KLIPS_FIXES_DES_PARITY
-# define KLIPS_FIXES_DES_PARITY 1
-#endif /* !KLIPS_FIXES_DES_PARITY */
-
-/* we don't really want to print these unless there are really big problems */
-#ifndef KLIPS_DIVULGE_CYPHER_KEY
-# define KLIPS_DIVULGE_CYPHER_KEY 0
-#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
-
-#ifndef KLIPS_DIVULGE_HMAC_KEY
-# define KLIPS_DIVULGE_HMAC_KEY 0
-#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-
-#ifndef IPSEC_DISALLOW_IPOPTIONS
-# define IPSEC_DISALLOW_IPOPTIONS 1
-#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-
-/* extra toggles for regression testing */
-#ifdef CONFIG_IPSEC_REGRESS
-
-/*
- * should pfkey_acquire() become 100% lossy?
- *
- */
-extern int sysctl_ipsec_regress_pfkey_lossage;
-#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
-# ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE
-# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
-# else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-/* not by default! */
-# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
-# endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
-
-#endif /* CONFIG_IPSEC_REGRESS */
-
-/*
- * debugging routines.
- */
-#ifdef CONFIG_IPSEC_DEBUG
-extern void ipsec_print_ip(struct iphdr *ip);
-
- #define KLIPS_PRINT(flag, format, args...) \
- ((flag) ? printk(KERN_INFO format , ## args) : 0)
- #define KLIPS_PRINTMORE(flag, format, args...) \
- ((flag) ? printk(format , ## args) : 0)
- #define KLIPS_IP_PRINT(flag, ip) \
- ((flag) ? ipsec_print_ip(ip) : 0)
-#else /* CONFIG_IPSEC_DEBUG */
- #define KLIPS_PRINT(flag, format, args...) do ; while(0)
- #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
- #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
-#endif /* CONFIG_IPSEC_DEBUG */
-
-
-/*
- * Stupid kernel API differences in APIs. Not only do some
- * kernels not have ip_select_ident, but some have differing APIs,
- * and SuSE has one with one parameter, but no way of checking to
- * see what is really what.
- */
-
-#ifdef SUSE_LINUX_2_4_19_IS_STUPID
-#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
-#else
-
-/* simplest case, nothing */
-#if !defined(IP_SELECT_IDENT)
-#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
-#endif
-
-/* kernels > 2.3.37-ish */
-#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
-#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
-#endif
-
-/* kernels > 2.4.2 */
-#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
-#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
-#endif
-
-#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
-
-/*
- * make klips fail test:east-espiv-01.
- * exploit is at testing/attacks/espiv
- *
- */
-#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
-
-
-/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
-#ifndef IP_FRAGMENT_LINEARIZE
-# define IP_FRAGMENT_LINEARIZE 0
-#endif /* IP_FRAGMENT_LINEARIZE */
-#endif /* __KERNEL__ */
-
#define _IPSEC_PARAM_H_
#endif /* _IPSEC_PARAM_H_ */
diff --git a/src/libfreeswan/ipsec_policy.h b/src/libfreeswan/ipsec_policy.h
deleted file mode 100644
index bf074f18f..000000000
--- a/src/libfreeswan/ipsec_policy.h
+++ /dev/null
@@ -1,233 +0,0 @@
-#ifndef _IPSEC_POLICY_H
-/*
- * policy interface file between pluto and applications
- * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- *
- * RCSID $Id: ipsec_policy.h 3839 2008-04-18 11:25:37Z andreas $
- */
-#define _IPSEC_POLICY_H /* seen it, no need to see it again */
-
-
-/*
- * this file defines an interface between an application (or rather an
- * application library) and a key/policy daemon. It provides for inquiries
- * as to the current state of a connected socket, as well as for general
- * questions.
- *
- * In general, the interface is defined as a series of functional interfaces,
- * and the policy messages should be internal. However, because this is in
- * fact an ABI between pieces of the system that may get compiled and revised
- * seperately, this ABI must be public and revision controlled.
- *
- * It is expected that the daemon will always support previous versions.
- */
-
-#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
-
-enum ipsec_policy_command {
- IPSEC_CMD_QUERY_FD = 1,
- IPSEC_CMD_QUERY_HOSTPAIR = 2,
- IPSEC_CMD_QUERY_DSTONLY = 3,
-};
-
-struct ipsec_policy_msg_head {
- u_int32_t ipm_version;
- u_int32_t ipm_msg_len;
- u_int32_t ipm_msg_type;
- u_int32_t ipm_msg_seq;
-};
-
-enum ipsec_privacy_quality {
- IPSEC_PRIVACY_NONE = 0,
- IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
- IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
- IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
- IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
- IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
- IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
- IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
- IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
-};
-
-enum ipsec_bandwidth_quality {
- IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
- IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
- Good enough for telnet/ssh. */
- IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
- IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
- offloaded, but latency/jitter may be bad */
- IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
-};
-
-/* moved from programs/pluto/constants.h */
-/* IPsec AH transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
- * and in http://www.iana.org/assignments/isakmp-registry
- */
-enum ipsec_authentication_algo {
- AH_NONE = 0,
- AH_MD5 = 2,
- AH_SHA = 3,
- AH_DES = 4,
- AH_SHA2_256 = 5,
- AH_SHA2_384 = 6,
- AH_SHA2_512 = 7,
- AH_RIPEMD = 8,
- AH_AES_XCBC_MAC = 9,
- AH_RSA = 10
-};
-
-/* IPsec ESP transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
- * and from http://www.iana.org/assignments/isakmp-registry
- */
-
-enum ipsec_cipher_algo {
- ESP_NONE = 0,
- ESP_DES_IV64 = 1,
- ESP_DES = 2,
- ESP_3DES = 3,
- ESP_RC5 = 4,
- ESP_IDEA = 5,
- ESP_CAST = 6,
- ESP_BLOWFISH = 7,
- ESP_3IDEA = 8,
- ESP_DES_IV32 = 9,
- ESP_RC4 = 10,
- ESP_NULL = 11,
- ESP_AES = 12,
- ESP_AES_CTR = 13,
- ESP_AES_CCM_8 = 14,
- ESP_AES_CCM_12 = 15,
- ESP_AES_CCM_16 = 16,
- ESP_UNASSIGNED_17 = 17,
- ESP_AES_GCM_8 = 18,
- ESP_AES_GCM_12 = 19,
- ESP_AES_GCM_16 = 20,
- ESP_SEED_CBC = 21,
- ESP_CAMELLIA = 22,
- ESP_SERPENT = 252,
- ESP_TWOFISH = 253
-};
-
-/* IPCOMP transform values
- * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
- */
-
-enum ipsec_comp_algo {
- IPSCOMP_NONE = 0,
- IPCOMP_OUI = 1,
- IPCOMP_DEFLATE = 2,
- IPCOMP_LZS = 3,
- IPCOMP_LZJH = 4
-};
-
-/* Identification type values
- * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
- */
-
-enum ipsec_id_type {
- ID_IMPOSSIBLE= (-2), /* private to Pluto */
- ID_MYID= (-1), /* private to Pluto */
- ID_NONE= 0, /* private to Pluto */
- ID_IPV4_ADDR= 1,
- ID_FQDN= 2,
- ID_USER_FQDN= 3,
- ID_IPV4_ADDR_SUBNET= 4,
- ID_IPV6_ADDR= 5,
- ID_IPV6_ADDR_SUBNET= 6,
- ID_IPV4_ADDR_RANGE= 7,
- ID_IPV6_ADDR_RANGE= 8,
- ID_DER_ASN1_DN= 9,
- ID_DER_ASN1_GN= 10,
- ID_KEY_ID= 11
-};
-
-/* Certificate type values
- * RFC 2408 ISAKMP, chapter 3.9
- */
-enum ipsec_cert_type {
- CERT_NONE= 0,
- CERT_PKCS7_WRAPPED_X509= 1,
- CERT_PGP= 2,
- CERT_DNS_SIGNED_KEY= 3,
- CERT_X509_SIGNATURE= 4,
- CERT_X509_KEY_EXCHANGE= 5,
- CERT_KERBEROS_TOKENS= 6,
- CERT_CRL= 7,
- CERT_ARL= 8,
- CERT_SPKI= 9,
- CERT_X509_ATTRIBUTE= 10,
- CERT_RAW_RSA_KEY= 11
-};
-
-/* a SIG record in ASCII */
-struct ipsec_dns_sig {
- char fqdn[256];
- char dns_sig[768]; /* empty string if not signed */
-};
-
-struct ipsec_raw_key {
- char id_name[256];
- char fs_keyid[8];
-};
-
-struct ipsec_identity {
- enum ipsec_id_type ii_type;
- enum ipsec_cert_type ii_format;
- union {
- struct ipsec_dns_sig ipsec_dns_signed;
- /* some thing for PGP */
- /* some thing for PKIX */
- struct ipsec_raw_key ipsec_raw_key;
- } ii_credential;
-};
-
-#define IPSEC_MAX_CREDENTIALS 32
-
-struct ipsec_policy_cmd_query {
- struct ipsec_policy_msg_head head;
-
- /* Query section */
- ip_address query_local; /* us */
- ip_address query_remote; /* them */
- u_short src_port, dst_port;
-
- /* Answer section */
- enum ipsec_privacy_quality strength;
- enum ipsec_bandwidth_quality bandwidth;
- enum ipsec_authentication_algo auth_detail;
- enum ipsec_cipher_algo esp_detail;
- enum ipsec_comp_algo comp_detail;
-
- int credential_count;
-
- struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
-};
-
-#define IPSEC_POLICY_SOCKET "/var/run/pluto.info"
-
-/* prototypes */
-extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
-extern err_t ipsec_policy_init(void);
-extern err_t ipsec_policy_final(void);
-extern err_t ipsec_policy_readmsg(int policysock,
- unsigned char *buf, size_t buflen);
-extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
-extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
-
-
-extern const char *ipsec_policy_version_code(void);
-extern const char *ipsec_policy_version_string(void);
-
-#endif /* _IPSEC_POLICY_H */
diff --git a/src/libfreeswan/ipsec_proto.h b/src/libfreeswan/ipsec_proto.h
deleted file mode 100644
index 23b9cf247..000000000
--- a/src/libfreeswan/ipsec_proto.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * @(#) prototypes for FreeSWAN functions
- *
- * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_proto.h 3265 2007-10-08 19:52:55Z andreas $
- *
- */
-
-#ifndef _IPSEC_PROTO_H_
-
-#include "ipsec_param.h"
-
-/*
- * This file is a kernel only file that declares prototypes for
- * all intra-module function calls and global data structures.
- *
- * Include this file last.
- *
- */
-
-/* ipsec_init.c */
-extern struct prng ipsec_prng;
-
-/* ipsec_sa.c */
-extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
-extern spinlock_t tdb_lock;
-extern int ipsec_sadb_init(void);
-
-extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id*);
-extern int ipsec_sa_put(struct ipsec_sa *);
-extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
-extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
-extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
-
-extern int ipsec_sadb_cleanup(__u8);
-extern int ipsec_sa_wipe(struct ipsec_sa *);
-
-/* debug declarations */
-
-/* ipsec_proc.c */
-extern int ipsec_proc_init(void);
-extern void ipsec_proc_cleanup(void);
-
-/* ipsec_radij.c */
-extern int ipsec_makeroute(struct sockaddr_encap *ea,
- struct sockaddr_encap *em,
- struct sa_id said,
- uint32_t pid,
- struct sk_buff *skb,
- struct ident *ident_s,
- struct ident *ident_d);
-
-extern int ipsec_breakroute(struct sockaddr_encap *ea,
- struct sockaddr_encap *em,
- struct sk_buff **first,
- struct sk_buff **last);
-
-int ipsec_radijinit(void);
-int ipsec_cleareroutes(void);
-int ipsec_radijcleanup(void);
-
-/* ipsec_life.c */
-extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
- const char *lifename,
- const char *saname,
- enum ipsec_life_type ilt,
- enum ipsec_direction idir,
- struct ipsec_sa *ips);
-
-
-extern int ipsec_lifetime_format(char *buffer,
- int buflen,
- char *lifename,
- enum ipsec_life_type timebaselife,
- struct ipsec_lifetime64 *lifetime);
-
-extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
- __u64 newvalue);
-
-extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
- __u64 newvalue);
-
-
-
-
-#ifdef CONFIG_IPSEC_DEBUG
-
-extern int debug_xform;
-extern int debug_eroute;
-extern int debug_spi;
-extern int debug_netlink;
-
-#endif /* CONFIG_IPSEC_DEBUG */
-
-
-
-
-#define _IPSEC_PROTO_H
-#endif /* _IPSEC_PROTO_H_ */
diff --git a/src/libfreeswan/ipsec_radij.h b/src/libfreeswan/ipsec_radij.h
deleted file mode 100644
index 88e849eee..000000000
--- a/src/libfreeswan/ipsec_radij.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_radij.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#ifndef _IPSEC_RADIJ_H
-
-#include <freeswan.h>
-
-int ipsec_walk(char *);
-
-int ipsec_rj_walker_procprint(struct radij_node *, void *);
-int ipsec_rj_walker_delete(struct radij_node *, void *);
-
-/* This structure is used to pass information between
- * ipsec_eroute_get_info and ipsec_rj_walker_procprint
- * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
- */
-struct wsbuf
-{
- /* from caller of ipsec_eroute_get_info: */
- char *const buffer; /* start of buffer provided */
- const int length; /* length of buffer provided */
- const off_t offset; /* file position of first character of interest */
- /* accumulated by ipsec_rj_walker_procprint: */
- int len; /* number of character filled into buffer */
- off_t begin; /* file position contained in buffer[0] (<=offset) */
-};
-
-
-extern struct radij_node_head *rnh;
-extern spinlock_t eroute_lock;
-
-struct eroute * ipsec_findroute(struct sockaddr_encap *);
-
-#define O1(x) (int)(((x)>>24)&0xff)
-#define O2(x) (int)(((x)>>16)&0xff)
-#define O3(x) (int)(((x)>>8)&0xff)
-#define O4(x) (int)(((x))&0xff)
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int debug_radij;
-void rj_dumptrees(void);
-
-#define DB_RJ_DUMPTREES 0x0001
-#define DB_RJ_FINDROUTE 0x0002
-#endif /* CONFIG_IPSEC_DEBUG */
-
-#define _IPSEC_RADIJ_H
-#endif
diff --git a/src/libfreeswan/ipsec_rcv.h b/src/libfreeswan/ipsec_rcv.h
deleted file mode 100644
index d972a18b9..000000000
--- a/src/libfreeswan/ipsec_rcv.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_rcv.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#define DB_RX_PKTRX 0x0001
-#define DB_RX_PKTRX2 0x0002
-#define DB_RX_DMP 0x0004
-#define DB_RX_IPSA 0x0010
-#define DB_RX_XF 0x0020
-#define DB_RX_IPAD 0x0040
-#define DB_RX_INAU 0x0080
-#define DB_RX_OINFO 0x0100
-#define DB_RX_OINFO2 0x0200
-#define DB_RX_OH 0x0400
-#define DB_RX_REPLAY 0x0800
-
-#ifdef __KERNEL__
-/* struct options; */
-
-#define __NO_VERSION__
-#include <linux/module.h>
-#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-#include <linux/version.h>
-#include <freeswan.h>
-
-#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
-
-struct ipsec_birth_reply {
- int packet_template_len;
- unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
-};
-
-extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
-extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
-
-extern int
-#ifdef PROTO_HANDLER_SINGLE_PARM
-ipsec_rcv(struct sk_buff *skb);
-#else /* PROTO_HANDLER_SINGLE_PARM */
-ipsec_rcv(struct sk_buff *skb,
-#ifdef NET_21
- unsigned short xlen);
-#else /* NET_21 */
- struct device *dev,
- struct options *opt,
- __u32 daddr,
- unsigned short len,
- __u32 saddr,
- int redo,
- struct inet_protocol *protocol);
-#endif /* NET_21 */
-#endif /* PROTO_HANDLER_SINGLE_PARM */
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int debug_rcv;
-#endif /* CONFIG_IPSEC_DEBUG */
-extern int sysctl_ipsec_inbound_policy_check;
-#endif /* __KERNEL__ */
diff --git a/src/libfreeswan/ipsec_sa.h b/src/libfreeswan/ipsec_sa.h
deleted file mode 100644
index 9d178e11f..000000000
--- a/src/libfreeswan/ipsec_sa.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * @(#) Definitions of IPsec Security Association (ipsec_sa)
- *
- * Copyright (C) 2001, 2002, 2003
- * Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_sa.h 3265 2007-10-08 19:52:55Z andreas $
- *
- * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
- *
- */
-
-/*
- * This file describes the IPsec Security Association Structure.
- *
- * This structure keeps track of a single transform that may be done
- * to a set of packets. It can describe applying the transform or
- * apply the reverse. (e.g. compression vs expansion). However, it
- * only describes one at a time. To describe both, two structures would
- * be used, but since the sides of the transform are performed
- * on different machines typically it is usual to have only one side
- * of each association.
- *
- */
-
-#ifndef _IPSEC_SA_H_
-
-#ifdef __KERNEL__
-#include "ipsec_stats.h"
-#include "ipsec_life.h"
-#include "ipsec_eroute.h"
-#endif /* __KERNEL__ */
-#include "ipsec_param.h"
-
-
-/* SAs are held in a table.
- * Entries in this table are referenced by IPsecSAref_t values.
- * IPsecSAref_t values are conceptually subscripts. Because
- * we want to allocate the table piece-meal, the subscripting
- * is implemented with two levels, a bit like paged virtual memory.
- * This representation mechanism is known as an Iliffe Vector.
- *
- * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
- * pointers to subtables.
- * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
- * is a pointer to an SA.
- *
- * An IPsecSAref_t contains either an exceptional value (signified by the
- * high-order bit being on) or a reference to a table entry. A table entry
- * reference has the subtable subscript in the low-order
- * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
- * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
- *
- * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
- * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
- *
- * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
- * struct ipsec_sa*. The macro definition clearly shows the two-level
- * access needed to find the SA pointer.
- *
- * The Maintable is allocated when IPsec is initialized.
- * Each subtable is allocated when needed, but the first is allocated
- * when IPsec is initialized.
- *
- * IPsecSAref_t is designed to be smaller than an NFmark so that
- * they can be stored in NFmarks and still leave a few bits for other
- * purposes. The spare bits are in the low order of the NFmark
- * but in the high order of the IPsecSAref_t, so conversion is required.
- * We pick the upper bits of NFmark on the theory that they are less likely to
- * interfere with more pedestrian uses of nfmark.
- */
-
-
-typedef unsigned short int IPsecRefTableUnusedCount;
-
-#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
-
-#ifdef __KERNEL__
-#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
-#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
-#endif
-
-#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-
-#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-
-#ifdef CONFIG_NETFILTER
-#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
-#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
-#else /* CONFIG_NETFILTER */
-/* just make it work for now, it doesn't matter, since there is no nfmark */
-#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
-#endif /* CONFIG_NETFILTER */
-#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
-#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-
-#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
-
-#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
-#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
-
-#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
-#define IPsecSA2SAref(x) ((x)->ips_ref)
-
-#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
-
-/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
-struct ipsec_sa
-{
- IPsecSAref_t ips_ref; /* reference table entry number */
- atomic_t ips_refcount; /* reference count for this struct */
- struct ipsec_sa *ips_hnext; /* next in hash chain */
- struct ipsec_sa *ips_inext; /* pointer to next xform */
- struct ipsec_sa *ips_onext; /* pointer to prev xform */
-
- struct ifnet *ips_rcvif; /* related rcv encap interface */
-
- struct sa_id ips_said; /* SA ID */
-
- __u32 ips_seq; /* seq num of msg that initiated this SA */
- __u32 ips_pid; /* PID of process that initiated this SA */
- __u8 ips_authalg; /* auth algorithm for this SA */
- __u8 ips_encalg; /* enc algorithm for this SA */
-
- struct ipsec_stats ips_errs;
-
- __u8 ips_replaywin; /* replay window size */
- __u8 ips_state; /* state of SA */
- __u32 ips_replaywin_lastseq; /* last pkt sequence num */
- __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
- __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
-
- __u32 ips_flags; /* generic xform flags */
-
-
- struct ipsec_lifetimes ips_life; /* lifetime records */
-
- /* selector information */
- struct sockaddr*ips_addr_s; /* src sockaddr */
- struct sockaddr*ips_addr_d; /* dst sockaddr */
- struct sockaddr*ips_addr_p; /* proxy sockaddr */
- __u16 ips_addr_s_size;
- __u16 ips_addr_d_size;
- __u16 ips_addr_p_size;
- ip_address ips_flow_s;
- ip_address ips_flow_d;
- ip_address ips_mask_s;
- ip_address ips_mask_d;
-
- __u16 ips_key_bits_a; /* size of authkey in bits */
- __u16 ips_auth_bits; /* size of authenticator in bits */
- __u16 ips_key_bits_e; /* size of enckey in bits */
- __u16 ips_iv_bits; /* size of IV in bits */
- __u8 ips_iv_size;
- __u16 ips_key_a_size;
- __u16 ips_key_e_size;
-
- caddr_t ips_key_a; /* authentication key */
- caddr_t ips_key_e; /* encryption key */
- caddr_t ips_iv; /* Initialisation Vector */
-
- struct ident ips_ident_s; /* identity src */
- struct ident ips_ident_d; /* identity dst */
-
-#ifdef CONFIG_IPSEC_IPCOMP
- __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
- __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
- __u64 ips_comp_ratio_cbytes; /* compressed bytes */
- __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
-#endif /* CONFIG_IPSEC_IPCOMP */
-
-#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
- __u8 ips_natt_type;
- __u8 ips_natt_reserved[3];
- __u16 ips_natt_sport;
- __u16 ips_natt_dport;
-
- struct sockaddr *ips_natt_oa;
- __u16 ips_natt_oa_size;
- __u16 ips_natt_reserved2;
-#endif
-
-#if 0
- __u32 ips_sens_dpd;
- __u8 ips_sens_sens_level;
- __u8 ips_sens_sens_len;
- __u64* ips_sens_sens_bitmap;
- __u8 ips_sens_integ_level;
- __u8 ips_sens_integ_len;
- __u64* ips_sens_integ_bitmap;
-#endif
- struct ipsec_alg_enc *ips_alg_enc;
- struct ipsec_alg_auth *ips_alg_auth;
- IPsecSAref_t ips_ref_rel;
-};
-
-struct IPsecSArefSubTable
-{
- struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
-};
-
-struct ipsec_sadb {
- struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
- IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
- int refFreeListHead;
- int refFreeListTail;
- IPsecSAref_t refFreeListCont;
- IPsecSAref_t said_hash[SADB_HASHMOD];
- spinlock_t sadb_lock;
-};
-
-extern struct ipsec_sadb ipsec_sadb;
-
-extern int ipsec_SAref_recycle(void);
-extern int ipsec_SArefSubTable_alloc(unsigned table);
-extern int ipsec_saref_freelist_init(void);
-extern int ipsec_sadb_init(void);
-extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
-extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
-extern int ipsec_sa_free(struct ipsec_sa* ips);
-extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id *said);
-extern int ipsec_sa_put(struct ipsec_sa *ips);
-extern int ipsec_sa_add(struct ipsec_sa *ips);
-extern int ipsec_sa_del(struct ipsec_sa *ips);
-extern int ipsec_sa_delchain(struct ipsec_sa *ips);
-extern int ipsec_sadb_cleanup(__u8 proto);
-extern int ipsec_sadb_free(void);
-extern int ipsec_sa_wipe(struct ipsec_sa *ips);
-#endif /* __KERNEL__ */
-
-enum ipsec_direction {
- ipsec_incoming = 1,
- ipsec_outgoing = 2
-};
-
-#define _IPSEC_SA_H_
-#endif /* _IPSEC_SA_H_ */
diff --git a/src/libfreeswan/ipsec_sha1.h b/src/libfreeswan/ipsec_sha1.h
deleted file mode 100644
index b0f952c92..000000000
--- a/src/libfreeswan/ipsec_sha1.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * RCSID $Id: ipsec_sha1.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-/*
- * Here is the original comment from the distribution:
-
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-
- * Adapted for use by the IPSEC code by John Ioannidis
- */
-
-
-#ifndef _IPSEC_SHA1_H_
-#define _IPSEC_SHA1_H_
-
-typedef struct
-{
- __u32 state[5];
- __u32 count[2];
- __u8 buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(__u32 state[5], __u8 buffer[64]);
-void SHA1Init(void *context);
-void SHA1Update(void *context, unsigned char *data, __u32 len);
-void SHA1Final(unsigned char digest[20], void *context);
-
-
-#endif /* _IPSEC_SHA1_H_ */
diff --git a/src/libfreeswan/ipsec_stats.h b/src/libfreeswan/ipsec_stats.h
deleted file mode 100644
index dabd02993..000000000
--- a/src/libfreeswan/ipsec_stats.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * @(#) definition of ipsec_stats structure
- *
- * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
- * and Michael Richardson <mcr@freeswan.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_stats.h 3265 2007-10-08 19:52:55Z andreas $
- *
- */
-
-/*
- * This file describes the errors/statistics that FreeSWAN collects.
- */
-
-#ifndef _IPSEC_STATS_H_
-
-struct ipsec_stats {
- __u32 ips_alg_errs; /* number of algorithm errors */
- __u32 ips_auth_errs; /* # of authentication errors */
- __u32 ips_encsize_errs; /* # of encryption size errors*/
- __u32 ips_encpad_errs; /* # of encryption pad errors*/
- __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-};
-
-extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
-
-#define _IPSEC_STATS_H_
-#endif /* _IPSEC_STATS_H_ */
diff --git a/src/libfreeswan/ipsec_tunnel.h b/src/libfreeswan/ipsec_tunnel.h
deleted file mode 100644
index df52cf646..000000000
--- a/src/libfreeswan/ipsec_tunnel.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * IPSEC tunneling code
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_tunnel.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#include <linux/types.h>
-
-#ifdef NET_21
-# define DEV_QUEUE_XMIT(skb, device, pri) {\
- skb->dev = device; \
- neigh_compat_output(skb); \
- /* skb->dst->output(skb); */ \
- }
-# define ICMP_SEND(skb_in, type, code, info, dev) \
- icmp_send(skb_in, type, code, htonl(info))
-# define IP_SEND(skb, dev) \
- ip_send(skb);
-#else /* NET_21 */
-# define DEV_QUEUE_XMIT(skb, device, pri) {\
- dev_queue_xmit(skb, device, pri); \
- }
-# define ICMP_SEND(skb_in, type, code, info, dev) \
- icmp_send(skb_in, type, code, info, dev)
-# define IP_SEND(skb, dev) \
- if(ntohs(iph->tot_len) > physmtu) { \
- ip_fragment(NULL, skb, dev, 0); \
- ipsec_kfree_skb(skb); \
- } else { \
- dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
- }
-#endif /* NET_21 */
-
-
-/*
- * Heavily based on drivers/net/new_tunnel.c. Lots
- * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
- */
-
-struct ipsectunnelconf
-{
- __u32 cf_cmd;
- union
- {
- char cfu_name[12];
- } cf_u;
-#define cf_name cf_u.cfu_name
-};
-
-#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
-#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
-#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
-
-#ifdef __KERNEL__
-#include <linux/version.h>
-#ifndef KERNEL_VERSION
-# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
-struct ipsecpriv
-{
- struct sk_buff_head sendq;
- struct device *dev;
- struct wait_queue *wait_queue;
- char locked;
- int (*hard_start_xmit) (struct sk_buff *skb,
- struct device *dev);
- int (*hard_header) (struct sk_buff *skb,
- struct device *dev,
- unsigned short type,
- void *daddr,
- void *saddr,
- unsigned len);
-#ifdef NET_21
- int (*rebuild_header)(struct sk_buff *skb);
-#else /* NET_21 */
- int (*rebuild_header)(void *buff, struct device *dev,
- unsigned long raddr, struct sk_buff *skb);
-#endif /* NET_21 */
- int (*set_mac_address)(struct device *dev, void *addr);
-#ifndef NET_21
- void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
- unsigned short htype, __u32 daddr);
-#endif /* !NET_21 */
- void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
- struct net_device_stats *(*get_stats)(struct device *dev);
- struct net_device_stats mystats;
- int mtu; /* What is the desired MTU? */
-};
-
-extern char ipsec_tunnel_c_version[];
-
-extern struct device *ipsecdevices[IPSEC_NUM_IF];
-
-int ipsec_tunnel_init_devices(void);
-
-/* void */ int ipsec_tunnel_cleanup_devices(void);
-
-extern /* void */ int ipsec_init(void);
-
-extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev);
-
-#ifdef CONFIG_IPSEC_DEBUG
-extern int debug_tunnel;
-extern int sysctl_ipsec_debug_verbose;
-#endif /* CONFIG_IPSEC_DEBUG */
-#endif /* __KERNEL__ */
-
-#ifdef CONFIG_IPSEC_DEBUG
-#define DB_TN_INIT 0x0001
-#define DB_TN_PROCFS 0x0002
-#define DB_TN_XMIT 0x0010
-#define DB_TN_OHDR 0x0020
-#define DB_TN_CROUT 0x0040
-#define DB_TN_OXFS 0x0080
-#define DB_TN_REVEC 0x0100
-#endif /* CONFIG_IPSEC_DEBUG */
diff --git a/src/libfreeswan/ipsec_xform.h b/src/libfreeswan/ipsec_xform.h
deleted file mode 100644
index 642a39bd5..000000000
--- a/src/libfreeswan/ipsec_xform.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Definitions relevant to IPSEC transformations
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_xform.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#ifndef _IPSEC_XFORM_H_
-
-#include <freeswan.h>
-#include "ipsec_policy.h"
-
-#define XF_NONE 0 /* No transform set */
-#define XF_IP4 1 /* IPv4 inside IPv4 */
-#define XF_AHMD5 2 /* AH MD5 */
-#define XF_AHSHA 3 /* AH SHA */
-#define XF_ESP3DES 5 /* ESP DES3-CBC */
-#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
-#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
-#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
-#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
-#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
-#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
-#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
-#define XF_IP6 15 /* IPv6 inside IPv6 */
-#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
-
-#define XF_CLR 126 /* Clear SA table */
-#define XF_DEL 127 /* Delete SA */
-
-#define XFT_AUTH 0x0001
-#define XFT_CONF 0x0100
-
-/* available if CONFIG_IPSEC_DEBUG is defined */
-#define DB_XF_INIT 0x0001
-
-#define PROTO2TXT(x) \
- (x) == IPPROTO_AH ? "AH" : \
- (x) == IPPROTO_ESP ? "ESP" : \
- (x) == IPPROTO_IPIP ? "IPIP" : \
- (x) == IPPROTO_COMP ? "COMP" : \
- "UNKNOWN_proto"
-static inline const char *enc_name_id (unsigned id) {
- static char buf[16];
- snprintf(buf, sizeof(buf), "_ID%d", id);
- return buf;
-}
-static inline const char *auth_name_id (unsigned id) {
- static char buf[16];
- snprintf(buf, sizeof(buf), "_ID%d", id);
- return buf;
-}
-#define IPS_XFORM_NAME(x) \
- PROTO2TXT((x)->ips_said.proto), \
- (x)->ips_said.proto == IPPROTO_COMP ? \
- ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
- "_DEFLATE" : "_UNKNOWN_comp") : \
- (x)->ips_encalg == ESP_NONE ? "" : \
- (x)->ips_encalg == ESP_3DES ? "_3DES" : \
- (x)->ips_encalg == ESP_AES ? "_AES" : \
- (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
- (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
- enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
- (x)->ips_authalg == AH_NONE ? "" : \
- (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
- (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
- (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
- (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
- (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
- auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
-
-#define _IPSEC_XFORM_H_
-#endif /* _IPSEC_XFORM_H_ */
diff --git a/src/libfreeswan/ipsec_xmit.h b/src/libfreeswan/ipsec_xmit.h
deleted file mode 100644
index 07ed7da43..000000000
--- a/src/libfreeswan/ipsec_xmit.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * IPSEC tunneling code
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: ipsec_xmit.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#include "freeswan/ipsec_sa.h"
-
-enum ipsec_xmit_value
-{
- IPSEC_XMIT_STOLEN=2,
- IPSEC_XMIT_PASS=1,
- IPSEC_XMIT_OK=0,
- IPSEC_XMIT_ERRMEMALLOC=-1,
- IPSEC_XMIT_ESP_BADALG=-2,
- IPSEC_XMIT_BADPROTO=-3,
- IPSEC_XMIT_ESP_PUSHPULLERR=-4,
- IPSEC_XMIT_BADLEN=-5,
- IPSEC_XMIT_AH_BADALG=-6,
- IPSEC_XMIT_SAIDNOTFOUND=-7,
- IPSEC_XMIT_SAIDNOTLIVE=-8,
- IPSEC_XMIT_REPLAYROLLED=-9,
- IPSEC_XMIT_LIFETIMEFAILED=-10,
- IPSEC_XMIT_CANNOTFRAG=-11,
- IPSEC_XMIT_MSSERR=-12,
- IPSEC_XMIT_ERRSKBALLOC=-13,
- IPSEC_XMIT_ENCAPFAIL=-14,
- IPSEC_XMIT_NODEV=-15,
- IPSEC_XMIT_NOPRIVDEV=-16,
- IPSEC_XMIT_NOPHYSDEV=-17,
- IPSEC_XMIT_NOSKB=-18,
- IPSEC_XMIT_NOIPV6=-19,
- IPSEC_XMIT_NOIPOPTIONS=-20,
- IPSEC_XMIT_TTLEXPIRED=-21,
- IPSEC_XMIT_BADHHLEN=-22,
- IPSEC_XMIT_PUSHPULLERR=-23,
- IPSEC_XMIT_ROUTEERR=-24,
- IPSEC_XMIT_RECURSDETECT=-25,
- IPSEC_XMIT_IPSENDFAILURE=-26,
-#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
- IPSEC_XMIT_ESPUDP=-27,
-#endif
-};
-
-struct ipsec_xmit_state
-{
- struct sk_buff *skb; /* working skb pointer */
- struct device *dev; /* working dev pointer */
- struct ipsecpriv *prv; /* Our device' private space */
- struct sk_buff *oskb; /* Original skb pointer */
- struct net_device_stats *stats; /* This device's statistics */
- struct iphdr *iph; /* Our new IP header */
- __u32 newdst; /* The other SG's IP address */
- __u32 orgdst; /* Original IP destination address */
- __u32 orgedst; /* 1st SG's IP address */
- __u32 newsrc; /* The new source SG's IP address */
- __u32 orgsrc; /* Original IP source address */
- __u32 innersrc; /* Innermost IP source address */
- int iphlen; /* IP header length */
- int pyldsz; /* upper protocol payload size */
- int headroom;
- int tailroom;
- int max_headroom; /* The extra header space needed */
- int max_tailroom; /* The extra stuffing needed */
- int ll_headroom; /* The extra link layer hard_header space needed */
- int tot_headroom; /* The total header space needed */
- int tot_tailroom; /* The totalstuffing needed */
- __u8 *saved_header; /* saved copy of the hard header */
- unsigned short sport, dport;
-
- struct sockaddr_encap matcher; /* eroute search key */
- struct eroute *eroute;
- struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
- char sa_txt[SATOA_BUF];
- size_t sa_len;
- int hard_header_stripped; /* has the hard header been removed yet? */
- int hard_header_len;
- struct device *physdev;
-/* struct device *virtdev; */
- short physmtu;
- short mtudiff;
-#ifdef NET_21
- struct rtable *route;
-#endif /* NET_21 */
- struct sa_id outgoing_said;
-#ifdef NET_21
- int pass;
-#endif /* NET_21 */
- int error;
- uint32_t eroute_pid;
- struct ipsec_sa ips;
-#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
- uint8_t natt_type;
- uint8_t natt_head;
- uint16_t natt_sport;
- uint16_t natt_dport;
-#endif
-};
-
-#if 0 /* save for alg refactorisation */
-struct xform_functions
-{
- enum ipsec_xmit_value (*checks)(struct ipsec_xmit_state *ixs,
- struct sk_buff *skb);
- enum ipsec_xmit_value (*encrypt)(struct ipsec_xmit_state *ixs);
-
- enum ipsec_xmit_value (*setup_auth)(struct ipsec_xmit_state *ixs,
- struct sk_buff *skb,
- __u32 *replay,
- unsigned char **authenticator);
- enum ipsec_xmit_value (*calc_auth)(struct ipsec_xmit_state *ixs,
- struct sk_buff *skb);
-};
-#endif
-
-enum ipsec_xmit_value
-ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
-
-enum ipsec_xmit_value
-ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
-
-enum ipsec_xmit_value
-ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
-
-extern int ipsec_xmit_trap_count;
-extern int ipsec_xmit_trap_sendcount;
-
-extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
diff --git a/src/libfreeswan/keyblobtoid.3 b/src/libfreeswan/keyblobtoid.3
index e33603bb0..8b5bfb0a2 100644
--- a/src/libfreeswan/keyblobtoid.3
+++ b/src/libfreeswan/keyblobtoid.3
@@ -1,5 +1,4 @@
.TH IPSEC_KEYBLOBTOID 3 "25 March 2002"
-.\" RCSID $Id: keyblobtoid.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec keyblobtoid, splitkeytoid \- generate key IDs from RSA keys
.SH SYNOPSIS
diff --git a/src/libfreeswan/keyblobtoid.c b/src/libfreeswan/keyblobtoid.c
index f8c47a55c..118e61391 100644
--- a/src/libfreeswan/keyblobtoid.c
+++ b/src/libfreeswan/keyblobtoid.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: keyblobtoid.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/optionsfrom.3 b/src/libfreeswan/optionsfrom.3
deleted file mode 100644
index 717d280f0..000000000
--- a/src/libfreeswan/optionsfrom.3
+++ /dev/null
@@ -1,182 +0,0 @@
-.TH IPSEC_OPTIONSFROM 3 "16 Oct 1998"
-.\" RCSID $Id: optionsfrom.3 3265 2007-10-08 19:52:55Z andreas $
-.SH NAME
-ipsec optionsfrom \- read additional ``command-line'' options from file
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *optionsfrom(char *filename, int *argcp,"
-.ti +1c
-.B "char ***argvp, int optind, FILE *errsto);"
-.SH DESCRIPTION
-.I Optionsfrom
-is called from within a
-.IR getopt_long (3)
-scan,
-as the result of the appearance of an option (preferably
-.BR \-\-optionsfrom )
-to insert additional ``command-line'' arguments
-into the scan immediately after
-the option.
-Typically this would be done to pick up options which are
-security-sensitive and should not be visible to
-.IR ps (1)
-and similar commands,
-and hence cannot be supplied as part
-of the actual command line or the environment.
-.PP
-.I Optionsfrom
-reads the additional arguments from the specified
-.IR filename ,
-allocates a new argument vector to hold pointers to the existing
-arguments plus the new ones,
-and amends
-.I argc
-and
-.I argv
-(via the pointers
-.I argcp
-and
-.IR argvp ,
-which must point to the
-.I argc
-and
-.I argv
-being supplied to
-.IR getopt_long (3))
-accordingly.
-.I Optind
-must be the index, in the original argument vector,
-of the next argument.
-.PP
-If
-.I errsto
-is NULL,
-.I optionsfrom
-returns NULL for success and
-a pointer to a string-literal error message for failure;
-see DIAGNOSTICS.
-If
-.I errsto
-is non-NULL and an error occurs,
-.I optionsfrom
-prints a suitable complaint onto the
-.I errsto
-descriptor and invokes
-.I exit
-with an exit status of 2;
-this is a convenience for cases where more sophisticated
-responses are not required.
-.PP
-The text of existing arguments is not disturbed by
-.IR optionsfrom ,
-so pointers to them and into them remain valid.
-.PP
-The file of additional arguments is an ASCII text file.
-Lines consisting solely of white space,
-and lines beginning with
-.BR # ,
-are comments and are ignored.
-Otherwise, a line which does not begin with
-.BR \-
-is taken to be a single argument;
-if it both begins and ends with double-quote ("),
-those quotes are stripped off (note, no other processing is done within
-the line!).
-A line beginning with
-.B \-
-is considered to contain multiple arguments separated by white space.
-.PP
-Because
-.I optionsfrom
-reads its entire file before the
-.IR getopt_long (3)
-scan is resumed, an
-.I optionsfrom
-file can contain another
-.B \-\-optionsfrom
-option.
-Obviously, infinite loops are possible here.
-If
-.I errsto
-is non-NULL,
-.I optionsfrom
-considers it an error to be called more than 100 times.
-If
-.I errsto
-is NULL,
-loop detection is up to the caller
-(and the internal loop counter is zeroed out).
-.SH EXAMPLE
-A reasonable way to invoke
-.I optionsfrom
-would be like so:
-.PP
-.nf
-.ft B
-#include <getopt.h>
-
-struct option opts[] = {
- /* ... */
- "optionsfrom", 1, NULL, '+',
- /* ... */
-};
-
-int
-main(argc, argv)
-int argc;
-char *argv[];
-{
- int opt;
- extern char *optarg;
- extern int optind;
-
- while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
- switch (opt) {
- /* ... */
- case '+': /* optionsfrom */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- break;
- /* ... */
- }
- /* ... */
-.ft
-.fi
-.SH SEE ALSO
-getopt_long(3)
-.SH DIAGNOSTICS
-Errors in
-.I optionsfrom
-are:
-unable to open file;
-attempt to allocate temporary storage for argument or
-argument vector failed;
-read error in file;
-line too long.
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
-.SH BUGS
-The double-quote convention is rather simplistic.
-.PP
-Line length is currently limited to 1023 bytes,
-and there is no continuation convention.
-.PP
-The restriction of error reports to literal strings
-(so that callers don't need to worry about freeing them or copying them)
-does limit the precision of error reporting.
-.PP
-The error-reporting convention lends itself
-to slightly obscure code,
-because many readers will not think of NULL as signifying success.
-.PP
-There is a certain element of unwarranted chumminess with
-the insides of
-.IR getopt_long (3)
-here.
-No non-public interfaces are actually used, but
-.IR optionsfrom
-does rely on
-.IR getopt_long (3)
-being well-behaved in certain ways that are not actually
-promised by the specs.
diff --git a/src/libfreeswan/optionsfrom.c b/src/libfreeswan/optionsfrom.c
deleted file mode 100644
index f4878f386..000000000
--- a/src/libfreeswan/optionsfrom.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * pick up more options from a file, in the middle of an option scan
- * Copyright (C) 1998, 1999 Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- *
- * RCSID $Id: optionsfrom.c 3265 2007-10-08 19:52:55Z andreas $
- */
-#include "internal.h"
-#include "freeswan.h"
-
-#include <stdio.h>
-
-#define MAX 100 /* loop-detection limit */
-
-/* internal work area */
-struct work {
-# define LOTS 1024
- char buf[LOTS];
- char *line;
- char *pending;
-};
-
-static const char *dowork(const char *, int *, char ***, int);
-static const char *getanarg(FILE *, struct work *, char **);
-static char *getline(FILE *, char *, size_t);
-
-/*
- - optionsfrom - add some options, taken from a file, to argc/argv
- * If errsto is non-NULL, does not return in event of error.
- */
-const char * /* NULL for success, else string literal */
-optionsfrom(filename, argcp, argvp, optind, errsto)
-const char *filename;
-int *argcp; /* pointer to argc */
-char ***argvp; /* pointer to argv */
-int optind; /* current optind, number of next argument */
-FILE *errsto; /* where to report errors (NULL means return) */
-{
- const char *e;
- static int nuses = 0;
-
- if (errsto != NULL) {
- nuses++;
- if (nuses >= MAX) {
- fprintf(errsto,
- "%s: optionsfrom called %d times, looping?\n",
- (*argvp)[0], nuses);
- exit(2);
- }
- } else
- nuses = 0;
-
- e = dowork(filename, argcp, argvp, optind);
- if (e != NULL && errsto != NULL) {
- fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e);
- exit(2);
- }
- return e;
-}
-
-/*
- - dowork - do all the real work of optionsfrom
- * Does not alter the existing arguments, but does relocate and alter
- * the argv pointer vector.
- */
-static const char * /* NULL for success, else string literal */
-dowork(filename, argcp, argvp, optind)
-const char *filename;
-int *argcp; /* pointer to argc */
-char ***argvp; /* pointer to argv */
-int optind; /* current optind, number of next argument */
-{
- char **newargv;
- char **tmp;
- int newargc;
- int next; /* place for next argument */
- int room; /* how many more new arguments we can hold */
-# define SOME 10 /* first guess at how many we'll need */
- FILE *f;
- int i;
- const char *p;
- struct work wa; /* for getanarg() */
-
- f = fopen(filename, "r");
- if (f == NULL)
- return "unable to open file";
-
- newargc = *argcp + SOME;
- newargv = malloc((newargc+1) * sizeof(char *));
- if (newargv == NULL)
- return "unable to allocate memory";
- memcpy(newargv, *argvp, optind * sizeof(char *));
- room = SOME;
- next = optind;
-
- newargv[next] = NULL;
- wa.pending = NULL;
- while ((p = getanarg(f, &wa, &newargv[next])) == NULL) {
- if (room == 0) {
- newargc += SOME;
- tmp = realloc(newargv, (newargc+1) * sizeof(char *));
- if (tmp == NULL) {
- p = "out of space for new argv";
- break; /* NOTE BREAK OUT */
- }
- newargv = tmp;
- room += SOME;
- }
- next++;
- room--;
- }
- if (p != NULL && !feof(f)) { /* error of some kind */
- for (i = optind+1; i <= next; i++)
- if (newargv[i] != NULL)
- free(newargv[i]);
- free(newargv);
- fclose(f);
- return p;
- }
-
- fclose(f);
- memcpy(newargv + next, *argvp + optind,
- (*argcp+1-optind) * sizeof(char *));
- *argcp += next - optind;
- *argvp = newargv;
- return NULL;
-}
-
-/*
- - getanarg - get a malloced argument from the file
- */
-static const char * /* NULL for success, else string literal */
-getanarg(f, w, linep)
-FILE *f;
-struct work *w;
-char **linep; /* where to store pointer if successful */
-{
- size_t len;
- char *p;
- char *endp;
-
- while (w->pending == NULL) { /* no pending line */
- if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL)
- return "error in line read"; /* caller checks EOF */
- if (w->line[0] != '#' &&
- *(w->line + strspn(w->line, " \t")) != '\0')
- w->pending = w->line;
- }
-
- if (w->pending == w->line && w->line[0] != '-') {
- /* fresh plain line */
- w->pending = NULL;
- p = w->line;
- endp = p + strlen(p);
- if (*p == '"' && endp > p+1 && *(endp-1) == '"') {
- p++;
- endp--;
- *endp = '\0';
- }
- if (w->line == w->buf) {
- *linep = malloc(endp - p + 1);
- if (*linep == NULL)
- return "out of memory for new line";
- strcpy(*linep, p);
- } else /* getline already malloced it */
- *linep = p;
- return NULL;
- }
-
- /* chip off a piece of a pending line */
- p = w->pending;
- p += strspn(p, " \t");
- endp = p + strcspn(p, " \t");
- len = endp - p;
- if (*endp != '\0') {
- *endp++ = '\0';
- endp += strspn(endp, " \t");
- }
- /* endp now points to next real character, or to line-end NUL */
- *linep = malloc(len + 1);
- if (*linep == NULL) {
- if (w->line != w->buf)
- free(w->line);
- return "out of memory for new argument";
- }
- strcpy(*linep, p);
- if (*endp == '\0') {
- w->pending = NULL;
- if (w->line != w->buf)
- free(w->line);
- } else
- w->pending = endp;
- return NULL;
-}
-
-/*
- - getline - read a line from the file, trim newline off
- */
-static char * /* pointer to line, NULL for eof/error */
-getline(f, buf, bufsize)
-FILE *f;
-char *buf; /* buffer to use, if convenient */
-size_t bufsize; /* size of buf */
-{
- size_t len;
-
- if (fgets(buf, bufsize, f) == NULL)
- return NULL;
- len = strlen(buf);
-
- if (len < bufsize-1 || buf[bufsize-1] == '\n') {
- /* it fit */
- buf[len-1] = '\0';
- return buf;
- }
-
- /* oh crud, buffer overflow */
- /* for now, to hell with it */
- return NULL;
-}
-
-
-
-#ifdef TEST
-
-#include <getopt.h>
-
-char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";
-struct option opts[] = {
- "foo", 0, NULL, 'f',
- "bar", 0, NULL, 'b',
- "builtin", 0, NULL, 'B',
- "optionsfrom", 1, NULL, '+',
- "help", 0, NULL, 'h',
- "version", 0, NULL, 'v',
- 0, 0, NULL, 0,
-};
-
-int
-main(argc, argv)
-int argc;
-char *argv[];
-{
- int opt;
- extern char *optarg;
- extern int optind;
- int errflg = 0;
- const char *p;
- int i;
- FILE *errs = NULL;
-
- while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
- switch (opt) {
- case 'f':
- case 'b':
- break;
- case 'B':
- errs = stderr;
- break;
- case '+': /* optionsfrom */
- p = optionsfrom(optarg, &argc, &argv, optind, errs);
- if (p != NULL) {
- fprintf(stderr, "%s: optionsfrom error: %s\n",
- argv[0], p);
- exit(1);
- }
- break;
- case 'h': /* help */
- printf("%s\n", usage);
- exit(0);
- break;
- case 'v': /* version */
- printf("1\n");
- exit(0);
- break;
- case '?':
- default:
- errflg = 1;
- break;
- }
- if (errflg) {
- fprintf(stderr, "%s\n", usage);
- exit(2);
- }
-
- for (i = 1; i < argc; i++)
- printf("%d: `%s'\n", i, argv[i]);
- exit(0);
-}
-
-
-#endif /* TEST */
diff --git a/src/libfreeswan/pfkey.h b/src/libfreeswan/pfkey.h
index 8c657ff51..ba0010bc7 100644
--- a/src/libfreeswan/pfkey.h
+++ b/src/libfreeswan/pfkey.h
@@ -11,128 +11,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pfkey.h 3265 2007-10-08 19:52:55Z andreas $
*/
#ifndef __NET_IPSEC_PF_KEY_H
#define __NET_IPSEC_PF_KEY_H
-#ifdef __KERNEL__
-extern struct proto_ops pfkey_proto_ops;
-typedef struct sock pfkey_sock;
-extern int debug_pfkey;
-
-extern /* void */ int pfkey_init(void);
-extern /* void */ int pfkey_cleanup(void);
-
-extern struct sock *pfkey_sock_list;
-struct socket_list
-{
- struct socket *socketp;
- struct socket_list *next;
-};
-extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
-extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
-extern struct socket_list *pfkey_open_sockets;
-extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
-
-/*
- * There is a field-by-field copy in klips/net/ipsec/ipsec_alg.h
- * please keep in sync until we migrate all support stuff
- * to ipsec_alg objects
- */
-struct supported
-{
- uint16_t supported_alg_exttype;
- uint8_t supported_alg_id;
- uint8_t supported_alg_ivlen;
- uint16_t supported_alg_minbits;
- uint16_t supported_alg_maxbits;
-};
-extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
-struct supported_list
-{
- struct supported *supportedp;
- struct supported_list *next;
-};
-extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
-extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
-
-struct sockaddr_key
-{
- uint16_t key_family; /* PF_KEY */
- uint16_t key_pad; /* not used */
- uint32_t key_pid; /* process ID */
-};
-
-struct pfkey_extracted_data
-{
- struct ipsec_sa* ips;
- struct ipsec_sa* ips2;
- struct eroute *eroute;
-};
-
-extern int
-pfkey_alloc_eroute(struct eroute** eroute);
-
-extern int
-pfkey_sa_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_address_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_key_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_ident_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_sens_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_prop_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_supported_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_spirange_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int
-pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
- struct pfkey_extracted_data* extr);
-
-extern int pfkey_register_reply(int satype, struct sadb_msg *);
-extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
-extern int pfkey_expire(struct ipsec_sa *, int);
-extern int pfkey_acquire(struct ipsec_sa *);
-#else /* ! __KERNEL__ */
extern void (*pfkey_debug_func)(const char *message, ...);
-#endif /* __KERNEL__ */
-
extern uint8_t satype2proto(uint8_t satype);
extern uint8_t proto2satype(uint8_t proto);
extern char* satype2name(uint8_t satype);
@@ -242,12 +127,6 @@ pfkey_ident_build(struct sadb_ext** pfkey_ext,
uint8_t ident_len,
char* ident_string);
-#ifdef __KERNEL__
-extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
-extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-#endif /* __KERNEL__ */
-
int
pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
uint8_t type);
diff --git a/src/libfreeswan/pfkey_v2_build.c b/src/libfreeswan/pfkey_v2_build.c
index 45a8a8e71..ddc21040f 100644
--- a/src/libfreeswan/pfkey_v2_build.c
+++ b/src/libfreeswan/pfkey_v2_build.c
@@ -11,51 +11,18 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pfkey_v2_build.c 3265 2007-10-08 19:52:55Z andreas $
*/
/*
* Template from klips/net/ipsec/ipsec/ipsec_parser.c.
*/
-char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c 3265 2007-10-08 19:52:55Z andreas $";
-
-/*
- * Some ugly stuff to allow consistent debugging code for use in the
- * kernel and in user space
-*/
-
-#ifdef __KERNEL__
-
-# include <linux/kernel.h> /* for printk */
-
-# include "freeswan/ipsec_kversion.h" /* for malloc switch */
-# ifdef MALLOC_SLAB
-# include <linux/slab.h> /* kmalloc() */
-# else /* MALLOC_SLAB */
-# include <linux/malloc.h> /* kmalloc() */
-# endif /* MALLOC_SLAB */
-# include <linux/errno.h> /* error codes */
-# include <linux/types.h> /* size_t */
-# include <linux/interrupt.h> /* mark_bh */
-
-# include <linux/netdevice.h> /* struct device, and other headers */
-# include <linux/etherdevice.h> /* eth_type_trans */
-# include <linux/ip.h> /* struct iphdr */
-# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-# include <linux/ipv6.h> /* struct ipv6hdr */
-# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-
-# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
-# define FREE(obj) kfree(obj)
-# include <freeswan.h>
-#else /* __KERNEL__ */
+char pfkey_v2_build_c_version[] = "";
# include <sys/types.h>
-# include <linux/types.h>
-# include <linux/errno.h>
-# include <malloc.h>
+# include <sys/socket.h>
+# include <stdlib.h>
+# include <errno.h>
# include <string.h> /* memset */
# include <freeswan.h>
@@ -63,8 +30,6 @@ unsigned int pfkey_lib_debug = 0;
void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-/* #define PLUTO */
-
#define DEBUGGING(args...) if(pfkey_lib_debug) { \
if(pfkey_debug_func != NULL) { \
(*pfkey_debug_func)("pfkey_lib_debug:" args); \
@@ -73,22 +38,10 @@ void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
} }
# define MALLOC(size) malloc(size)
# define FREE(obj) free(obj)
-#endif /* __KERNEL__ */
#include <pfkeyv2.h>
#include <pfkey.h>
-#ifdef __KERNEL__
-
-#include "freeswan/radij.h" /* rd_nodes */
-#include "freeswan/ipsec_encap.h" /* sockaddr_encap */
-
-# define DEBUGGING(args...) \
- KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
-#endif /* __KERNEL__ */
-
-#include "ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
void
@@ -483,14 +436,14 @@ pfkey_address_build(struct sadb_ext** pfkey_ext,
"found address family AF_INET6.\n");
saddr_len = sizeof(struct sockaddr_in6);
sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
- , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[0])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[1])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[2])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[3])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[4])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[5])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[6])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr[7])
, ntohs(((struct sockaddr_in6*)address)->sin6_port));
break;
default:
diff --git a/src/libfreeswan/pfkey_v2_debug.c b/src/libfreeswan/pfkey_v2_debug.c
index 35e4f75f1..0256e2a03 100644
--- a/src/libfreeswan/pfkey_v2_debug.c
+++ b/src/libfreeswan/pfkey_v2_debug.c
@@ -13,36 +13,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pfkey_v2_debug.c 3265 2007-10-08 19:52:55Z andreas $
- *
*/
-#ifdef __KERNEL__
-
-# include <linux/kernel.h> /* for printk */
-
-# include "freeswan/ipsec_kversion.h" /* for malloc switch */
-# ifdef MALLOC_SLAB
-# include <linux/slab.h> /* kmalloc() */
-# else /* MALLOC_SLAB */
-# include <linux/malloc.h> /* kmalloc() */
-# endif /* MALLOC_SLAB */
-# include <linux/errno.h> /* error codes */
-# include <linux/types.h> /* size_t */
-# include <linux/interrupt.h> /* mark_bh */
-
-# include <linux/netdevice.h> /* struct device, and other headers */
-# include <linux/etherdevice.h> /* eth_type_trans */
-extern int debug_pfkey;
-
-#else /* __KERNEL__ */
-
# include <sys/types.h>
-# include <linux/types.h>
-# include <linux/errno.h>
-
-#endif /* __KERNEL__ */
+# include <errno.h>
#include "freeswan.h"
#include "pfkeyv2.h"
diff --git a/src/libfreeswan/pfkey_v2_ext_bits.c b/src/libfreeswan/pfkey_v2_ext_bits.c
index d6f31def4..b6ef4496d 100644
--- a/src/libfreeswan/pfkey_v2_ext_bits.c
+++ b/src/libfreeswan/pfkey_v2_ext_bits.c
@@ -11,48 +11,16 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pfkey_v2_ext_bits.c 3265 2007-10-08 19:52:55Z andreas $
*/
/*
* Template from klips/net/ipsec/ipsec/ipsec_parse.c.
*/
-char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c 3265 2007-10-08 19:52:55Z andreas $";
-
-/*
- * Some ugly stuff to allow consistent debugging code for use in the
- * kernel and in user space
-*/
-
-#ifdef __KERNEL__
-
-# include <linux/kernel.h> /* for printk */
-
-# include "freeswan/ipsec_kversion.h" /* for malloc switch */
-# ifdef MALLOC_SLAB
-# include <linux/slab.h> /* kmalloc() */
-# else /* MALLOC_SLAB */
-# include <linux/malloc.h> /* kmalloc() */
-# endif /* MALLOC_SLAB */
-# include <linux/errno.h> /* error codes */
-# include <linux/types.h> /* size_t */
-# include <linux/interrupt.h> /* mark_bh */
-
-# include <linux/netdevice.h> /* struct device, and other headers */
-# include <linux/etherdevice.h> /* eth_type_trans */
-# include <linux/ip.h> /* struct iphdr */
-# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-# include <linux/ipv6.h>
-# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-
-#else /* __KERNEL__ */
+char pfkey_v2_ext_bits_c_version[] = "";
# include <sys/types.h>
-# include <linux/types.h>
-# include <linux/errno.h>
-#endif
+# include <errno.h>
#include <freeswan.h>
#include <pfkeyv2.h>
diff --git a/src/libfreeswan/pfkey_v2_parse.c b/src/libfreeswan/pfkey_v2_parse.c
index e365d10b6..7ee08978c 100644
--- a/src/libfreeswan/pfkey_v2_parse.c
+++ b/src/libfreeswan/pfkey_v2_parse.c
@@ -11,83 +11,32 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pfkey_v2_parse.c 3265 2007-10-08 19:52:55Z andreas $
*/
/*
* Template from klips/net/ipsec/ipsec/ipsec_parser.c.
*/
-char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c 3265 2007-10-08 19:52:55Z andreas $";
-
-/*
- * Some ugly stuff to allow consistent debugging code for use in the
- * kernel and in user space
-*/
-
-#ifdef __KERNEL__
-
-# include <linux/kernel.h> /* for printk */
-
-#include "freeswan/ipsec_kversion.h" /* for malloc switch */
-
-# ifdef MALLOC_SLAB
-# include <linux/slab.h> /* kmalloc() */
-# else /* MALLOC_SLAB */
-# include <linux/malloc.h> /* kmalloc() */
-# endif /* MALLOC_SLAB */
-# include <linux/errno.h> /* error codes */
-# include <linux/types.h> /* size_t */
-# include <linux/interrupt.h> /* mark_bh */
-
-# include <linux/netdevice.h> /* struct device, and other headers */
-# include <linux/etherdevice.h> /* eth_type_trans */
-# include <linux/ip.h> /* struct iphdr */
-# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-# include <linux/ipv6.h> /* struct ipv6hdr */
-# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-extern int debug_pfkey;
-
-#include "freeswan.h"
-
-#include "ipsec_encap.h"
-
-#else /* __KERNEL__ */
+char pfkey_v2_parse_c_version[] = "";
# include <sys/types.h>
-# include <linux/types.h>
-# include <linux/errno.h>
+# include <sys/socket.h>
+# include <errno.h>
# include <freeswan.h>
# include <constants.h>
# include <defs.h> /* for PRINTF_LIKE */
# include <log.h> /* for debugging and DBG_log */
-/* #define PLUTO */
-
# ifdef PLUTO
# define DEBUGGING(level, args...) { DBG_log("pfkey_lib_debug:" args); }
# else
# define DEBUGGING(level, args...) if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; }
# endif
-#endif /* __KERNEL__ */
-
-
#include <pfkeyv2.h>
#include <pfkey.h>
-#ifdef __KERNEL__
-extern int sysctl_ipsec_debug_verbose;
-# define DEBUGGING(level, args...) \
- KLIPS_PRINT( \
- ((debug_pfkey & level & (PF_KEY_DEBUG_PARSE_STRUCT | PF_KEY_DEBUG_PARSE_PROBLEM)) \
- || (sysctl_ipsec_debug_verbose && (debug_pfkey & level & PF_KEY_DEBUG_PARSE_FLOW))) \
- , "klips_debug:" args)
-#endif /* __KERNEL__ */
-#include "ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
@@ -96,21 +45,11 @@ struct satype_tbl {
uint8_t satype;
char* name;
} static satype_tbl[] = {
-#ifdef __KERNEL__
- { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
- { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
- { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
-#ifdef CONFIG_IPSEC_IPCOMP
- { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
-#endif /* CONFIG_IPSEC_IPCOMP */
- { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
-#else /* __KERNEL__ */
{ SA_ESP, SADB_SATYPE_ESP, "ESP" },
{ SA_AH, SADB_SATYPE_AH, "AH" },
{ SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
{ SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
{ SA_INT, SADB_X_SATYPE_INT, "INT" },
-#endif /* __KERNEL__ */
{ 0, 0, "UNKNOWN" }
};
@@ -418,14 +357,14 @@ pfkey_address_parse(struct sadb_ext *pfkey_ext)
case AF_INET6:
saddr_len = sizeof(struct sockaddr_in6);
sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
- , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[0])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[1])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[2])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[3])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[4])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[5])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[6])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr[7]));
DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
"pfkey_address_parse: "
"found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
diff --git a/src/libfreeswan/pfkeyv2.h b/src/libfreeswan/pfkeyv2.h
index 1ea1265d3..5ef5e747c 100644
--- a/src/libfreeswan/pfkeyv2.h
+++ b/src/libfreeswan/pfkeyv2.h
@@ -1,8 +1,4 @@
/*
- * RCSID $Id: pfkeyv2.h 3846 2008-04-18 17:01:45Z andreas $
- */
-
-/*
RFC 2367 PF_KEY Key Management API July 1998
diff --git a/src/libfreeswan/portof.3 b/src/libfreeswan/portof.3
index ffa2c0125..112def560 100644
--- a/src/libfreeswan/portof.3
+++ b/src/libfreeswan/portof.3
@@ -1,5 +1,4 @@
.TH IPSEC_PORTOF 3 "8 Sept 2000"
-.\" RCSID $Id: portof.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec portof \- get port field of an ip_address
.br
diff --git a/src/libfreeswan/portof.c b/src/libfreeswan/portof.c
index 96d32acf2..6d06473ad 100644
--- a/src/libfreeswan/portof.c
+++ b/src/libfreeswan/portof.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: portof.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/prng.3 b/src/libfreeswan/prng.3
index 9d0130c0f..48c6ceed0 100644
--- a/src/libfreeswan/prng.3
+++ b/src/libfreeswan/prng.3
@@ -1,5 +1,4 @@
.TH IPSEC_PRNG 3 "1 April 2002"
-.\" RCSID $Id: prng.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec prng_init \- initialize IPsec pseudorandom-number generator
.br
diff --git a/src/libfreeswan/prng.c b/src/libfreeswan/prng.c
index cdf9eb0ed..6cb84e484 100644
--- a/src/libfreeswan/prng.c
+++ b/src/libfreeswan/prng.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: prng.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/radij.h b/src/libfreeswan/radij.h
deleted file mode 100644
index 2396020f7..000000000
--- a/src/libfreeswan/radij.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * RCSID $Id: radij.h 3265 2007-10-08 19:52:55Z andreas $
- */
-
-/*
- * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
- *
- * Variable and procedure names have been modified so that they don't
- * conflict with the original BSD code, as a small number of modifications
- * have been introduced and we may want to reuse this code in BSD.
- *
- * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
- * chi or a German ch sound (as `doch', not as in `milch'), or even a
- * spanish j as in Juan. It is not as far back in the throat like
- * the corresponding Hebrew sound, nor is it a soft breath like the English h.
- * It has nothing to do with the Dutch ij sound.
- *
- * Here is the appropriate copyright notice:
- */
-
-/*
- * Copyright (c) 1988, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)radix.h 8.1 (Berkeley) 6/10/93
- */
-
-#ifndef _RADIJ_H_
-#define _RADIJ_H_
-
-/*
-#define RJ_DEBUG
-*/
-
-#ifdef __KERNEL__
-
-#ifndef __P
-#ifdef __STDC__
-#define __P(x) x
-#else
-#define __P(x) ()
-#endif
-#endif
-
-/*
- * Radix search tree node layout.
- */
-
-struct radij_node
-{
- struct radij_mask *rj_mklist; /* list of masks contained in subtree */
- struct radij_node *rj_p; /* parent */
- short rj_b; /* bit offset; -1-index(netmask) */
- char rj_bmask; /* node: mask for bit test*/
- u_char rj_flags; /* enumerated next */
-#define RJF_NORMAL 1 /* leaf contains normal route */
-#define RJF_ROOT 2 /* leaf is root leaf for tree */
-#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
- union {
- struct { /* leaf only data: */
- caddr_t rj_Key; /* object of search */
- caddr_t rj_Mask; /* netmask, if present */
- struct radij_node *rj_Dupedkey;
- } rj_leaf;
- struct { /* node only data: */
- int rj_Off; /* where to start compare */
- struct radij_node *rj_L;/* progeny */
- struct radij_node *rj_R;/* progeny */
- }rj_node;
- } rj_u;
-#ifdef RJ_DEBUG
- int rj_info;
- struct radij_node *rj_twin;
- struct radij_node *rj_ybro;
-#endif
-};
-
-#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
-#define rj_key rj_u.rj_leaf.rj_Key
-#define rj_mask rj_u.rj_leaf.rj_Mask
-#define rj_off rj_u.rj_node.rj_Off
-#define rj_l rj_u.rj_node.rj_L
-#define rj_r rj_u.rj_node.rj_R
-
-/*
- * Annotations to tree concerning potential routes applying to subtrees.
- */
-
-extern struct radij_mask {
- short rm_b; /* bit offset; -1-index(netmask) */
- char rm_unused; /* cf. rj_bmask */
- u_char rm_flags; /* cf. rj_flags */
- struct radij_mask *rm_mklist; /* more masks to try */
- caddr_t rm_mask; /* the mask */
- int rm_refs; /* # of references to this struct */
-} *rj_mkfreelist;
-
-#define MKGet(m) {\
- if (rj_mkfreelist) {\
- m = rj_mkfreelist; \
- rj_mkfreelist = (m)->rm_mklist; \
- } else \
- R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
-
-#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
-
-struct radij_node_head {
- struct radij_node *rnh_treetop;
- int rnh_addrsize; /* permit, but not require fixed keys */
- int rnh_pktsize; /* permit, but not require fixed keys */
-#if 0
- struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
- __P((void *v, void *mask,
- struct radij_node_head *head, struct radij_node nodes[]));
-#endif
- int (*rnh_addaddr) /* add based on sockaddr */
- __P((void *v, void *mask,
- struct radij_node_head *head, struct radij_node nodes[]));
- struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
- __P((void *v, void *mask,
- struct radij_node_head *head, struct radij_node nodes[]));
-#if 0
- struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
- __P((void *v, void *mask, struct radij_node_head *head));
-#endif
- int (*rnh_deladdr) /* remove based on sockaddr */
- __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
- struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
- __P((void *v, void *mask, struct radij_node_head *head));
- struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
- __P((void *v, struct radij_node_head *head));
- struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
- __P((void *v, struct radij_node_head *head));
- int (*rnh_walktree) /* traverse tree */
- __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
- struct radij_node rnh_nodes[3]; /* empty tree for common case */
-};
-
-
-#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
-#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
-#define Free(p) kfree((caddr_t)p);
-
-void rj_init __P((void));
-int rj_inithead __P((void **, int));
-int rj_refines __P((void *, void *));
-int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
-struct radij_node
- *rj_addmask __P((void *, int, int)) /* , rgb */ ;
-int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
- struct radij_node [2])) /* , rgb */ ;
-int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
-struct radij_node /* rgb */
- *rj_insert __P((void *, struct radij_node_head *, int *,
- struct radij_node [2])),
- *rj_match __P((void *, struct radij_node_head *)),
- *rj_newpair __P((void *, int, struct radij_node[2])),
- *rj_search __P((void *, struct radij_node *)),
- *rj_search_m __P((void *, struct radij_node *, void *));
-
-void rj_deltree(struct radij_node_head *);
-void rj_delnodes(struct radij_node *);
-void rj_free_mkfreelist(void);
-int radijcleartree(void);
-int radijcleanup(void);
-
-extern struct radij_node_head *mask_rjhead;
-extern int maj_keylen;
-#endif /* __KERNEL__ */
-
-#endif /* _RADIJ_H_ */
diff --git a/src/libfreeswan/rangetoa.c b/src/libfreeswan/rangetoa.c
index 4d1eb204e..c5a7ddfda 100644
--- a/src/libfreeswan/rangetoa.c
+++ b/src/libfreeswan/rangetoa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: rangetoa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/rangetosubnet.3 b/src/libfreeswan/rangetosubnet.3
index 27e765670..100b42bd9 100644
--- a/src/libfreeswan/rangetosubnet.3
+++ b/src/libfreeswan/rangetosubnet.3
@@ -1,5 +1,4 @@
.TH IPSEC_RANGETOSUBNET 3 "8 Sept 2000"
-.\" RCSID $Id: rangetosubnet.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec rangetosubnet \- convert address range to subnet
.SH SYNOPSIS
diff --git a/src/libfreeswan/rangetosubnet.c b/src/libfreeswan/rangetosubnet.c
index f68efa6bf..0defa0739 100644
--- a/src/libfreeswan/rangetosubnet.c
+++ b/src/libfreeswan/rangetosubnet.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: rangetosubnet.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/sameaddr.3 b/src/libfreeswan/sameaddr.3
index dc172029e..62886bf1a 100644
--- a/src/libfreeswan/sameaddr.3
+++ b/src/libfreeswan/sameaddr.3
@@ -1,5 +1,4 @@
.TH IPSEC_ANYADDR 3 "28 Nov 2000"
-.\" RCSID $Id: sameaddr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec sameaddr \- are two addresses the same?
.br
diff --git a/src/libfreeswan/sameaddr.c b/src/libfreeswan/sameaddr.c
index 77f458e50..653b94c30 100644
--- a/src/libfreeswan/sameaddr.c
+++ b/src/libfreeswan/sameaddr.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: sameaddr.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/satoa.c b/src/libfreeswan/satoa.c
index 46ed1a483..fe7fb2ea0 100644
--- a/src/libfreeswan/satoa.c
+++ b/src/libfreeswan/satoa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: satoa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/satot.c b/src/libfreeswan/satot.c
index bb1e6c736..a16d62840 100644
--- a/src/libfreeswan/satot.c
+++ b/src/libfreeswan/satot.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: satot.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/subnetof.3 b/src/libfreeswan/subnetof.3
index 9358256cf..aacc76d2c 100644
--- a/src/libfreeswan/subnetof.3
+++ b/src/libfreeswan/subnetof.3
@@ -1,5 +1,4 @@
.TH IPSEC_SUBNETOF 3 "11 June 2001"
-.\" RCSID $Id: subnetof.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec subnetof \- given Internet address and subnet mask, return subnet number
.br
diff --git a/src/libfreeswan/subnetof.c b/src/libfreeswan/subnetof.c
index 4cc3653f3..55786a2e4 100644
--- a/src/libfreeswan/subnetof.c
+++ b/src/libfreeswan/subnetof.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: subnetof.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/subnettoa.c b/src/libfreeswan/subnettoa.c
index 6fc282de1..e8d98168d 100644
--- a/src/libfreeswan/subnettoa.c
+++ b/src/libfreeswan/subnettoa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: subnettoa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/subnettot.c b/src/libfreeswan/subnettot.c
index 7bdacc1fb..03d2e1e57 100644
--- a/src/libfreeswan/subnettot.c
+++ b/src/libfreeswan/subnettot.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: subnettot.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/subnettypeof.c b/src/libfreeswan/subnettypeof.c
index d2b09fde7..9fa15a7d5 100644
--- a/src/libfreeswan/subnettypeof.c
+++ b/src/libfreeswan/subnettypeof.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: subnettypeof.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ttoaddr.3 b/src/libfreeswan/ttoaddr.3
index a1ede84b3..70671145e 100644
--- a/src/libfreeswan/ttoaddr.3
+++ b/src/libfreeswan/ttoaddr.3
@@ -1,5 +1,4 @@
.TH IPSEC_TTOADDR 3 "28 Sept 2001"
-.\" RCSID $Id: ttoaddr.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec ttoaddr, tnatoaddr, addrtot \- convert Internet addresses to and from text
.br
diff --git a/src/libfreeswan/ttoaddr.c b/src/libfreeswan/ttoaddr.c
index 15e8dfe55..e4ceec863 100644
--- a/src/libfreeswan/ttoaddr.c
+++ b/src/libfreeswan/ttoaddr.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ttoaddr.c 3684 2008-03-28 11:46:30Z martin $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ttodata.3 b/src/libfreeswan/ttodata.3
index 0663407ff..8f4b1ec93 100644
--- a/src/libfreeswan/ttodata.3
+++ b/src/libfreeswan/ttodata.3
@@ -1,5 +1,4 @@
.TH IPSEC_TTODATA 3 "16 August 2003"
-.\" RCSID $Id: ttodata.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec ttodata, datatot \- convert binary data bytes from and to text formats
.SH SYNOPSIS
diff --git a/src/libfreeswan/ttodata.c b/src/libfreeswan/ttodata.c
index 5334ea124..b0d5e4d01 100644
--- a/src/libfreeswan/ttodata.c
+++ b/src/libfreeswan/ttodata.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ttodata.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ttoprotoport.c b/src/libfreeswan/ttoprotoport.c
index d64cfd5ee..c3d033168 100644
--- a/src/libfreeswan/ttoprotoport.c
+++ b/src/libfreeswan/ttoprotoport.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ttoprotoport.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
@@ -28,7 +26,7 @@ char *src; /* input string */
size_t src_len; /* length of input string, use strlen() if 0 */
u_int8_t *proto; /* extracted protocol number */
u_int16_t *port; /* extracted port number if it exists */
-int *has_port_wildcard; /* set if port is %any */
+bool *has_port_wildcard; /* set if port is %any */
{
char *end, *service_name;
char proto_name[16];
diff --git a/src/libfreeswan/ttosa.3 b/src/libfreeswan/ttosa.3
index 3ae041de2..f9ea36a09 100644
--- a/src/libfreeswan/ttosa.3
+++ b/src/libfreeswan/ttosa.3
@@ -1,5 +1,4 @@
.TH IPSEC_TTOSA 3 "26 Nov 2001"
-.\" RCSID $Id: ttosa.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec ttosa, satot \- convert IPsec Security Association IDs to and from text
.br
diff --git a/src/libfreeswan/ttosa.c b/src/libfreeswan/ttosa.c
index 4e6a29f74..20e01b152 100644
--- a/src/libfreeswan/ttosa.c
+++ b/src/libfreeswan/ttosa.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ttosa.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ttosubnet.c b/src/libfreeswan/ttosubnet.c
index 82e569ea1..36c039a96 100644
--- a/src/libfreeswan/ttosubnet.c
+++ b/src/libfreeswan/ttosubnet.c
@@ -11,9 +11,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ttosubnet.c 3265 2007-10-08 19:52:55Z andreas $
*/
+#include <sys/socket.h>
+
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ttoul.3 b/src/libfreeswan/ttoul.3
index 2bd08b4b0..ffd9fb38a 100644
--- a/src/libfreeswan/ttoul.3
+++ b/src/libfreeswan/ttoul.3
@@ -1,5 +1,4 @@
.TH IPSEC_TTOUL 3 "16 Aug 2000"
-.\" RCSID $Id: ttoul.3 3265 2007-10-08 19:52:55Z andreas $
.SH NAME
ipsec ttoul, ultot \- convert unsigned-long numbers to and from text
.SH SYNOPSIS
diff --git a/src/libfreeswan/ttoul.c b/src/libfreeswan/ttoul.c
index 1bd73a702..853a6130c 100644
--- a/src/libfreeswan/ttoul.c
+++ b/src/libfreeswan/ttoul.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ttoul.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ultoa.c b/src/libfreeswan/ultoa.c
index ae7c7e62b..ef45366a1 100644
--- a/src/libfreeswan/ultoa.c
+++ b/src/libfreeswan/ultoa.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ultoa.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/ultot.c b/src/libfreeswan/ultot.c
index 9e1bfa36c..c4f2d7884 100644
--- a/src/libfreeswan/ultot.c
+++ b/src/libfreeswan/ultot.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * RCSID $Id: ultot.c 3265 2007-10-08 19:52:55Z andreas $
*/
#include "internal.h"
#include "freeswan.h"
diff --git a/src/libfreeswan/version.3 b/src/libfreeswan/version.3
deleted file mode 100644
index e43ee8b61..000000000
--- a/src/libfreeswan/version.3
+++ /dev/null
@@ -1,44 +0,0 @@
-.TH IPSEC_VERSION 3 "21 Nov 2001"
-.\" RCSID $Id: version.3 3265 2007-10-08 19:52:55Z andreas $
-.SH NAME
-ipsec ipsec_version_code \- get IPsec version code
-.br
-ipsec ipsec_version_string \- get full IPsec version string
-.br
-ipsec ipsec_copyright_notice \- get IPsec copyright notice
-.SH SYNOPSIS
-.B "#include <freeswan.h>
-.sp
-.B "const char *ipsec_version_code(void);"
-.br
-.B "const char *ipsec_version_string(void);"
-.br
-.B "const char **ipsec_copyright_notice(void);"
-.SH DESCRIPTION
-These functions provide information on version numbering and copyright
-of the Linux FreeS/WAN IPsec implementation.
-.PP
-.I Ipsec_version_code
-returns a pointer to a string constant
-containing the current IPsec version code,
-such as ``1.92'' or ``snap2001Nov19b''.
-.PP
-.I Ipsec_version_string
-returns a pointer to a string constant giving a full version identification,
-consisting of the version code preceded by a prefix identifying the software,
-e.g. ``Linux FreeS/WAN 1.92''.
-.PP
-.I Ipsec_copyright_notice
-returns a pointer to a vector of pointers,
-terminated by a
-.BR NULL ,
-which is the text of a suitable copyright notice.
-Each pointer points to a string constant (possibly empty) which is one line
-of the somewhat-verbose copyright notice.
-The strings are NUL-terminated and do not contain a newline;
-supplying suitable line termination for the output device is
-the caller's responsibility.
-.SH SEE ALSO
-ipsec(8)
-.SH HISTORY
-Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/version.c b/src/libfreeswan/version.c
deleted file mode 100644
index ffd2f5680..000000000
--- a/src/libfreeswan/version.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * return IPsec version information
- * Copyright (C) 2001 Henry Spencer.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
- * License for more details.
- *
- * RCSID $Id: version.c 3265 2007-10-08 19:52:55Z andreas $
- */
-
-#ifdef __KERNEL__
-#include <linux/netdevice.h>
-#endif
-
-#include "freeswan.h"
-
-static const char strongswan_number[] = VERSION;
-static const char strongswan_string[] = "Linux strongSwan " VERSION;
-
-/*
- - ipsec_version_code - return IPsec version number/code, as string
- */
-const char *
-ipsec_version_code()
-{
- return strongswan_number;
-}
-
-/*
- - ipsec_version_string - return full version string
- */
-const char *
-ipsec_version_string()
-{
- return strongswan_string;
-}
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index 1d0f837ef..212b9547d 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -22,12 +22,15 @@ asn1/pem.c asn1/pem.h \
crypto/crypters/crypter.c crypto/crypters/crypter.h \
crypto/hashers/hasher.h crypto/hashers/hasher.c \
crypto/pkcs9.c crypto/pkcs9.h \
+crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords.h \
crypto/prfs/prf.c crypto/prfs/prf.h \
crypto/rngs/rng.c crypto/rngs/rng.h \
crypto/prf_plus.h crypto/prf_plus.c \
crypto/signers/signer.c crypto/signers/signer.h \
-crypto/diffie_hellman.c crypto/diffie_hellman.h \
crypto/crypto_factory.c crypto/crypto_factory.h \
+crypto/crypto_tester.c crypto/crypto_tester.h \
+crypto/diffie_hellman.c crypto/diffie_hellman.h \
+crypto/transform.c crypto/transform.h \
credentials/credential_factory.c credentials/credential_factory.h \
credentials/builder.c credentials/builder.h \
credentials/keys/private_key.c credentials/keys/private_key.h \
@@ -39,8 +42,9 @@ credentials/certificates/ac.h \
credentials/certificates/crl.h credentials/certificates/crl.c \
credentials/certificates/ocsp_request.h \
credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
-fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
database/database.h database/database_factory.h database/database_factory.c \
+fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
+pgp/pgp.c pgp/pgp.h \
utils.h utils.c \
utils/host.c utils/host.h \
utils/identification.c utils/identification.h \
@@ -54,15 +58,17 @@ utils/mutex.c utils/mutex.h \
utils/backtrace.c utils/backtrace.h \
plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h
-libstrongswan_la_LIBADD = -lpthread -ldl
+libstrongswan_la_LIBADD = -lpthread $(DLLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
- -DIPSEC_PLUGINDIR=\"${plugindir}\"
+AM_CFLAGS = \
+-DIPSEC_DIR=\"${ipsecdir}\" \
+-DIPSEC_PLUGINDIR=\"${plugindir}\"
if USE_LEAK_DETECTIVE
AM_CFLAGS += -DLEAK_DETECTIVE
- libstrongswan_la_SOURCES += utils/leak_detective.c utils/leak_detective.h
+ libstrongswan_la_SOURCES += \
+ utils/leak_detective.c utils/leak_detective.h
endif
if USE_LOCK_PROFILER
@@ -78,15 +84,28 @@ if USE_VSTR
libstrongswan_la_LIBADD += -lvstr
endif
-EXTRA_DIST = asn1/oid.txt asn1/oid.pl
-BUILT_SOURCES = asn1/oid.c asn1/oid.h
-MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
+EXTRA_DIST = \
+asn1/oid.txt asn1/oid.pl \
+crypto/proposal/proposal_keywords.txt
+
+BUILT_SOURCES = \
+$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
+$(srcdir)/crypto/proposal/proposal_keywords.c
+
+MAINTAINERCLEANFILES = \
+$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
+$(srcdir)/crypto/proposal/proposal_keywords.c
-asn1/oid.c : asn1/oid.pl asn1/oid.txt
- (cd `dirname $<` && $(PERL) `basename $<`)
+$(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
+ (cd $(srcdir)/asn1/ && $(PERL) oid.pl)
-asn1/oid.h : asn1/oid.pl asn1/oid.txt
- (cd `dirname $<` && $(PERL) `basename $<`)
+$(srcdir)/asn1/oid.h : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
+ (cd $(srcdir)/asn1/ && $(PERL) oid.pl)
+
+$(srcdir)/crypto/proposal/proposal_keywords.c: $(srcdir)/crypto/proposal/proposal_keywords.txt \
+ $(srcdir)/crypto/proposal/proposal_keywords.h
+ $(GPERF) -N proposal_get_token -m 10 -C -G -c -t -D < \
+ $(srcdir)/crypto/proposal/proposal_keywords.txt > $@
# build plugins with their own Makefile
@@ -102,6 +121,10 @@ if USE_DES
SUBDIRS += plugins/des
endif
+if USE_BLOWFISH
+ SUBDIRS += plugins/blowfish
+endif
+
if USE_MD4
SUBDIRS += plugins/md4
endif
@@ -170,10 +193,18 @@ if USE_OPENSSL
SUBDIRS += plugins/openssl
endif
+if USE_GCRYPT
+ SUBDIRS += plugins/gcrypt
+endif
+
if USE_AGENT
SUBDIRS += plugins/agent
endif
+if USE_TEST_VECTORS
+ SUBDIRS += plugins/test_vectors
+endif
+
if USE_INTEGRITY_TEST
SUBDIRS += fips
endif
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index ed13138e4..dd25f0526 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -33,30 +33,35 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@USE_LEAK_DETECTIVE_TRUE@am__append_1 = -DLEAK_DETECTIVE
-@USE_LEAK_DETECTIVE_TRUE@am__append_2 = utils/leak_detective.c utils/leak_detective.h
+@USE_LEAK_DETECTIVE_TRUE@am__append_2 = \
+@USE_LEAK_DETECTIVE_TRUE@ utils/leak_detective.c utils/leak_detective.h
+
@USE_LOCK_PROFILER_TRUE@am__append_3 = -DLOCK_PROFILER
@USE_VSTR_TRUE@am__append_4 = -lvstr
@USE_AES_TRUE@am__append_5 = plugins/aes
@USE_DES_TRUE@am__append_6 = plugins/des
-@USE_MD4_TRUE@am__append_7 = plugins/md4
-@USE_MD5_TRUE@am__append_8 = plugins/md5
-@USE_SHA1_TRUE@am__append_9 = plugins/sha1
-@USE_SHA2_TRUE@am__append_10 = plugins/sha2
-@USE_FIPS_PRF_TRUE@am__append_11 = plugins/fips_prf
-@USE_GMP_TRUE@am__append_12 = plugins/gmp
-@USE_RANDOM_TRUE@am__append_13 = plugins/random
-@USE_HMAC_TRUE@am__append_14 = plugins/hmac
-@USE_XCBC_TRUE@am__append_15 = plugins/xcbc
-@USE_X509_TRUE@am__append_16 = plugins/x509
-@USE_PUBKEY_TRUE@am__append_17 = plugins/pubkey
-@USE_CURL_TRUE@am__append_18 = plugins/curl
-@USE_LDAP_TRUE@am__append_19 = plugins/ldap
-@USE_MYSQL_TRUE@am__append_20 = plugins/mysql
-@USE_SQLITE_TRUE@am__append_21 = plugins/sqlite
-@USE_PADLOCK_TRUE@am__append_22 = plugins/padlock
-@USE_OPENSSL_TRUE@am__append_23 = plugins/openssl
-@USE_AGENT_TRUE@am__append_24 = plugins/agent
-@USE_INTEGRITY_TEST_TRUE@am__append_25 = fips
+@USE_BLOWFISH_TRUE@am__append_7 = plugins/blowfish
+@USE_MD4_TRUE@am__append_8 = plugins/md4
+@USE_MD5_TRUE@am__append_9 = plugins/md5
+@USE_SHA1_TRUE@am__append_10 = plugins/sha1
+@USE_SHA2_TRUE@am__append_11 = plugins/sha2
+@USE_FIPS_PRF_TRUE@am__append_12 = plugins/fips_prf
+@USE_GMP_TRUE@am__append_13 = plugins/gmp
+@USE_RANDOM_TRUE@am__append_14 = plugins/random
+@USE_HMAC_TRUE@am__append_15 = plugins/hmac
+@USE_XCBC_TRUE@am__append_16 = plugins/xcbc
+@USE_X509_TRUE@am__append_17 = plugins/x509
+@USE_PUBKEY_TRUE@am__append_18 = plugins/pubkey
+@USE_CURL_TRUE@am__append_19 = plugins/curl
+@USE_LDAP_TRUE@am__append_20 = plugins/ldap
+@USE_MYSQL_TRUE@am__append_21 = plugins/mysql
+@USE_SQLITE_TRUE@am__append_22 = plugins/sqlite
+@USE_PADLOCK_TRUE@am__append_23 = plugins/padlock
+@USE_OPENSSL_TRUE@am__append_24 = plugins/openssl
+@USE_GCRYPT_TRUE@am__append_25 = plugins/gcrypt
+@USE_AGENT_TRUE@am__append_26 = plugins/agent
+@USE_TEST_VECTORS_TRUE@am__append_27 = plugins/test_vectors
+@USE_INTEGRITY_TEST_TRUE@am__append_28 = fips
subdir = src/libstrongswan
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -75,7 +80,8 @@ am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
-libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
chunk.h debug.c debug.h enum.c enum.h settings.h settings.c \
printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h \
@@ -83,11 +89,14 @@ am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
asn1/pem.c asn1/pem.h crypto/crypters/crypter.c \
crypto/crypters/crypter.h crypto/hashers/hasher.h \
crypto/hashers/hasher.c crypto/pkcs9.c crypto/pkcs9.h \
- crypto/prfs/prf.c crypto/prfs/prf.h crypto/rngs/rng.c \
- crypto/rngs/rng.h crypto/prf_plus.h crypto/prf_plus.c \
- crypto/signers/signer.c crypto/signers/signer.h \
- crypto/diffie_hellman.c crypto/diffie_hellman.h \
- crypto/crypto_factory.c crypto/crypto_factory.h \
+ crypto/proposal/proposal_keywords.c \
+ crypto/proposal/proposal_keywords.h crypto/prfs/prf.c \
+ crypto/prfs/prf.h crypto/rngs/rng.c crypto/rngs/rng.h \
+ crypto/prf_plus.h crypto/prf_plus.c crypto/signers/signer.c \
+ crypto/signers/signer.h crypto/crypto_factory.c \
+ crypto/crypto_factory.h crypto/crypto_tester.c \
+ crypto/crypto_tester.h crypto/diffie_hellman.c \
+ crypto/diffie_hellman.h crypto/transform.c crypto/transform.h \
credentials/credential_factory.c \
credentials/credential_factory.h credentials/builder.c \
credentials/builder.h credentials/keys/private_key.c \
@@ -101,18 +110,19 @@ am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
credentials/certificates/crl.h credentials/certificates/crl.c \
credentials/certificates/ocsp_request.h \
credentials/certificates/ocsp_response.h \
- credentials/certificates/ocsp_response.c fetcher/fetcher.h \
- fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
- database/database.h database/database_factory.h \
- database/database_factory.c utils.h utils.c utils/host.c \
- utils/host.h utils/identification.c utils/identification.h \
- utils/iterator.h utils/lexparser.c utils/lexparser.h \
- utils/linked_list.c utils/linked_list.h utils/hashtable.c \
- utils/hashtable.h utils/enumerator.c utils/enumerator.h \
- utils/optionsfrom.c utils/optionsfrom.h utils/mutex.c \
- utils/mutex.h utils/backtrace.c utils/backtrace.h \
- plugins/plugin_loader.c plugins/plugin_loader.h \
- plugins/plugin.h utils/leak_detective.c utils/leak_detective.h \
+ credentials/certificates/ocsp_response.c database/database.h \
+ database/database_factory.h database/database_factory.c \
+ fetcher/fetcher.h fetcher/fetcher_manager.h \
+ fetcher/fetcher_manager.c pgp/pgp.c pgp/pgp.h utils.h utils.c \
+ utils/host.c utils/host.h utils/identification.c \
+ utils/identification.h utils/iterator.h utils/lexparser.c \
+ utils/lexparser.h utils/linked_list.c utils/linked_list.h \
+ utils/hashtable.c utils/hashtable.h utils/enumerator.c \
+ utils/enumerator.h utils/optionsfrom.c utils/optionsfrom.h \
+ utils/mutex.c utils/mutex.h utils/backtrace.c \
+ utils/backtrace.h plugins/plugin_loader.c \
+ plugins/plugin_loader.h plugins/plugin.h \
+ utils/leak_detective.c utils/leak_detective.h \
fips/fips_canister_start.c fips/fips.c fips/fips.h \
fips/fips_canister_end.c
@USE_LEAK_DETECTIVE_TRUE@am__objects_1 = leak_detective.lo
@@ -120,39 +130,44 @@ am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
@USE_INTEGRITY_TEST_FALSE@ chunk.lo debug.lo enum.lo \
@USE_INTEGRITY_TEST_FALSE@ settings.lo printf_hook.lo asn1.lo \
@USE_INTEGRITY_TEST_FALSE@ asn1_parser.lo oid.lo pem.lo \
-@USE_INTEGRITY_TEST_FALSE@ crypter.lo hasher.lo pkcs9.lo prf.lo \
-@USE_INTEGRITY_TEST_FALSE@ rng.lo prf_plus.lo signer.lo \
-@USE_INTEGRITY_TEST_FALSE@ diffie_hellman.lo crypto_factory.lo \
+@USE_INTEGRITY_TEST_FALSE@ crypter.lo hasher.lo pkcs9.lo \
+@USE_INTEGRITY_TEST_FALSE@ proposal_keywords.lo prf.lo rng.lo \
+@USE_INTEGRITY_TEST_FALSE@ prf_plus.lo signer.lo \
+@USE_INTEGRITY_TEST_FALSE@ crypto_factory.lo crypto_tester.lo \
+@USE_INTEGRITY_TEST_FALSE@ diffie_hellman.lo transform.lo \
@USE_INTEGRITY_TEST_FALSE@ credential_factory.lo builder.lo \
@USE_INTEGRITY_TEST_FALSE@ private_key.lo public_key.lo \
@USE_INTEGRITY_TEST_FALSE@ shared_key.lo certificate.lo x509.lo \
@USE_INTEGRITY_TEST_FALSE@ crl.lo ocsp_response.lo \
-@USE_INTEGRITY_TEST_FALSE@ fetcher_manager.lo \
-@USE_INTEGRITY_TEST_FALSE@ database_factory.lo utils.lo host.lo \
-@USE_INTEGRITY_TEST_FALSE@ identification.lo lexparser.lo \
-@USE_INTEGRITY_TEST_FALSE@ linked_list.lo hashtable.lo \
-@USE_INTEGRITY_TEST_FALSE@ enumerator.lo optionsfrom.lo \
-@USE_INTEGRITY_TEST_FALSE@ mutex.lo backtrace.lo \
+@USE_INTEGRITY_TEST_FALSE@ database_factory.lo \
+@USE_INTEGRITY_TEST_FALSE@ fetcher_manager.lo pgp.lo utils.lo \
+@USE_INTEGRITY_TEST_FALSE@ host.lo identification.lo \
+@USE_INTEGRITY_TEST_FALSE@ lexparser.lo linked_list.lo \
+@USE_INTEGRITY_TEST_FALSE@ hashtable.lo enumerator.lo \
+@USE_INTEGRITY_TEST_FALSE@ optionsfrom.lo mutex.lo backtrace.lo \
@USE_INTEGRITY_TEST_FALSE@ plugin_loader.lo $(am__objects_1)
@USE_INTEGRITY_TEST_TRUE@am_libstrongswan_la_OBJECTS = \
@USE_INTEGRITY_TEST_TRUE@ fips_canister_start.lo fips.lo \
@USE_INTEGRITY_TEST_TRUE@ library.lo chunk.lo debug.lo enum.lo \
@USE_INTEGRITY_TEST_TRUE@ settings.lo printf_hook.lo asn1.lo \
@USE_INTEGRITY_TEST_TRUE@ asn1_parser.lo oid.lo pem.lo \
-@USE_INTEGRITY_TEST_TRUE@ crypter.lo hasher.lo pkcs9.lo prf.lo \
-@USE_INTEGRITY_TEST_TRUE@ rng.lo prf_plus.lo signer.lo \
-@USE_INTEGRITY_TEST_TRUE@ diffie_hellman.lo crypto_factory.lo \
+@USE_INTEGRITY_TEST_TRUE@ crypter.lo hasher.lo pkcs9.lo \
+@USE_INTEGRITY_TEST_TRUE@ proposal_keywords.lo prf.lo rng.lo \
+@USE_INTEGRITY_TEST_TRUE@ prf_plus.lo signer.lo \
+@USE_INTEGRITY_TEST_TRUE@ crypto_factory.lo crypto_tester.lo \
+@USE_INTEGRITY_TEST_TRUE@ diffie_hellman.lo transform.lo \
@USE_INTEGRITY_TEST_TRUE@ credential_factory.lo builder.lo \
@USE_INTEGRITY_TEST_TRUE@ private_key.lo public_key.lo \
@USE_INTEGRITY_TEST_TRUE@ shared_key.lo certificate.lo x509.lo \
@USE_INTEGRITY_TEST_TRUE@ crl.lo ocsp_response.lo \
-@USE_INTEGRITY_TEST_TRUE@ fetcher_manager.lo \
-@USE_INTEGRITY_TEST_TRUE@ database_factory.lo utils.lo host.lo \
-@USE_INTEGRITY_TEST_TRUE@ identification.lo lexparser.lo \
-@USE_INTEGRITY_TEST_TRUE@ linked_list.lo hashtable.lo \
-@USE_INTEGRITY_TEST_TRUE@ enumerator.lo optionsfrom.lo mutex.lo \
-@USE_INTEGRITY_TEST_TRUE@ backtrace.lo plugin_loader.lo \
-@USE_INTEGRITY_TEST_TRUE@ $(am__objects_1) fips_canister_end.lo
+@USE_INTEGRITY_TEST_TRUE@ database_factory.lo \
+@USE_INTEGRITY_TEST_TRUE@ fetcher_manager.lo pgp.lo utils.lo \
+@USE_INTEGRITY_TEST_TRUE@ host.lo identification.lo \
+@USE_INTEGRITY_TEST_TRUE@ lexparser.lo linked_list.lo \
+@USE_INTEGRITY_TEST_TRUE@ hashtable.lo enumerator.lo \
+@USE_INTEGRITY_TEST_TRUE@ optionsfrom.lo mutex.lo backtrace.lo \
+@USE_INTEGRITY_TEST_TRUE@ plugin_loader.lo $(am__objects_1) \
+@USE_INTEGRITY_TEST_TRUE@ fips_canister_end.lo
libstrongswan_la_OBJECTS = $(am_libstrongswan_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -179,12 +194,12 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = . plugins/aes plugins/des plugins/md4 plugins/md5 \
- plugins/sha1 plugins/sha2 plugins/fips_prf plugins/gmp \
- plugins/random plugins/hmac plugins/xcbc plugins/x509 \
- plugins/pubkey plugins/curl plugins/ldap plugins/mysql \
- plugins/sqlite plugins/padlock plugins/openssl plugins/agent \
- fips
+DIST_SUBDIRS = . plugins/aes plugins/des plugins/blowfish plugins/md4 \
+ plugins/md5 plugins/sha1 plugins/sha2 plugins/fips_prf \
+ plugins/gmp plugins/random plugins/hmac plugins/xcbc \
+ plugins/x509 plugins/pubkey plugins/curl plugins/ldap \
+ plugins/mysql plugins/sqlite plugins/padlock plugins/openssl \
+ plugins/gcrypt plugins/agent plugins/test_vectors fips
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -201,6 +216,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -223,6 +239,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -234,6 +253,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -247,6 +267,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -307,6 +329,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -318,6 +341,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -336,15 +360,21 @@ lib_LTLIBRARIES = libstrongswan.la
@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/hashers/hasher.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/pkcs9.c crypto/pkcs9.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/proposal/proposal_keywords.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/proposal/proposal_keywords.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/prfs/prf.c crypto/prfs/prf.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/rngs/rng.c crypto/rngs/rng.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/prf_plus.h crypto/prf_plus.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/signers/signer.h \
-@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \
-@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \
@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.c \
@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_factory.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_tester.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/crypto_tester.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/diffie_hellman.h \
+@USE_INTEGRITY_TEST_FALSE@ crypto/transform.c \
+@USE_INTEGRITY_TEST_FALSE@ crypto/transform.h \
@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.c \
@USE_INTEGRITY_TEST_FALSE@ credentials/credential_factory.h \
@USE_INTEGRITY_TEST_FALSE@ credentials/builder.c \
@@ -365,13 +395,14 @@ lib_LTLIBRARIES = libstrongswan.la
@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_request.h \
@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.h \
@USE_INTEGRITY_TEST_FALSE@ credentials/certificates/ocsp_response.c \
-@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher.h \
-@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.h \
-@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.c \
@USE_INTEGRITY_TEST_FALSE@ database/database.h \
@USE_INTEGRITY_TEST_FALSE@ database/database_factory.h \
-@USE_INTEGRITY_TEST_FALSE@ database/database_factory.c utils.h \
-@USE_INTEGRITY_TEST_FALSE@ utils.c utils/host.c utils/host.h \
+@USE_INTEGRITY_TEST_FALSE@ database/database_factory.c \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher.h \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.h \
+@USE_INTEGRITY_TEST_FALSE@ fetcher/fetcher_manager.c pgp/pgp.c \
+@USE_INTEGRITY_TEST_FALSE@ pgp/pgp.h utils.h utils.c \
+@USE_INTEGRITY_TEST_FALSE@ utils/host.c utils/host.h \
@USE_INTEGRITY_TEST_FALSE@ utils/identification.c \
@USE_INTEGRITY_TEST_FALSE@ utils/identification.h \
@USE_INTEGRITY_TEST_FALSE@ utils/iterator.h utils/lexparser.c \
@@ -402,15 +433,20 @@ lib_LTLIBRARIES = libstrongswan.la
@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/hashers/hasher.c \
@USE_INTEGRITY_TEST_TRUE@ crypto/pkcs9.c crypto/pkcs9.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/proposal/proposal_keywords.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/proposal/proposal_keywords.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/prfs/prf.c crypto/prfs/prf.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/rngs/rng.c crypto/rngs/rng.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/prf_plus.h crypto/prf_plus.c \
@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.c \
@USE_INTEGRITY_TEST_TRUE@ crypto/signers/signer.h \
-@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \
-@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \
@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.c \
@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_factory.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_tester.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/crypto_tester.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.c \
+@USE_INTEGRITY_TEST_TRUE@ crypto/diffie_hellman.h \
+@USE_INTEGRITY_TEST_TRUE@ crypto/transform.c crypto/transform.h \
@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.c \
@USE_INTEGRITY_TEST_TRUE@ credentials/credential_factory.h \
@USE_INTEGRITY_TEST_TRUE@ credentials/builder.c \
@@ -431,13 +467,14 @@ lib_LTLIBRARIES = libstrongswan.la
@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_request.h \
@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.h \
@USE_INTEGRITY_TEST_TRUE@ credentials/certificates/ocsp_response.c \
-@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher.h \
-@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.h \
-@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.c \
@USE_INTEGRITY_TEST_TRUE@ database/database.h \
@USE_INTEGRITY_TEST_TRUE@ database/database_factory.h \
-@USE_INTEGRITY_TEST_TRUE@ database/database_factory.c utils.h \
-@USE_INTEGRITY_TEST_TRUE@ utils.c utils/host.c utils/host.h \
+@USE_INTEGRITY_TEST_TRUE@ database/database_factory.c \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher.h \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.h \
+@USE_INTEGRITY_TEST_TRUE@ fetcher/fetcher_manager.c pgp/pgp.c \
+@USE_INTEGRITY_TEST_TRUE@ pgp/pgp.h utils.h utils.c \
+@USE_INTEGRITY_TEST_TRUE@ utils/host.c utils/host.h \
@USE_INTEGRITY_TEST_TRUE@ utils/identification.c \
@USE_INTEGRITY_TEST_TRUE@ utils/identification.h \
@USE_INTEGRITY_TEST_TRUE@ utils/iterator.h utils/lexparser.c \
@@ -453,14 +490,23 @@ lib_LTLIBRARIES = libstrongswan.la
@USE_INTEGRITY_TEST_TRUE@ plugins/plugin_loader.h \
@USE_INTEGRITY_TEST_TRUE@ plugins/plugin.h $(am__append_2) \
@USE_INTEGRITY_TEST_TRUE@ fips/fips_canister_end.c
-libstrongswan_la_LIBADD = -lpthread -ldl $(am__append_4)
+libstrongswan_la_LIBADD = -lpthread $(DLLIB) $(am__append_4)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_PLUGINDIR=\"${plugindir}\" $(am__append_1) \
$(am__append_3)
-EXTRA_DIST = asn1/oid.txt asn1/oid.pl
-BUILT_SOURCES = asn1/oid.c asn1/oid.h
-MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
+EXTRA_DIST = \
+asn1/oid.txt asn1/oid.pl \
+crypto/proposal/proposal_keywords.txt
+
+BUILT_SOURCES = \
+$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
+$(srcdir)/crypto/proposal/proposal_keywords.c
+
+MAINTAINERCLEANFILES = \
+$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
+$(srcdir)/crypto/proposal/proposal_keywords.c
+
# build plugins with their own Makefile
#######################################
@@ -470,7 +516,8 @@ SUBDIRS = . $(am__append_5) $(am__append_6) $(am__append_7) \
$(am__append_14) $(am__append_15) $(am__append_16) \
$(am__append_17) $(am__append_18) $(am__append_19) \
$(am__append_20) $(am__append_21) $(am__append_22) \
- $(am__append_23) $(am__append_24) $(am__append_25)
+ $(am__append_23) $(am__append_24) $(am__append_25) \
+ $(am__append_26) $(am__append_27) $(am__append_28)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -480,8 +527,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -551,6 +598,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_factory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_tester.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diffie_hellman.Plo@am__quote@
@@ -573,17 +621,20 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs9.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf_plus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf_hook.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_keywords.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x509.Plo@am__quote@
@@ -657,6 +708,13 @@ pkcs9.lo: crypto/pkcs9.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pkcs9.lo `test -f 'crypto/pkcs9.c' || echo '$(srcdir)/'`crypto/pkcs9.c
+proposal_keywords.lo: crypto/proposal/proposal_keywords.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT proposal_keywords.lo -MD -MP -MF $(DEPDIR)/proposal_keywords.Tpo -c -o proposal_keywords.lo `test -f 'crypto/proposal/proposal_keywords.c' || echo '$(srcdir)/'`crypto/proposal/proposal_keywords.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/proposal_keywords.Tpo $(DEPDIR)/proposal_keywords.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/proposal/proposal_keywords.c' object='proposal_keywords.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o proposal_keywords.lo `test -f 'crypto/proposal/proposal_keywords.c' || echo '$(srcdir)/'`crypto/proposal/proposal_keywords.c
+
prf.lo: crypto/prfs/prf.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT prf.lo -MD -MP -MF $(DEPDIR)/prf.Tpo -c -o prf.lo `test -f 'crypto/prfs/prf.c' || echo '$(srcdir)/'`crypto/prfs/prf.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/prf.Tpo $(DEPDIR)/prf.Plo
@@ -685,6 +743,20 @@ signer.lo: crypto/signers/signer.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o signer.lo `test -f 'crypto/signers/signer.c' || echo '$(srcdir)/'`crypto/signers/signer.c
+crypto_factory.lo: crypto/crypto_factory.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_factory.lo -MD -MP -MF $(DEPDIR)/crypto_factory.Tpo -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypto_factory.Tpo $(DEPDIR)/crypto_factory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypto_factory.c' object='crypto_factory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
+
+crypto_tester.lo: crypto/crypto_tester.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_tester.lo -MD -MP -MF $(DEPDIR)/crypto_tester.Tpo -c -o crypto_tester.lo `test -f 'crypto/crypto_tester.c' || echo '$(srcdir)/'`crypto/crypto_tester.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypto_tester.Tpo $(DEPDIR)/crypto_tester.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypto_tester.c' object='crypto_tester.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_tester.lo `test -f 'crypto/crypto_tester.c' || echo '$(srcdir)/'`crypto/crypto_tester.c
+
diffie_hellman.lo: crypto/diffie_hellman.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diffie_hellman.lo -MD -MP -MF $(DEPDIR)/diffie_hellman.Tpo -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/diffie_hellman.Tpo $(DEPDIR)/diffie_hellman.Plo
@@ -692,12 +764,12 @@ diffie_hellman.lo: crypto/diffie_hellman.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o diffie_hellman.lo `test -f 'crypto/diffie_hellman.c' || echo '$(srcdir)/'`crypto/diffie_hellman.c
-crypto_factory.lo: crypto/crypto_factory.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_factory.lo -MD -MP -MF $(DEPDIR)/crypto_factory.Tpo -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/crypto_factory.Tpo $(DEPDIR)/crypto_factory.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/crypto_factory.c' object='crypto_factory.lo' libtool=yes @AMDEPBACKSLASH@
+transform.lo: crypto/transform.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT transform.lo -MD -MP -MF $(DEPDIR)/transform.Tpo -c -o transform.lo `test -f 'crypto/transform.c' || echo '$(srcdir)/'`crypto/transform.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/transform.Tpo $(DEPDIR)/transform.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='crypto/transform.c' object='transform.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_factory.lo `test -f 'crypto/crypto_factory.c' || echo '$(srcdir)/'`crypto/crypto_factory.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o transform.lo `test -f 'crypto/transform.c' || echo '$(srcdir)/'`crypto/transform.c
credential_factory.lo: credentials/credential_factory.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT credential_factory.lo -MD -MP -MF $(DEPDIR)/credential_factory.Tpo -c -o credential_factory.lo `test -f 'credentials/credential_factory.c' || echo '$(srcdir)/'`credentials/credential_factory.c
@@ -762,6 +834,13 @@ ocsp_response.lo: credentials/certificates/ocsp_response.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ocsp_response.lo `test -f 'credentials/certificates/ocsp_response.c' || echo '$(srcdir)/'`credentials/certificates/ocsp_response.c
+database_factory.lo: database/database_factory.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database_factory.lo -MD -MP -MF $(DEPDIR)/database_factory.Tpo -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/database_factory.Tpo $(DEPDIR)/database_factory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='database/database_factory.c' object='database_factory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
+
fetcher_manager.lo: fetcher/fetcher_manager.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fetcher_manager.lo -MD -MP -MF $(DEPDIR)/fetcher_manager.Tpo -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fetcher_manager.Tpo $(DEPDIR)/fetcher_manager.Plo
@@ -769,12 +848,12 @@ fetcher_manager.lo: fetcher/fetcher_manager.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fetcher_manager.lo `test -f 'fetcher/fetcher_manager.c' || echo '$(srcdir)/'`fetcher/fetcher_manager.c
-database_factory.lo: database/database_factory.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database_factory.lo -MD -MP -MF $(DEPDIR)/database_factory.Tpo -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/database_factory.Tpo $(DEPDIR)/database_factory.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='database/database_factory.c' object='database_factory.lo' libtool=yes @AMDEPBACKSLASH@
+pgp.lo: pgp/pgp.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pgp.lo -MD -MP -MF $(DEPDIR)/pgp.Tpo -c -o pgp.lo `test -f 'pgp/pgp.c' || echo '$(srcdir)/'`pgp/pgp.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/pgp.Tpo $(DEPDIR)/pgp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pgp/pgp.c' object='pgp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pgp.lo `test -f 'pgp/pgp.c' || echo '$(srcdir)/'`pgp/pgp.c
host.lo: utils/host.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT host.lo -MD -MP -MF $(DEPDIR)/host.Tpo -c -o host.lo `test -f 'utils/host.c' || echo '$(srcdir)/'`utils/host.c
@@ -955,7 +1034,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -1168,11 +1247,16 @@ uninstall-am: uninstall-libLTLIBRARIES
uninstall-libLTLIBRARIES
-asn1/oid.c : asn1/oid.pl asn1/oid.txt
- (cd `dirname $<` && $(PERL) `basename $<`)
+$(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
+ (cd $(srcdir)/asn1/ && $(PERL) oid.pl)
+
+$(srcdir)/asn1/oid.h : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
+ (cd $(srcdir)/asn1/ && $(PERL) oid.pl)
-asn1/oid.h : asn1/oid.pl asn1/oid.txt
- (cd `dirname $<` && $(PERL) `basename $<`)
+$(srcdir)/crypto/proposal/proposal_keywords.c: $(srcdir)/crypto/proposal/proposal_keywords.txt \
+ $(srcdir)/crypto/proposal/proposal_keywords.h
+ $(GPERF) -N proposal_get_token -m 10 -C -G -c -t -D < \
+ $(srcdir)/crypto/proposal/proposal_keywords.txt > $@
# 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/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h
index 4ea89730c..6a2b594c0 100644
--- a/src/libstrongswan/asn1/asn1.h
+++ b/src/libstrongswan/asn1/asn1.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: asn1.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -27,7 +25,8 @@
#include <stdarg.h>
-#include <library.h>
+#include <utils.h>
+#include <chunk.h>
/**
* Definition of some primitive ASN1 types
@@ -107,13 +106,21 @@ chunk_t asn1_algorithmIdentifier(int oid);
int asn1_known_oid(chunk_t object);
/**
+ * Converts a known OID index to an ASN.1 OID
+ *
+ * @param n index into the oid_names[] table
+ * @return allocated OID chunk, chunk_empty if index out of range
+ */
+chunk_t asn1_build_known_oid(int n);
+
+/**
* Returns the length of an ASN.1 object
* The blob pointer is advanced past the tag length fields
*
* @param blob pointer to an ASN.1 coded blob
* @return length of ASN.1 object
*/
-u_int asn1_length(chunk_t *blob);
+size_t asn1_length(chunk_t *blob);
/**
* Parses an ASN.1 algorithmIdentifier object
@@ -221,6 +228,15 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
chunk_t asn1_bitstring(const char *mode, chunk_t content);
/**
+ * Build an ASN.1 INTEGER object
+ *
+ * @param mode 'c' for copy or 'm' for move
+ * @param content content of the INTEGER
+ * @return chunk containing the ASN.1 coded INTEGER
+ */
+chunk_t asn1_integer(const char *mode, chunk_t content);
+
+/**
* Build an ASN.1 object from a variable number of individual chunks
*
* @param type ASN.1 type to be created
diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c
index 7ea9ace4f..bc4c0b50f 100644
--- a/src/libstrongswan/asn1/asn1_parser.c
+++ b/src/libstrongswan/asn1/asn1_parser.c
@@ -13,15 +13,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: asn1_parser.c 3894 2008-04-28 18:44:21Z andreas $
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
-#include <library.h>
+#include <utils.h>
#include <debug.h>
#include "asn1.h"
diff --git a/src/libstrongswan/asn1/asn1_parser.h b/src/libstrongswan/asn1/asn1_parser.h
index bcc966e04..b2f4133a1 100644
--- a/src/libstrongswan/asn1/asn1_parser.h
+++ b/src/libstrongswan/asn1/asn1_parser.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: asn1_parser.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -27,7 +25,9 @@
#include <stdarg.h>
-#include <library.h>
+#include <utils.h>
+#include <chunk.h>
+#include <asn1/asn1.h>
/**
* Definition of ASN.1 flags
diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c
index f9eb26d1d..53657b514 100644
--- a/src/libstrongswan/asn1/oid.c
+++ b/src/libstrongswan/asn1/oid.c
@@ -10,270 +10,300 @@
#include "oid.h"
const oid_t oid_names[] = {
- {0x02, 7, 1, "ITU-T Administration" }, /* 0 */
- { 0x82, 0, 1, "" }, /* 1 */
- { 0x06, 0, 1, "Germany ITU-T member" }, /* 2 */
- { 0x01, 0, 1, "Deutsche Telekom AG" }, /* 3 */
- { 0x0A, 0, 1, "" }, /* 4 */
- { 0x07, 0, 1, "" }, /* 5 */
- { 0x14, 0, 0, "ND" }, /* 6 */
- {0x09, 18, 1, "data" }, /* 7 */
- { 0x92, 0, 1, "" }, /* 8 */
- { 0x26, 0, 1, "" }, /* 9 */
- { 0x89, 0, 1, "" }, /* 10 */
- { 0x93, 0, 1, "" }, /* 11 */
- { 0xF2, 0, 1, "" }, /* 12 */
- { 0x2C, 0, 1, "" }, /* 13 */
- { 0x64, 0, 1, "pilot" }, /* 14 */
- { 0x01, 0, 1, "pilotAttributeType" }, /* 15 */
- { 0x01, 17, 0, "UID" }, /* 16 */
- { 0x19, 0, 0, "DC" }, /* 17 */
- {0x55, 52, 1, "X.500" }, /* 18 */
- { 0x04, 36, 1, "X.509" }, /* 19 */
- { 0x03, 21, 0, "CN" }, /* 20 */
- { 0x04, 22, 0, "S" }, /* 21 */
- { 0x05, 23, 0, "SN" }, /* 22 */
- { 0x06, 24, 0, "C" }, /* 23 */
- { 0x07, 25, 0, "L" }, /* 24 */
- { 0x08, 26, 0, "ST" }, /* 25 */
- { 0x0A, 27, 0, "O" }, /* 26 */
- { 0x0B, 28, 0, "OU" }, /* 27 */
- { 0x0C, 29, 0, "T" }, /* 28 */
- { 0x0D, 30, 0, "D" }, /* 29 */
- { 0x24, 31, 0, "userCertificate" }, /* 30 */
- { 0x29, 32, 0, "N" }, /* 31 */
- { 0x2A, 33, 0, "G" }, /* 32 */
- { 0x2B, 34, 0, "I" }, /* 33 */
- { 0x2D, 35, 0, "ID" }, /* 34 */
- { 0x48, 0, 0, "role" }, /* 35 */
- { 0x1D, 0, 1, "id-ce" }, /* 36 */
- { 0x09, 38, 0, "subjectDirectoryAttrs" }, /* 37 */
- { 0x0E, 39, 0, "subjectKeyIdentifier" }, /* 38 */
- { 0x0F, 40, 0, "keyUsage" }, /* 39 */
- { 0x10, 41, 0, "privateKeyUsagePeriod" }, /* 40 */
- { 0x11, 42, 0, "subjectAltName" }, /* 41 */
- { 0x12, 43, 0, "issuerAltName" }, /* 42 */
- { 0x13, 44, 0, "basicConstraints" }, /* 43 */
- { 0x14, 45, 0, "crlNumber" }, /* 44 */
- { 0x15, 46, 0, "reasonCode" }, /* 45 */
- { 0x1F, 47, 0, "crlDistributionPoints" }, /* 46 */
- { 0x20, 48, 0, "certificatePolicies" }, /* 47 */
- { 0x23, 49, 0, "authorityKeyIdentifier" }, /* 48 */
- { 0x25, 50, 0, "extendedKeyUsage" }, /* 49 */
- { 0x37, 51, 0, "targetInformation" }, /* 50 */
- { 0x38, 0, 0, "noRevAvail" }, /* 51 */
- {0x2A, 131, 1, "" }, /* 52 */
- { 0x86, 0, 1, "" }, /* 53 */
- { 0x48, 0, 1, "" }, /* 54 */
- { 0x86, 95, 1, "" }, /* 55 */
- { 0xF6, 61, 1, "" }, /* 56 */
- { 0x7D, 0, 1, "NortelNetworks" }, /* 57 */
- { 0x07, 0, 1, "Entrust" }, /* 58 */
- { 0x41, 0, 1, "nsn-ce" }, /* 59 */
- { 0x00, 0, 0, "entrustVersInfo" }, /* 60 */
- { 0xF7, 0, 1, "" }, /* 61 */
- { 0x0D, 0, 1, "RSADSI" }, /* 62 */
- { 0x01, 90, 1, "PKCS" }, /* 63 */
- { 0x01, 72, 1, "PKCS-1" }, /* 64 */
- { 0x01, 66, 0, "rsaEncryption" }, /* 65 */
- { 0x02, 67, 0, "md2WithRSAEncryption" }, /* 66 */
- { 0x04, 68, 0, "md5WithRSAEncryption" }, /* 67 */
- { 0x05, 69, 0, "sha-1WithRSAEncryption" }, /* 68 */
- { 0x0B, 70, 0, "sha256WithRSAEncryption" }, /* 69 */
- { 0x0C, 71, 0, "sha384WithRSAEncryption" }, /* 70 */
- { 0x0D, 0, 0, "sha512WithRSAEncryption" }, /* 71 */
- { 0x07, 79, 1, "PKCS-7" }, /* 72 */
- { 0x01, 74, 0, "data" }, /* 73 */
- { 0x02, 75, 0, "signedData" }, /* 74 */
- { 0x03, 76, 0, "envelopedData" }, /* 75 */
- { 0x04, 77, 0, "signedAndEnvelopedData" }, /* 76 */
- { 0x05, 78, 0, "digestedData" }, /* 77 */
- { 0x06, 0, 0, "encryptedData" }, /* 78 */
- { 0x09, 0, 1, "PKCS-9" }, /* 79 */
- { 0x01, 81, 0, "E" }, /* 80 */
- { 0x02, 82, 0, "unstructuredName" }, /* 81 */
- { 0x03, 83, 0, "contentType" }, /* 82 */
- { 0x04, 84, 0, "messageDigest" }, /* 83 */
- { 0x05, 85, 0, "signingTime" }, /* 84 */
- { 0x06, 86, 0, "counterSignature" }, /* 85 */
- { 0x07, 87, 0, "challengePassword" }, /* 86 */
- { 0x08, 88, 0, "unstructuredAddress" }, /* 87 */
- { 0x0E, 89, 0, "extensionRequest" }, /* 88 */
- { 0x0F, 0, 0, "S/MIME Capabilities" }, /* 89 */
- { 0x02, 93, 1, "digestAlgorithm" }, /* 90 */
- { 0x02, 92, 0, "md2" }, /* 91 */
- { 0x05, 0, 0, "md5" }, /* 92 */
- { 0x03, 0, 1, "encryptionAlgorithm" }, /* 93 */
- { 0x07, 0, 0, "3des-ede-cbc" }, /* 94 */
- { 0xCE, 0, 1, "" }, /* 95 */
- { 0x3D, 0, 1, "ansi-X9-62" }, /* 96 */
- { 0x02, 99, 1, "id-publicKeyType" }, /* 97 */
- { 0x01, 0, 0, "id-ecPublicKey" }, /* 98 */
- { 0x03, 129, 1, "ellipticCurve" }, /* 99 */
- { 0x00, 121, 1, "c-TwoCurve" }, /* 100 */
- { 0x01, 102, 0, "c2pnb163v1" }, /* 101 */
- { 0x02, 103, 0, "c2pnb163v2" }, /* 102 */
- { 0x03, 104, 0, "c2pnb163v3" }, /* 103 */
- { 0x04, 105, 0, "c2pnb176w1" }, /* 104 */
- { 0x05, 106, 0, "c2tnb191v1" }, /* 105 */
- { 0x06, 107, 0, "c2tnb191v2" }, /* 106 */
- { 0x07, 108, 0, "c2tnb191v3" }, /* 107 */
- { 0x08, 109, 0, "c2onb191v4" }, /* 108 */
- { 0x09, 110, 0, "c2onb191v5" }, /* 109 */
- { 0x0A, 111, 0, "c2pnb208w1" }, /* 110 */
- { 0x0B, 112, 0, "c2tnb239v1" }, /* 111 */
- { 0x0C, 113, 0, "c2tnb239v2" }, /* 112 */
- { 0x0D, 114, 0, "c2tnb239v3" }, /* 113 */
- { 0x0E, 115, 0, "c2onb239v4" }, /* 114 */
- { 0x0F, 116, 0, "c2onb239v5" }, /* 115 */
- { 0x10, 117, 0, "c2pnb272w1" }, /* 116 */
- { 0x11, 118, 0, "c2pnb304w1" }, /* 117 */
- { 0x12, 119, 0, "c2tnb359v1" }, /* 118 */
- { 0x13, 120, 0, "c2pnb368w1" }, /* 119 */
- { 0x14, 0, 0, "c2tnb431r1" }, /* 120 */
- { 0x01, 0, 1, "primeCurve" }, /* 121 */
- { 0x01, 123, 0, "prime192v1" }, /* 122 */
- { 0x02, 124, 0, "prime192v2" }, /* 123 */
- { 0x03, 125, 0, "prime192v3" }, /* 124 */
- { 0x04, 126, 0, "prime239v1" }, /* 125 */
- { 0x05, 127, 0, "prime239v2" }, /* 126 */
- { 0x06, 128, 0, "prime239v3" }, /* 127 */
- { 0x07, 0, 0, "prime256v1" }, /* 128 */
- { 0x04, 0, 1, "id-ecSigType" }, /* 129 */
- { 0x01, 0, 0, "ecdsa-with-SHA1" }, /* 130 */
- {0x2B, 231, 1, "" }, /* 131 */
- { 0x06, 184, 1, "dod" }, /* 132 */
- { 0x01, 0, 1, "internet" }, /* 133 */
- { 0x04, 152, 1, "private" }, /* 134 */
- { 0x01, 0, 1, "enterprise" }, /* 135 */
- { 0x82, 145, 1, "" }, /* 136 */
- { 0x37, 0, 1, "Microsoft" }, /* 137 */
- { 0x0A, 142, 1, "" }, /* 138 */
- { 0x03, 0, 1, "" }, /* 139 */
- { 0x03, 141, 0, "msSGC" }, /* 140 */
- { 0x04, 0, 0, "msEncryptingFileSystem" }, /* 141 */
- { 0x14, 0, 1, "msEnrollmentInfrastructure"}, /* 142 */
- { 0x02, 0, 1, "msCertificateTypeExtension"}, /* 143 */
- { 0x02, 0, 0, "msSmartcardLogon" }, /* 144 */
- { 0x89, 0, 1, "" }, /* 145 */
- { 0x31, 0, 1, "" }, /* 146 */
- { 0x01, 0, 1, "" }, /* 147 */
- { 0x01, 0, 1, "" }, /* 148 */
- { 0x02, 0, 1, "" }, /* 149 */
- { 0x02, 151, 0, "" }, /* 150 */
- { 0x4B, 0, 0, "TCGID" }, /* 151 */
- { 0x05, 0, 1, "security" }, /* 152 */
- { 0x05, 0, 1, "mechanisms" }, /* 153 */
- { 0x07, 0, 1, "id-pkix" }, /* 154 */
- { 0x01, 157, 1, "id-pe" }, /* 155 */
- { 0x01, 0, 0, "authorityInfoAccess" }, /* 156 */
- { 0x03, 167, 1, "id-kp" }, /* 157 */
- { 0x01, 159, 0, "serverAuth" }, /* 158 */
- { 0x02, 160, 0, "clientAuth" }, /* 159 */
- { 0x03, 161, 0, "codeSigning" }, /* 160 */
- { 0x04, 162, 0, "emailProtection" }, /* 161 */
- { 0x05, 163, 0, "ipsecEndSystem" }, /* 162 */
- { 0x06, 164, 0, "ipsecTunnel" }, /* 163 */
- { 0x07, 165, 0, "ipsecUser" }, /* 164 */
- { 0x08, 166, 0, "timeStamping" }, /* 165 */
- { 0x09, 0, 0, "ocspSigning" }, /* 166 */
- { 0x08, 169, 1, "id-otherNames" }, /* 167 */
- { 0x05, 0, 0, "xmppAddr" }, /* 168 */
- { 0x0A, 174, 1, "id-aca" }, /* 169 */
- { 0x01, 171, 0, "authenticationInfo" }, /* 170 */
- { 0x02, 172, 0, "accessIdentity" }, /* 171 */
- { 0x03, 173, 0, "chargingIdentity" }, /* 172 */
- { 0x04, 0, 0, "group" }, /* 173 */
- { 0x30, 0, 1, "id-ad" }, /* 174 */
- { 0x01, 183, 1, "ocsp" }, /* 175 */
- { 0x01, 177, 0, "basic" }, /* 176 */
- { 0x02, 178, 0, "nonce" }, /* 177 */
- { 0x03, 179, 0, "crl" }, /* 178 */
- { 0x04, 180, 0, "response" }, /* 179 */
- { 0x05, 181, 0, "noCheck" }, /* 180 */
- { 0x06, 182, 0, "archiveCutoff" }, /* 181 */
- { 0x07, 0, 0, "serviceLocator" }, /* 182 */
- { 0x02, 0, 0, "caIssuers" }, /* 183 */
- { 0x0E, 190, 1, "oiw" }, /* 184 */
- { 0x03, 0, 1, "secsig" }, /* 185 */
- { 0x02, 0, 1, "algorithms" }, /* 186 */
- { 0x07, 188, 0, "des-cbc" }, /* 187 */
- { 0x1A, 189, 0, "sha-1" }, /* 188 */
- { 0x1D, 0, 0, "sha-1WithRSASignature" }, /* 189 */
- { 0x24, 197, 1, "TeleTrusT" }, /* 190 */
- { 0x03, 0, 1, "algorithm" }, /* 191 */
- { 0x03, 0, 1, "signatureAlgorithm" }, /* 192 */
- { 0x01, 0, 1, "rsaSignature" }, /* 193 */
- { 0x02, 195, 0, "rsaSigWithripemd160" }, /* 194 */
- { 0x03, 196, 0, "rsaSigWithripemd128" }, /* 195 */
- { 0x04, 0, 0, "rsaSigWithripemd256" }, /* 196 */
- { 0x81, 0, 1, "" }, /* 197 */
- { 0x04, 0, 1, "Certicom" }, /* 198 */
- { 0x00, 0, 1, "curve" }, /* 199 */
- { 0x01, 201, 0, "sect163k1" }, /* 200 */
- { 0x02, 202, 0, "sect163r1" }, /* 201 */
- { 0x03, 203, 0, "sect239k1" }, /* 202 */
- { 0x04, 204, 0, "sect113r1" }, /* 203 */
- { 0x05, 205, 0, "sect113r2" }, /* 204 */
- { 0x06, 206, 0, "secp112r1" }, /* 205 */
- { 0x07, 207, 0, "secp112r2" }, /* 206 */
- { 0x08, 208, 0, "secp160r1" }, /* 207 */
- { 0x09, 209, 0, "secp160k1" }, /* 208 */
- { 0x0A, 210, 0, "secp256k1" }, /* 209 */
- { 0x0F, 211, 0, "sect163r2" }, /* 210 */
- { 0x10, 212, 0, "sect283k1" }, /* 211 */
- { 0x11, 213, 0, "sect283r1" }, /* 212 */
- { 0x16, 214, 0, "sect131r1" }, /* 213 */
- { 0x17, 215, 0, "sect131r2" }, /* 214 */
- { 0x18, 216, 0, "sect193r1" }, /* 215 */
- { 0x19, 217, 0, "sect193r2" }, /* 216 */
- { 0x1A, 218, 0, "sect233k1" }, /* 217 */
- { 0x1B, 219, 0, "sect233r1" }, /* 218 */
- { 0x1C, 220, 0, "secp128r1" }, /* 219 */
- { 0x1D, 221, 0, "secp128r2" }, /* 220 */
- { 0x1E, 222, 0, "secp160r2" }, /* 221 */
- { 0x1F, 223, 0, "secp192k1" }, /* 222 */
- { 0x20, 224, 0, "secp224k1" }, /* 223 */
- { 0x21, 225, 0, "secp224r1" }, /* 224 */
- { 0x22, 226, 0, "secp384r1" }, /* 225 */
- { 0x23, 227, 0, "secp521r1" }, /* 226 */
- { 0x24, 228, 0, "sect409k1" }, /* 227 */
- { 0x25, 229, 0, "sect409r1" }, /* 228 */
- { 0x26, 230, 0, "sect571k1" }, /* 229 */
- { 0x27, 0, 0, "sect571r1" }, /* 230 */
- {0x60, 0, 1, "" }, /* 231 */
- { 0x86, 0, 1, "" }, /* 232 */
- { 0x48, 0, 1, "" }, /* 233 */
- { 0x01, 0, 1, "organization" }, /* 234 */
- { 0x65, 242, 1, "gov" }, /* 235 */
- { 0x03, 0, 1, "csor" }, /* 236 */
- { 0x04, 0, 1, "nistalgorithm" }, /* 237 */
- { 0x02, 0, 1, "hashalgs" }, /* 238 */
- { 0x01, 240, 0, "id-SHA-256" }, /* 239 */
- { 0x02, 241, 0, "id-SHA-384" }, /* 240 */
- { 0x03, 0, 0, "id-SHA-512" }, /* 241 */
- { 0x86, 0, 1, "" }, /* 242 */
- { 0xf8, 0, 1, "" }, /* 243 */
- { 0x42, 256, 1, "netscape" }, /* 244 */
- { 0x01, 251, 1, "" }, /* 245 */
- { 0x01, 247, 0, "nsCertType" }, /* 246 */
- { 0x03, 248, 0, "nsRevocationUrl" }, /* 247 */
- { 0x04, 249, 0, "nsCaRevocationUrl" }, /* 248 */
- { 0x08, 250, 0, "nsCaPolicyUrl" }, /* 249 */
- { 0x0d, 0, 0, "nsComment" }, /* 250 */
- { 0x03, 254, 1, "directory" }, /* 251 */
- { 0x01, 0, 1, "" }, /* 252 */
- { 0x03, 0, 0, "employeeNumber" }, /* 253 */
- { 0x04, 0, 1, "policy" }, /* 254 */
- { 0x01, 0, 0, "nsSGC" }, /* 255 */
- { 0x45, 0, 1, "verisign" }, /* 256 */
- { 0x01, 0, 1, "pki" }, /* 257 */
- { 0x09, 0, 1, "attributes" }, /* 258 */
- { 0x02, 260, 0, "messageType" }, /* 259 */
- { 0x03, 261, 0, "pkiStatus" }, /* 260 */
- { 0x04, 262, 0, "failInfo" }, /* 261 */
- { 0x05, 263, 0, "senderNonce" }, /* 262 */
- { 0x06, 264, 0, "recipientNonce" }, /* 263 */
- { 0x07, 265, 0, "transID" }, /* 264 */
- { 0x08, 0, 0, "extensionReq" } /* 265 */
+ {0x02, 7, 1, 0, "ITU-T Administration" }, /* 0 */
+ { 0x82, 0, 1, 1, "" }, /* 1 */
+ { 0x06, 0, 1, 2, "Germany ITU-T member" }, /* 2 */
+ { 0x01, 0, 1, 3, "Deutsche Telekom AG" }, /* 3 */
+ { 0x0A, 0, 1, 4, "" }, /* 4 */
+ { 0x07, 0, 1, 5, "" }, /* 5 */
+ { 0x14, 0, 0, 6, "ND" }, /* 6 */
+ {0x09, 18, 1, 0, "data" }, /* 7 */
+ { 0x92, 0, 1, 1, "" }, /* 8 */
+ { 0x26, 0, 1, 2, "" }, /* 9 */
+ { 0x89, 0, 1, 3, "" }, /* 10 */
+ { 0x93, 0, 1, 4, "" }, /* 11 */
+ { 0xF2, 0, 1, 5, "" }, /* 12 */
+ { 0x2C, 0, 1, 6, "" }, /* 13 */
+ { 0x64, 0, 1, 7, "pilot" }, /* 14 */
+ { 0x01, 0, 1, 8, "pilotAttributeType" }, /* 15 */
+ { 0x01, 17, 0, 9, "UID" }, /* 16 */
+ { 0x19, 0, 0, 9, "DC" }, /* 17 */
+ {0x55, 52, 1, 0, "X.500" }, /* 18 */
+ { 0x04, 36, 1, 1, "X.509" }, /* 19 */
+ { 0x03, 21, 0, 2, "CN" }, /* 20 */
+ { 0x04, 22, 0, 2, "S" }, /* 21 */
+ { 0x05, 23, 0, 2, "SN" }, /* 22 */
+ { 0x06, 24, 0, 2, "C" }, /* 23 */
+ { 0x07, 25, 0, 2, "L" }, /* 24 */
+ { 0x08, 26, 0, 2, "ST" }, /* 25 */
+ { 0x0A, 27, 0, 2, "O" }, /* 26 */
+ { 0x0B, 28, 0, 2, "OU" }, /* 27 */
+ { 0x0C, 29, 0, 2, "T" }, /* 28 */
+ { 0x0D, 30, 0, 2, "D" }, /* 29 */
+ { 0x24, 31, 0, 2, "userCertificate" }, /* 30 */
+ { 0x29, 32, 0, 2, "N" }, /* 31 */
+ { 0x2A, 33, 0, 2, "G" }, /* 32 */
+ { 0x2B, 34, 0, 2, "I" }, /* 33 */
+ { 0x2D, 35, 0, 2, "ID" }, /* 34 */
+ { 0x48, 0, 0, 2, "role" }, /* 35 */
+ { 0x1D, 0, 1, 1, "id-ce" }, /* 36 */
+ { 0x09, 38, 0, 2, "subjectDirectoryAttrs" }, /* 37 */
+ { 0x0E, 39, 0, 2, "subjectKeyIdentifier" }, /* 38 */
+ { 0x0F, 40, 0, 2, "keyUsage" }, /* 39 */
+ { 0x10, 41, 0, 2, "privateKeyUsagePeriod" }, /* 40 */
+ { 0x11, 42, 0, 2, "subjectAltName" }, /* 41 */
+ { 0x12, 43, 0, 2, "issuerAltName" }, /* 42 */
+ { 0x13, 44, 0, 2, "basicConstraints" }, /* 43 */
+ { 0x14, 45, 0, 2, "crlNumber" }, /* 44 */
+ { 0x15, 46, 0, 2, "reasonCode" }, /* 45 */
+ { 0x1F, 47, 0, 2, "crlDistributionPoints" }, /* 46 */
+ { 0x20, 48, 0, 2, "certificatePolicies" }, /* 47 */
+ { 0x23, 49, 0, 2, "authorityKeyIdentifier" }, /* 48 */
+ { 0x25, 50, 0, 2, "extendedKeyUsage" }, /* 49 */
+ { 0x37, 51, 0, 2, "targetInformation" }, /* 50 */
+ { 0x38, 0, 0, 2, "noRevAvail" }, /* 51 */
+ {0x2A, 143, 1, 0, "" }, /* 52 */
+ { 0x83, 65, 1, 1, "" }, /* 53 */
+ { 0x08, 0, 1, 2, "jp" }, /* 54 */
+ { 0x8C, 0, 1, 3, "" }, /* 55 */
+ { 0x9A, 0, 1, 4, "" }, /* 56 */
+ { 0x4B, 0, 1, 5, "" }, /* 57 */
+ { 0x3D, 0, 1, 6, "" }, /* 58 */
+ { 0x01, 0, 1, 7, "security" }, /* 59 */
+ { 0x01, 0, 1, 8, "algorithm" }, /* 60 */
+ { 0x01, 0, 1, 9, "symm-encryption-alg" }, /* 61 */
+ { 0x02, 63, 0, 10, "camellia128-cbc" }, /* 62 */
+ { 0x03, 64, 0, 10, "camellia192-cbc" }, /* 63 */
+ { 0x04, 0, 0, 10, "camellia256-cbc" }, /* 64 */
+ { 0x86, 0, 1, 1, "" }, /* 65 */
+ { 0x48, 0, 1, 2, "us" }, /* 66 */
+ { 0x86, 107, 1, 3, "" }, /* 67 */
+ { 0xF6, 73, 1, 4, "" }, /* 68 */
+ { 0x7D, 0, 1, 5, "NortelNetworks" }, /* 69 */
+ { 0x07, 0, 1, 6, "Entrust" }, /* 70 */
+ { 0x41, 0, 1, 7, "nsn-ce" }, /* 71 */
+ { 0x00, 0, 0, 8, "entrustVersInfo" }, /* 72 */
+ { 0xF7, 0, 1, 4, "" }, /* 73 */
+ { 0x0D, 0, 1, 5, "RSADSI" }, /* 74 */
+ { 0x01, 102, 1, 6, "PKCS" }, /* 75 */
+ { 0x01, 84, 1, 7, "PKCS-1" }, /* 76 */
+ { 0x01, 78, 0, 8, "rsaEncryption" }, /* 77 */
+ { 0x02, 79, 0, 8, "md2WithRSAEncryption" }, /* 78 */
+ { 0x04, 80, 0, 8, "md5WithRSAEncryption" }, /* 79 */
+ { 0x05, 81, 0, 8, "sha-1WithRSAEncryption" }, /* 80 */
+ { 0x0B, 82, 0, 8, "sha256WithRSAEncryption" }, /* 81 */
+ { 0x0C, 83, 0, 8, "sha384WithRSAEncryption" }, /* 82 */
+ { 0x0D, 0, 0, 8, "sha512WithRSAEncryption" }, /* 83 */
+ { 0x07, 91, 1, 7, "PKCS-7" }, /* 84 */
+ { 0x01, 86, 0, 8, "data" }, /* 85 */
+ { 0x02, 87, 0, 8, "signedData" }, /* 86 */
+ { 0x03, 88, 0, 8, "envelopedData" }, /* 87 */
+ { 0x04, 89, 0, 8, "signedAndEnvelopedData" }, /* 88 */
+ { 0x05, 90, 0, 8, "digestedData" }, /* 89 */
+ { 0x06, 0, 0, 8, "encryptedData" }, /* 90 */
+ { 0x09, 0, 1, 7, "PKCS-9" }, /* 91 */
+ { 0x01, 93, 0, 8, "E" }, /* 92 */
+ { 0x02, 94, 0, 8, "unstructuredName" }, /* 93 */
+ { 0x03, 95, 0, 8, "contentType" }, /* 94 */
+ { 0x04, 96, 0, 8, "messageDigest" }, /* 95 */
+ { 0x05, 97, 0, 8, "signingTime" }, /* 96 */
+ { 0x06, 98, 0, 8, "counterSignature" }, /* 97 */
+ { 0x07, 99, 0, 8, "challengePassword" }, /* 98 */
+ { 0x08, 100, 0, 8, "unstructuredAddress" }, /* 99 */
+ { 0x0E, 101, 0, 8, "extensionRequest" }, /* 100 */
+ { 0x0F, 0, 0, 8, "S/MIME Capabilities" }, /* 101 */
+ { 0x02, 105, 1, 6, "digestAlgorithm" }, /* 102 */
+ { 0x02, 104, 0, 7, "md2" }, /* 103 */
+ { 0x05, 0, 0, 7, "md5" }, /* 104 */
+ { 0x03, 0, 1, 6, "encryptionAlgorithm" }, /* 105 */
+ { 0x07, 0, 0, 7, "3des-ede-cbc" }, /* 106 */
+ { 0xCE, 0, 1, 3, "" }, /* 107 */
+ { 0x3D, 0, 1, 4, "ansi-X9-62" }, /* 108 */
+ { 0x02, 111, 1, 5, "id-publicKeyType" }, /* 109 */
+ { 0x01, 0, 0, 6, "id-ecPublicKey" }, /* 110 */
+ { 0x03, 141, 1, 5, "ellipticCurve" }, /* 111 */
+ { 0x00, 133, 1, 6, "c-TwoCurve" }, /* 112 */
+ { 0x01, 114, 0, 7, "c2pnb163v1" }, /* 113 */
+ { 0x02, 115, 0, 7, "c2pnb163v2" }, /* 114 */
+ { 0x03, 116, 0, 7, "c2pnb163v3" }, /* 115 */
+ { 0x04, 117, 0, 7, "c2pnb176w1" }, /* 116 */
+ { 0x05, 118, 0, 7, "c2tnb191v1" }, /* 117 */
+ { 0x06, 119, 0, 7, "c2tnb191v2" }, /* 118 */
+ { 0x07, 120, 0, 7, "c2tnb191v3" }, /* 119 */
+ { 0x08, 121, 0, 7, "c2onb191v4" }, /* 120 */
+ { 0x09, 122, 0, 7, "c2onb191v5" }, /* 121 */
+ { 0x0A, 123, 0, 7, "c2pnb208w1" }, /* 122 */
+ { 0x0B, 124, 0, 7, "c2tnb239v1" }, /* 123 */
+ { 0x0C, 125, 0, 7, "c2tnb239v2" }, /* 124 */
+ { 0x0D, 126, 0, 7, "c2tnb239v3" }, /* 125 */
+ { 0x0E, 127, 0, 7, "c2onb239v4" }, /* 126 */
+ { 0x0F, 128, 0, 7, "c2onb239v5" }, /* 127 */
+ { 0x10, 129, 0, 7, "c2pnb272w1" }, /* 128 */
+ { 0x11, 130, 0, 7, "c2pnb304w1" }, /* 129 */
+ { 0x12, 131, 0, 7, "c2tnb359v1" }, /* 130 */
+ { 0x13, 132, 0, 7, "c2pnb368w1" }, /* 131 */
+ { 0x14, 0, 0, 7, "c2tnb431r1" }, /* 132 */
+ { 0x01, 0, 1, 6, "primeCurve" }, /* 133 */
+ { 0x01, 135, 0, 7, "prime192v1" }, /* 134 */
+ { 0x02, 136, 0, 7, "prime192v2" }, /* 135 */
+ { 0x03, 137, 0, 7, "prime192v3" }, /* 136 */
+ { 0x04, 138, 0, 7, "prime239v1" }, /* 137 */
+ { 0x05, 139, 0, 7, "prime239v2" }, /* 138 */
+ { 0x06, 140, 0, 7, "prime239v3" }, /* 139 */
+ { 0x07, 0, 0, 7, "prime256v1" }, /* 140 */
+ { 0x04, 0, 1, 5, "id-ecSigType" }, /* 141 */
+ { 0x01, 0, 0, 6, "ecdsa-with-SHA1" }, /* 142 */
+ {0x2B, 243, 1, 0, "" }, /* 143 */
+ { 0x06, 196, 1, 1, "dod" }, /* 144 */
+ { 0x01, 0, 1, 2, "internet" }, /* 145 */
+ { 0x04, 164, 1, 3, "private" }, /* 146 */
+ { 0x01, 0, 1, 4, "enterprise" }, /* 147 */
+ { 0x82, 157, 1, 5, "" }, /* 148 */
+ { 0x37, 0, 1, 6, "Microsoft" }, /* 149 */
+ { 0x0A, 154, 1, 7, "" }, /* 150 */
+ { 0x03, 0, 1, 8, "" }, /* 151 */
+ { 0x03, 153, 0, 9, "msSGC" }, /* 152 */
+ { 0x04, 0, 0, 9, "msEncryptingFileSystem" }, /* 153 */
+ { 0x14, 0, 1, 7, "msEnrollmentInfrastructure"}, /* 154 */
+ { 0x02, 0, 1, 8, "msCertificateTypeExtension"}, /* 155 */
+ { 0x02, 0, 0, 9, "msSmartcardLogon" }, /* 156 */
+ { 0x89, 0, 1, 5, "" }, /* 157 */
+ { 0x31, 0, 1, 6, "" }, /* 158 */
+ { 0x01, 0, 1, 7, "" }, /* 159 */
+ { 0x01, 0, 1, 8, "" }, /* 160 */
+ { 0x02, 0, 1, 9, "" }, /* 161 */
+ { 0x02, 163, 0, 10, "" }, /* 162 */
+ { 0x4B, 0, 0, 10, "TCGID" }, /* 163 */
+ { 0x05, 0, 1, 3, "security" }, /* 164 */
+ { 0x05, 0, 1, 4, "mechanisms" }, /* 165 */
+ { 0x07, 0, 1, 5, "id-pkix" }, /* 166 */
+ { 0x01, 169, 1, 6, "id-pe" }, /* 167 */
+ { 0x01, 0, 0, 7, "authorityInfoAccess" }, /* 168 */
+ { 0x03, 179, 1, 6, "id-kp" }, /* 169 */
+ { 0x01, 171, 0, 7, "serverAuth" }, /* 170 */
+ { 0x02, 172, 0, 7, "clientAuth" }, /* 171 */
+ { 0x03, 173, 0, 7, "codeSigning" }, /* 172 */
+ { 0x04, 174, 0, 7, "emailProtection" }, /* 173 */
+ { 0x05, 175, 0, 7, "ipsecEndSystem" }, /* 174 */
+ { 0x06, 176, 0, 7, "ipsecTunnel" }, /* 175 */
+ { 0x07, 177, 0, 7, "ipsecUser" }, /* 176 */
+ { 0x08, 178, 0, 7, "timeStamping" }, /* 177 */
+ { 0x09, 0, 0, 7, "ocspSigning" }, /* 178 */
+ { 0x08, 181, 1, 6, "id-otherNames" }, /* 179 */
+ { 0x05, 0, 0, 7, "xmppAddr" }, /* 180 */
+ { 0x0A, 186, 1, 6, "id-aca" }, /* 181 */
+ { 0x01, 183, 0, 7, "authenticationInfo" }, /* 182 */
+ { 0x02, 184, 0, 7, "accessIdentity" }, /* 183 */
+ { 0x03, 185, 0, 7, "chargingIdentity" }, /* 184 */
+ { 0x04, 0, 0, 7, "group" }, /* 185 */
+ { 0x30, 0, 1, 6, "id-ad" }, /* 186 */
+ { 0x01, 195, 1, 7, "ocsp" }, /* 187 */
+ { 0x01, 189, 0, 8, "basic" }, /* 188 */
+ { 0x02, 190, 0, 8, "nonce" }, /* 189 */
+ { 0x03, 191, 0, 8, "crl" }, /* 190 */
+ { 0x04, 192, 0, 8, "response" }, /* 191 */
+ { 0x05, 193, 0, 8, "noCheck" }, /* 192 */
+ { 0x06, 194, 0, 8, "archiveCutoff" }, /* 193 */
+ { 0x07, 0, 0, 8, "serviceLocator" }, /* 194 */
+ { 0x02, 0, 0, 7, "caIssuers" }, /* 195 */
+ { 0x0E, 202, 1, 1, "oiw" }, /* 196 */
+ { 0x03, 0, 1, 2, "secsig" }, /* 197 */
+ { 0x02, 0, 1, 3, "algorithms" }, /* 198 */
+ { 0x07, 200, 0, 4, "des-cbc" }, /* 199 */
+ { 0x1A, 201, 0, 4, "sha-1" }, /* 200 */
+ { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 201 */
+ { 0x24, 209, 1, 1, "TeleTrusT" }, /* 202 */
+ { 0x03, 0, 1, 2, "algorithm" }, /* 203 */
+ { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 204 */
+ { 0x01, 0, 1, 4, "rsaSignature" }, /* 205 */
+ { 0x02, 207, 0, 5, "rsaSigWithripemd160" }, /* 206 */
+ { 0x03, 208, 0, 5, "rsaSigWithripemd128" }, /* 207 */
+ { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 208 */
+ { 0x81, 0, 1, 1, "" }, /* 209 */
+ { 0x04, 0, 1, 2, "Certicom" }, /* 210 */
+ { 0x00, 0, 1, 3, "curve" }, /* 211 */
+ { 0x01, 213, 0, 4, "sect163k1" }, /* 212 */
+ { 0x02, 214, 0, 4, "sect163r1" }, /* 213 */
+ { 0x03, 215, 0, 4, "sect239k1" }, /* 214 */
+ { 0x04, 216, 0, 4, "sect113r1" }, /* 215 */
+ { 0x05, 217, 0, 4, "sect113r2" }, /* 216 */
+ { 0x06, 218, 0, 4, "secp112r1" }, /* 217 */
+ { 0x07, 219, 0, 4, "secp112r2" }, /* 218 */
+ { 0x08, 220, 0, 4, "secp160r1" }, /* 219 */
+ { 0x09, 221, 0, 4, "secp160k1" }, /* 220 */
+ { 0x0A, 222, 0, 4, "secp256k1" }, /* 221 */
+ { 0x0F, 223, 0, 4, "sect163r2" }, /* 222 */
+ { 0x10, 224, 0, 4, "sect283k1" }, /* 223 */
+ { 0x11, 225, 0, 4, "sect283r1" }, /* 224 */
+ { 0x16, 226, 0, 4, "sect131r1" }, /* 225 */
+ { 0x17, 227, 0, 4, "sect131r2" }, /* 226 */
+ { 0x18, 228, 0, 4, "sect193r1" }, /* 227 */
+ { 0x19, 229, 0, 4, "sect193r2" }, /* 228 */
+ { 0x1A, 230, 0, 4, "sect233k1" }, /* 229 */
+ { 0x1B, 231, 0, 4, "sect233r1" }, /* 230 */
+ { 0x1C, 232, 0, 4, "secp128r1" }, /* 231 */
+ { 0x1D, 233, 0, 4, "secp128r2" }, /* 232 */
+ { 0x1E, 234, 0, 4, "secp160r2" }, /* 233 */
+ { 0x1F, 235, 0, 4, "secp192k1" }, /* 234 */
+ { 0x20, 236, 0, 4, "secp224k1" }, /* 235 */
+ { 0x21, 237, 0, 4, "secp224r1" }, /* 236 */
+ { 0x22, 238, 0, 4, "secp384r1" }, /* 237 */
+ { 0x23, 239, 0, 4, "secp521r1" }, /* 238 */
+ { 0x24, 240, 0, 4, "sect409k1" }, /* 239 */
+ { 0x25, 241, 0, 4, "sect409r1" }, /* 240 */
+ { 0x26, 242, 0, 4, "sect571k1" }, /* 241 */
+ { 0x27, 0, 0, 4, "sect571r1" }, /* 242 */
+ {0x60, 0, 1, 0, "" }, /* 243 */
+ { 0x86, 0, 1, 1, "" }, /* 244 */
+ { 0x48, 0, 1, 2, "" }, /* 245 */
+ { 0x01, 289, 1, 3, "organization" }, /* 246 */
+ { 0x65, 265, 1, 4, "gov" }, /* 247 */
+ { 0x03, 0, 1, 5, "csor" }, /* 248 */
+ { 0x04, 0, 1, 6, "nistalgorithm" }, /* 249 */
+ { 0x01, 260, 1, 7, "aes" }, /* 250 */
+ { 0x02, 252, 0, 8, "id-aes128-CBC" }, /* 251 */
+ { 0x06, 253, 0, 8, "id-aes128-GCM" }, /* 252 */
+ { 0x07, 254, 0, 8, "id-aes128-CCM" }, /* 253 */
+ { 0x16, 255, 0, 8, "id-aes192-CBC" }, /* 254 */
+ { 0x1A, 256, 0, 8, "id-aes192-GCM" }, /* 255 */
+ { 0x1B, 257, 0, 8, "id-aes192-CCM" }, /* 256 */
+ { 0x2A, 258, 0, 8, "id-aes256-CBC" }, /* 257 */
+ { 0x2E, 259, 0, 8, "id-aes256-GCM" }, /* 258 */
+ { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 259 */
+ { 0x02, 0, 1, 7, "hashalgs" }, /* 260 */
+ { 0x01, 262, 0, 8, "id-SHA-256" }, /* 261 */
+ { 0x02, 263, 0, 8, "id-SHA-384" }, /* 262 */
+ { 0x03, 264, 0, 8, "id-SHA-512" }, /* 263 */
+ { 0x04, 0, 0, 8, "id-SHA-224" }, /* 264 */
+ { 0x86, 0, 1, 4, "" }, /* 265 */
+ { 0xf8, 0, 1, 5, "" }, /* 266 */
+ { 0x42, 279, 1, 6, "netscape" }, /* 267 */
+ { 0x01, 274, 1, 7, "" }, /* 268 */
+ { 0x01, 270, 0, 8, "nsCertType" }, /* 269 */
+ { 0x03, 271, 0, 8, "nsRevocationUrl" }, /* 270 */
+ { 0x04, 272, 0, 8, "nsCaRevocationUrl" }, /* 271 */
+ { 0x08, 273, 0, 8, "nsCaPolicyUrl" }, /* 272 */
+ { 0x0d, 0, 0, 8, "nsComment" }, /* 273 */
+ { 0x03, 277, 1, 7, "directory" }, /* 274 */
+ { 0x01, 0, 1, 8, "" }, /* 275 */
+ { 0x03, 0, 0, 9, "employeeNumber" }, /* 276 */
+ { 0x04, 0, 1, 7, "policy" }, /* 277 */
+ { 0x01, 0, 0, 8, "nsSGC" }, /* 278 */
+ { 0x45, 0, 1, 6, "verisign" }, /* 279 */
+ { 0x01, 0, 1, 7, "pki" }, /* 280 */
+ { 0x09, 0, 1, 8, "attributes" }, /* 281 */
+ { 0x02, 283, 0, 9, "messageType" }, /* 282 */
+ { 0x03, 284, 0, 9, "pkiStatus" }, /* 283 */
+ { 0x04, 285, 0, 9, "failInfo" }, /* 284 */
+ { 0x05, 286, 0, 9, "senderNonce" }, /* 285 */
+ { 0x06, 287, 0, 9, "recipientNonce" }, /* 286 */
+ { 0x07, 288, 0, 9, "transID" }, /* 287 */
+ { 0x08, 0, 0, 9, "extensionReq" }, /* 288 */
+ { 0x86, 0, 1, 3, "old-netscape" }, /* 289 */
+ { 0xF7, 0, 1, 4, "" }, /* 290 */
+ { 0x0D, 0, 1, 5, "" }, /* 291 */
+ { 0x01, 0, 1, 6, "" }, /* 292 */
+ { 0x09, 0, 1, 7, "" }, /* 293 */
+ { 0x01, 295, 0, 8, "emailAddress" }, /* 294 */
+ { 0x02, 0, 0, 8, "unstructuredName" } /* 295 */
};
diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h
index 72049259a..477789b62 100644
--- a/src/libstrongswan/asn1/oid.h
+++ b/src/libstrongswan/asn1/oid.h
@@ -5,6 +5,8 @@
* Do not edit manually!
*/
+#include <sys/types.h>
+
#ifndef OID_H_
#define OID_H_
@@ -12,12 +14,31 @@ typedef struct {
u_char octet;
u_int next;
u_int down;
+ u_int level;
const u_char *name;
} oid_t;
extern const oid_t oid_names[];
#define OID_UNKNOWN -1
+#define OID_NAME_DISTINGUISHER 6
+#define OID_PILOT_USERID 16
+#define OID_PILOT_DOMAIN_COMPONENT 17
+#define OID_COMMON_NAME 20
+#define OID_SURNAME 21
+#define OID_SERIAL_NUMBER 22
+#define OID_COUNTRY 23
+#define OID_LOCALITY 24
+#define OID_STATE_OR_PROVINCE 25
+#define OID_ORGANIZATION 26
+#define OID_ORGANIZATION_UNIT 27
+#define OID_TITLE 28
+#define OID_DESCRIPTION 29
+#define OID_USER_CERTIFICATE 30
+#define OID_NAME 31
+#define OID_GIVEN_NAME 32
+#define OID_INITIALS 33
+#define OID_UNIQUE_IDENTIFIER 34
#define OID_ROLE 35
#define OID_SUBJECT_KEY_ID 38
#define OID_SUBJECT_ALT_NAME 41
@@ -29,117 +50,136 @@ extern const oid_t oid_names[];
#define OID_EXTENDED_KEY_USAGE 49
#define OID_TARGET_INFORMATION 50
#define OID_NO_REV_AVAIL 51
-#define OID_RSA_ENCRYPTION 65
-#define OID_MD2_WITH_RSA 66
-#define OID_MD5_WITH_RSA 67
-#define OID_SHA1_WITH_RSA 68
-#define OID_SHA256_WITH_RSA 69
-#define OID_SHA384_WITH_RSA 70
-#define OID_SHA512_WITH_RSA 71
-#define OID_PKCS7_DATA 73
-#define OID_PKCS7_SIGNED_DATA 74
-#define OID_PKCS7_ENVELOPED_DATA 75
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA 76
-#define OID_PKCS7_DIGESTED_DATA 77
-#define OID_PKCS7_ENCRYPTED_DATA 78
-#define OID_PKCS9_EMAIL 80
-#define OID_PKCS9_CONTENT_TYPE 82
-#define OID_PKCS9_MESSAGE_DIGEST 83
-#define OID_PKCS9_SIGNING_TIME 84
-#define OID_MD2 91
-#define OID_MD5 92
-#define OID_3DES_EDE_CBC 94
-#define OID_EC_PUBLICKEY 98
-#define OID_C2PNB163V1 101
-#define OID_C2PNB163V2 102
-#define OID_C2PNB163V3 103
-#define OID_C2PNB176W1 104
-#define OID_C2PNB191V1 105
-#define OID_C2PNB191V2 106
-#define OID_C2PNB191V3 107
-#define OID_C2PNB191V4 108
-#define OID_C2PNB191V5 109
-#define OID_C2PNB208W1 110
-#define OID_C2PNB239V1 111
-#define OID_C2PNB239V2 112
-#define OID_C2PNB239V3 113
-#define OID_C2PNB239V4 114
-#define OID_C2PNB239V5 115
-#define OID_C2PNB272W1 116
-#define OID_C2PNB304W1 117
-#define OID_C2PNB359V1 118
-#define OID_C2PNB368W1 119
-#define OID_C2PNB431R1 120
-#define OID_PRIME192V1 122
-#define OID_PRIME192V2 123
-#define OID_PRIME192V3 124
-#define OID_PRIME239V1 125
-#define OID_PRIME239V2 126
-#define OID_PRIME239V3 127
-#define OID_PRIME256V1 128
-#define OID_ECDSA_WITH_SHA1 130
-#define OID_AUTHORITY_INFO_ACCESS 156
-#define OID_OCSP_SIGNING 166
-#define OID_XMPP_ADDR 168
-#define OID_AUTHENTICATION_INFO 170
-#define OID_ACCESS_IDENTITY 171
-#define OID_CHARGING_IDENTITY 172
-#define OID_GROUP 173
-#define OID_OCSP 175
-#define OID_BASIC 176
-#define OID_NONCE 177
-#define OID_CRL 178
-#define OID_RESPONSE 179
-#define OID_NO_CHECK 180
-#define OID_ARCHIVE_CUTOFF 181
-#define OID_SERVICE_LOCATOR 182
-#define OID_CA_ISSUERS 183
-#define OID_DES_CBC 187
-#define OID_SHA1 188
-#define OID_SHA1_WITH_RSA_OIW 189
-#define OID_SECT163K1 200
-#define OID_SECT163R1 201
-#define OID_SECT239K1 202
-#define OID_SECT113R1 203
-#define OID_SECT113R2 204
-#define OID_SECT112R1 205
-#define OID_SECT112R2 206
-#define OID_SECT160R1 207
-#define OID_SECT160K1 208
-#define OID_SECT256K1 209
-#define OID_SECT163R2 210
-#define OID_SECT283K1 211
-#define OID_SECT283R1 212
-#define OID_SECT131R1 213
-#define OID_SECT131R2 214
-#define OID_SECT193R1 215
-#define OID_SECT193R2 216
-#define OID_SECT233K1 217
-#define OID_SECT233R1 218
-#define OID_SECT128R1 219
-#define OID_SECT128R2 220
-#define OID_SECT160R2 221
-#define OID_SECT192K1 222
-#define OID_SECT224K1 223
-#define OID_SECT224R1 224
-#define OID_SECT384R1 225
-#define OID_SECT521R1 226
-#define OID_SECT409K1 227
-#define OID_SECT409R1 228
-#define OID_SECT571K1 229
-#define OID_SECT571R1 230
-#define OID_SHA256 239
-#define OID_SHA384 240
-#define OID_SHA512 241
-#define OID_NS_REVOCATION_URL 247
-#define OID_NS_CA_REVOCATION_URL 248
-#define OID_NS_CA_POLICY_URL 249
-#define OID_NS_COMMENT 250
-#define OID_PKI_MESSAGE_TYPE 259
-#define OID_PKI_STATUS 260
-#define OID_PKI_FAIL_INFO 261
-#define OID_PKI_SENDER_NONCE 262
-#define OID_PKI_RECIPIENT_NONCE 263
-#define OID_PKI_TRANS_ID 264
+#define OID_CAMELLIA128_CBC 62
+#define OID_CAMELLIA192_CBC 63
+#define OID_CAMELLIA256_CBC 64
+#define OID_RSA_ENCRYPTION 77
+#define OID_MD2_WITH_RSA 78
+#define OID_MD5_WITH_RSA 79
+#define OID_SHA1_WITH_RSA 80
+#define OID_SHA256_WITH_RSA 81
+#define OID_SHA384_WITH_RSA 82
+#define OID_SHA512_WITH_RSA 83
+#define OID_PKCS7_DATA 85
+#define OID_PKCS7_SIGNED_DATA 86
+#define OID_PKCS7_ENVELOPED_DATA 87
+#define OID_PKCS7_SIGNED_ENVELOPED_DATA 88
+#define OID_PKCS7_DIGESTED_DATA 89
+#define OID_PKCS7_ENCRYPTED_DATA 90
+#define OID_PKCS9_EMAIL 92
+#define OID_PKCS9_CONTENT_TYPE 94
+#define OID_PKCS9_MESSAGE_DIGEST 95
+#define OID_PKCS9_SIGNING_TIME 96
+#define OID_MD2 103
+#define OID_MD5 104
+#define OID_3DES_EDE_CBC 106
+#define OID_EC_PUBLICKEY 110
+#define OID_C2PNB163V1 113
+#define OID_C2PNB163V2 114
+#define OID_C2PNB163V3 115
+#define OID_C2PNB176W1 116
+#define OID_C2PNB191V1 117
+#define OID_C2PNB191V2 118
+#define OID_C2PNB191V3 119
+#define OID_C2PNB191V4 120
+#define OID_C2PNB191V5 121
+#define OID_C2PNB208W1 122
+#define OID_C2PNB239V1 123
+#define OID_C2PNB239V2 124
+#define OID_C2PNB239V3 125
+#define OID_C2PNB239V4 126
+#define OID_C2PNB239V5 127
+#define OID_C2PNB272W1 128
+#define OID_C2PNB304W1 129
+#define OID_C2PNB359V1 130
+#define OID_C2PNB368W1 131
+#define OID_C2PNB431R1 132
+#define OID_PRIME192V1 134
+#define OID_PRIME192V2 135
+#define OID_PRIME192V3 136
+#define OID_PRIME239V1 137
+#define OID_PRIME239V2 138
+#define OID_PRIME239V3 139
+#define OID_PRIME256V1 140
+#define OID_ECDSA_WITH_SHA1 142
+#define OID_TCGID 163
+#define OID_AUTHORITY_INFO_ACCESS 168
+#define OID_OCSP_SIGNING 178
+#define OID_XMPP_ADDR 180
+#define OID_AUTHENTICATION_INFO 182
+#define OID_ACCESS_IDENTITY 183
+#define OID_CHARGING_IDENTITY 184
+#define OID_GROUP 185
+#define OID_OCSP 187
+#define OID_BASIC 188
+#define OID_NONCE 189
+#define OID_CRL 190
+#define OID_RESPONSE 191
+#define OID_NO_CHECK 192
+#define OID_ARCHIVE_CUTOFF 193
+#define OID_SERVICE_LOCATOR 194
+#define OID_CA_ISSUERS 195
+#define OID_DES_CBC 199
+#define OID_SHA1 200
+#define OID_SHA1_WITH_RSA_OIW 201
+#define OID_SECT163K1 212
+#define OID_SECT163R1 213
+#define OID_SECT239K1 214
+#define OID_SECT113R1 215
+#define OID_SECT113R2 216
+#define OID_SECT112R1 217
+#define OID_SECT112R2 218
+#define OID_SECT160R1 219
+#define OID_SECT160K1 220
+#define OID_SECT256K1 221
+#define OID_SECT163R2 222
+#define OID_SECT283K1 223
+#define OID_SECT283R1 224
+#define OID_SECT131R1 225
+#define OID_SECT131R2 226
+#define OID_SECT193R1 227
+#define OID_SECT193R2 228
+#define OID_SECT233K1 229
+#define OID_SECT233R1 230
+#define OID_SECT128R1 231
+#define OID_SECT128R2 232
+#define OID_SECT160R2 233
+#define OID_SECT192K1 234
+#define OID_SECT224K1 235
+#define OID_SECT224R1 236
+#define OID_SECT384R1 237
+#define OID_SECT521R1 238
+#define OID_SECT409K1 239
+#define OID_SECT409R1 240
+#define OID_SECT571K1 241
+#define OID_SECT571R1 242
+#define OID_AES128_CBC 251
+#define OID_AES128_GCM 252
+#define OID_AES128_CCM 253
+#define OID_AES192_CBC 254
+#define OID_AES192_GCM 255
+#define OID_AES192_CCM 256
+#define OID_AES256_CBC 257
+#define OID_AES256_GCM 258
+#define OID_AES256_CCM 259
+#define OID_SHA256 261
+#define OID_SHA384 262
+#define OID_SHA512 263
+#define OID_SHA224 264
+#define OID_NS_REVOCATION_URL 270
+#define OID_NS_CA_REVOCATION_URL 271
+#define OID_NS_CA_POLICY_URL 272
+#define OID_NS_COMMENT 273
+#define OID_EMPLOYEE_NUMBER 276
+#define OID_PKI_MESSAGE_TYPE 282
+#define OID_PKI_STATUS 283
+#define OID_PKI_FAIL_INFO 284
+#define OID_PKI_SENDER_NONCE 285
+#define OID_PKI_RECIPIENT_NONCE 286
+#define OID_PKI_TRANS_ID 287
+#define OID_EMAIL_ADDRESS 294
+#define OID_UNSTRUCTURED_NAME 295
+
+#define OID_MAX 296
#endif /* OID_H_ */
diff --git a/src/libstrongswan/asn1/oid.pl b/src/libstrongswan/asn1/oid.pl
index 373101cc0..ed26febc9 100644
--- a/src/libstrongswan/asn1/oid.pl
+++ b/src/libstrongswan/asn1/oid.pl
@@ -32,12 +32,14 @@ print OID_H "/* Object identifiers (OIDs) used by strongSwan\n",
" * ", $automatic, "\n",
" * ", $warning, "\n",
" */\n\n",
+ "#include <sys/types.h>\n\n",
"#ifndef OID_H_\n",
"#define OID_H_\n\n",
"typedef struct {\n",
" u_char octet;\n",
" u_int next;\n",
" u_int down;\n",
+ " u_int level;\n",
" const u_char *name;\n",
"} oid_t;\n",
"\n",
@@ -77,6 +79,8 @@ while ($line = <SRC>)
$counter++;
}
+printf OID_H "\n#define OID_MAX%s%d\n", "\t" x 8, $counter;
+
print OID_H "\n#endif /* OID_H_ */\n";
close SRC;
@@ -113,12 +117,13 @@ for ($c = 0; $c < $counter; $c++)
}
}
- printf OID_C " {%s%s,%s%3d, %d, %s%s}%s /* %3d */\n"
+ printf OID_C " {%s%s,%s%3d, %d, %2d, %s%s}%s /* %3d */\n"
,' ' x @order[$c]
, @octet[$c]
, ' ' x (1 + $max_order - @order[$c])
, @next[$c]
, @order[$c+1] > @order[$c]
+ , @order[$c] / 2
, @name[$c]
, ' ' x ($max_name - length(@name[$c]))
, $c != $counter-1 ? "," : " "
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index 6bb765787..1514f179f 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -4,7 +4,7 @@
0x01 "Deutsche Telekom AG"
0x0A ""
0x07 ""
- 0x14 "ND"
+ 0x14 "ND" OID_NAME_DISTINGUISHER
0x09 "data"
0x92 ""
0x26 ""
@@ -14,25 +14,25 @@
0x2C ""
0x64 "pilot"
0x01 "pilotAttributeType"
- 0x01 "UID"
- 0x19 "DC"
+ 0x01 "UID" OID_PILOT_USERID
+ 0x19 "DC" OID_PILOT_DOMAIN_COMPONENT
0x55 "X.500"
0x04 "X.509"
- 0x03 "CN"
- 0x04 "S"
- 0x05 "SN"
- 0x06 "C"
- 0x07 "L"
- 0x08 "ST"
- 0x0A "O"
- 0x0B "OU"
- 0x0C "T"
- 0x0D "D"
- 0x24 "userCertificate"
- 0x29 "N"
- 0x2A "G"
- 0x2B "I"
- 0x2D "ID"
+ 0x03 "CN" OID_COMMON_NAME
+ 0x04 "S" OID_SURNAME
+ 0x05 "SN" OID_SERIAL_NUMBER
+ 0x06 "C" OID_COUNTRY
+ 0x07 "L" OID_LOCALITY
+ 0x08 "ST" OID_STATE_OR_PROVINCE
+ 0x0A "O" OID_ORGANIZATION
+ 0x0B "OU" OID_ORGANIZATION_UNIT
+ 0x0C "T" OID_TITLE
+ 0x0D "D" OID_DESCRIPTION
+ 0x24 "userCertificate" OID_USER_CERTIFICATE
+ 0x29 "N" OID_NAME
+ 0x2A "G" OID_GIVEN_NAME
+ 0x2B "I" OID_INITIALS
+ 0x2D "ID" OID_UNIQUE_IDENTIFIER
0x48 "role" OID_ROLE
0x1D "id-ce"
0x09 "subjectDirectoryAttrs"
@@ -51,8 +51,20 @@
0x37 "targetInformation" OID_TARGET_INFORMATION
0x38 "noRevAvail" OID_NO_REV_AVAIL
0x2A ""
+ 0x83 ""
+ 0x08 "jp"
+ 0x8C ""
+ 0x9A ""
+ 0x4B ""
+ 0x3D ""
+ 0x01 "security"
+ 0x01 "algorithm"
+ 0x01 "symm-encryption-alg"
+ 0x02 "camellia128-cbc" OID_CAMELLIA128_CBC
+ 0x03 "camellia192-cbc" OID_CAMELLIA192_CBC
+ 0x04 "camellia256-cbc" OID_CAMELLIA256_CBC
0x86 ""
- 0x48 ""
+ 0x48 "us"
0x86 ""
0xF6 ""
0x7D "NortelNetworks"
@@ -149,7 +161,7 @@
0x01 ""
0x02 ""
0x02 ""
- 0x4B "TCGID"
+ 0x4B "TCGID" OID_TCGID
0x05 "security"
0x05 "mechanisms"
0x07 "id-pkix"
@@ -236,10 +248,21 @@
0x65 "gov"
0x03 "csor"
0x04 "nistalgorithm"
+ 0x01 "aes"
+ 0x02 "id-aes128-CBC" OID_AES128_CBC
+ 0x06 "id-aes128-GCM" OID_AES128_GCM
+ 0x07 "id-aes128-CCM" OID_AES128_CCM
+ 0x16 "id-aes192-CBC" OID_AES192_CBC
+ 0x1A "id-aes192-GCM" OID_AES192_GCM
+ 0x1B "id-aes192-CCM" OID_AES192_CCM
+ 0x2A "id-aes256-CBC" OID_AES256_CBC
+ 0x2E "id-aes256-GCM" OID_AES256_GCM
+ 0x2F "id-aes256-CCM" OID_AES256_CCM
0x02 "hashalgs"
0x01 "id-SHA-256" OID_SHA256
0x02 "id-SHA-384" OID_SHA384
0x03 "id-SHA-512" OID_SHA512
+ 0x04 "id-SHA-224" OID_SHA224
0x86 ""
0xf8 ""
0x42 "netscape"
@@ -251,7 +274,7 @@
0x0d "nsComment" OID_NS_COMMENT
0x03 "directory"
0x01 ""
- 0x03 "employeeNumber"
+ 0x03 "employeeNumber" OID_EMPLOYEE_NUMBER
0x04 "policy"
0x01 "nsSGC"
0x45 "verisign"
@@ -264,3 +287,10 @@
0x06 "recipientNonce" OID_PKI_RECIPIENT_NONCE
0x07 "transID" OID_PKI_TRANS_ID
0x08 "extensionReq"
+ 0x86 "old-netscape"
+ 0xF7 ""
+ 0x0D ""
+ 0x01 ""
+ 0x09 ""
+ 0x01 "emailAddress" OID_EMAIL_ADDRESS
+ 0x02 "unstructuredName" OID_UNSTRUCTURED_NAME
diff --git a/src/libstrongswan/asn1/pem.c b/src/libstrongswan/asn1/pem.c
index d3176b6bc..059795548 100755
--- a/src/libstrongswan/asn1/pem.c
+++ b/src/libstrongswan/asn1/pem.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pem.c 4029 2008-06-03 12:14:02Z martin $
*/
#include <stdio.h>
@@ -84,8 +82,8 @@ static bool find_boundary(const char* tag, chunk_t *line)
/*
* decrypts a passphrase protected encrypted data block
*/
-static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size,
- chunk_t *iv, chunk_t *passphrase)
+static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size,
+ chunk_t *iv, chunk_t passphrase)
{
hasher_t *hasher;
crypter_t *crypter;
@@ -95,10 +93,10 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
chunk_t key = {alloca(key_size), key_size};
u_int8_t padding, *last_padding_pos, *first_padding_pos;
- if (passphrase == NULL || passphrase->len == 0)
+ if (passphrase.len == 0)
{
DBG1(" missing passphrase");
- return FALSE;
+ return INVALID_ARG;
}
/* build key from passphrase and IV */
@@ -106,18 +104,18 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
if (hasher == NULL)
{
DBG1(" MD5 hash algorithm not available");
- return FALSE;
+ return NOT_SUPPORTED;
}
hash.len = hasher->get_hash_size(hasher);
hash.ptr = alloca(hash.len);
- hasher->get_hash(hasher, *passphrase, NULL);
+ hasher->get_hash(hasher, passphrase, NULL);
hasher->get_hash(hasher, salt, hash.ptr);
memcpy(key.ptr, hash.ptr, hash.len);
if (key.len > hash.len)
{
hasher->get_hash(hasher, hash, NULL);
- hasher->get_hash(hasher, *passphrase, NULL);
+ hasher->get_hash(hasher, passphrase, NULL);
hasher->get_hash(hasher, salt, hash.ptr);
memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len);
}
@@ -129,7 +127,7 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
{
DBG1(" %N encryption algorithm not available",
encryption_algorithm_names, alg);
- return FALSE;
+ return NOT_SUPPORTED;
}
crypter->set_key(crypter, key);
@@ -138,7 +136,7 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
{
crypter->destroy(crypter);
DBG1(" data size is not multiple of block size");
- return FALSE;
+ return PARSE_ERROR;
}
crypter->decrypt(crypter, *blob, *iv, &decrypted);
crypter->destroy(crypter);
@@ -156,12 +154,12 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
if (*last_padding_pos != padding)
{
DBG1(" invalid passphrase");
- return FALSE;
+ return INVALID_ARG;
}
}
/* remove padding */
blob->len -= padding;
- return TRUE;
+ return SUCCESS;
}
/* Converts a PEM encoded file into its binary form
@@ -169,7 +167,7 @@ static bool pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_si
* RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
* RFC 934 Message Encapsulation, January 1985
*/
-bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
+status_t pem_to_bin(chunk_t *blob, chunk_t passphrase, bool *pgp)
{
typedef enum {
PEM_PRE = 0,
@@ -239,17 +237,21 @@ bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
DBG2(" %.*s", (int)line.len, line.ptr);
ugh = extract_parameter_value(&name, &value, &line);
if (ugh != NULL)
+ {
continue;
-
+ }
if (match("Proc-Type", &name) && *value.ptr == '4')
+ {
encrypted = TRUE;
+ }
else if (match("DEK-Info", &name))
{
chunk_t dek;
if (!extract_token(&dek, ',', &value))
+ {
dek = value;
-
+ }
if (match("DES-EDE3-CBC", &dek))
{
alg = ENCR_3DES;
@@ -274,7 +276,7 @@ bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
{
DBG1(" encryption algorithm '%.s' not supported",
dek.len, dek.ptr);
- return FALSE;
+ return NOT_SUPPORTED;
}
eat_whitespace(&value);
iv = chunk_from_hex(value, iv.ptr);
@@ -317,11 +319,11 @@ bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
if (state != PEM_POST)
{
DBG1(" file coded in unknown format, discarded");
- return FALSE;
+ return PARSE_ERROR;
}
if (!encrypted)
{
- return TRUE;
+ return SUCCESS;
}
return pem_decrypt(blob, alg, key_size, &iv, passphrase);
@@ -337,7 +339,9 @@ bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
if (fd)
{
+ chunk_t pass = chunk_empty;
int bytes;
+
fseek(fd, 0, SEEK_END );
blob->len = ftell(fd);
rewind(fd);
@@ -356,10 +360,13 @@ bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
}
if (passphrase != NULL)
- DBG4(" passphrase:", passphrase->ptr, passphrase->len);
+ {
+ pass = *passphrase;
+ DBG4(" passphrase: %#B", passphrase);
+ }
/* try PEM format */
- if (pem_to_bin(blob, passphrase, pgp))
+ if (pem_to_bin(blob, pass, pgp) == SUCCESS)
{
if (*pgp)
{
diff --git a/src/libstrongswan/asn1/pem.h b/src/libstrongswan/asn1/pem.h
index 4b76fbe80..7385330d7 100755
--- a/src/libstrongswan/asn1/pem.h
+++ b/src/libstrongswan/asn1/pem.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pem.h 4011 2008-05-23 19:18:08Z andreas $
*/
#ifndef PEM_H_
@@ -23,9 +21,9 @@
#include <library.h>
-bool pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp);
+status_t pem_to_bin(chunk_t *blob, chunk_t passphrase, bool *pgp);
-bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
- chunk_t *blob, bool *pgp);
+bool pem_asn1_load_file(char *filename, chunk_t *passphrase, chunk_t *blob,
+ bool *pgp);
#endif /*PEM_H_ @} */
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
index 331ef4436..c9c181f87 100644
--- a/src/libstrongswan/chunk.c
+++ b/src/libstrongswan/chunk.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: chunk.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <stdio.h>
@@ -208,7 +206,7 @@ void chunk_split(chunk_t chunk, const char *mode, ...)
/**
* Described in header.
*/
-bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force)
+bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force)
{
mode_t oldmask;
FILE *fd;
@@ -216,7 +214,7 @@ bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force)
if (!force && access(path, F_OK) == 0)
{
- DBG1(" file '%s' already exists", path);
+ DBG1(" %s file '%s' already exists", label, path);
return FALSE;
}
oldmask = umask(mask);
@@ -225,18 +223,20 @@ bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force)
{
if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len)
{
+ DBG1(" written %s file '%s' (%d bytes)",
+ label, path, chunk.len);
good = TRUE;
}
else
{
- DBG1(" writing to file '%s' failed: %s", path, strerror(errno));
+ DBG1(" writing %s file '%s' failed: %s",
+ label, path, strerror(errno));
}
fclose(fd);
- return TRUE;
}
else
{
- DBG1(" could not open file '%s': %s", path, strerror(errno));
+ DBG1(" could not open %s file '%s': %s", label, path, strerror(errno));
}
umask(oldmask);
return good;
diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h
index 125b86b12..3d8c360c5 100644
--- a/src/libstrongswan/chunk.h
+++ b/src/libstrongswan/chunk.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: chunk.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -41,7 +39,7 @@ struct chunk_t {
size_t len;
};
-#include <library.h>
+#include <utils.h>
/**
* A { NULL, 0 }-chunk handy for initialization.
@@ -86,8 +84,14 @@ void chunk_split(chunk_t chunk, const char *mode, ...);
/**
* Write the binary contents of a chunk_t to a file
- */
-bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force);
+ *
+ * @param path path where file is written to
+ * @param label label specifying file type
+ * @param mask file mode creation mask
+ * @param force overwrite existing file by force
+ * @return TRUE if write operation was successful
+ */
+bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force);
/**
* Convert a chunk of data to hex encoding.
@@ -95,7 +99,6 @@ bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force);
* The resulting string is '\\0' terminated, but the chunk does not include
* the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
*
- * @param chunk data to convert
* @param buf buffer to write to, NULL to malloc
* @param uppercase TRUE to use uppercase letters
* @return chunk of encoded data
@@ -181,12 +184,12 @@ static inline void chunk_clear(chunk_t *chunk)
/**
* Clone a chunk on heap
*/
-#define chunk_clone(chunk) chunk_create_clone((chunk).len ? malloc(chunk.len) : NULL, chunk)
+#define chunk_clone(chunk) chunk_create_clone((chunk).len ? malloc((chunk).len) : NULL, chunk)
/**
* Clone a chunk on stack
*/
-#define chunk_clonea(chunk) chunk_create_clone(alloca(chunk.len), chunk)
+#define chunk_clonea(chunk) chunk_create_clone(alloca((chunk).len), chunk)
/**
* Concatenate chunks into a chunk on heap
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index 0bca198f1..701cbcde3 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -20,6 +20,8 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_AGENT_SOCKET",
"BUILD_BLOB_ASN1_DER",
"BUILD_BLOB_ASN1_PEM",
+ "BUILD_BLOB_PGP",
+ "BUILD_BLOB_RFC_3110",
"BUILD_KEY_SIZE",
"BUILD_SIGNING_KEY",
"BUILD_SIGNING_CERT",
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index 4b3fb1ae4..01ccf2a5c 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -38,14 +38,18 @@ typedef builder_t* (*builder_constructor_t)(int subtype);
* Parts to build credentials from.
*/
enum builder_part_t {
- /** path to a file containing an ASN1 blob, char* */
+ /** path to a file containing an ASN.1 blob, char* */
BUILD_FROM_FILE,
/** unix socket of a ssh/pgp agent, char* */
BUILD_AGENT_SOCKET,
- /** DER encoded ASN1 blob, chunk_t */
+ /** DER encoded ASN.1 blob, chunk_t */
BUILD_BLOB_ASN1_DER,
- /** PEM encoded ASN1 blob, null terminated char* */
+ /** PEM encoded ASN.1 blob, null terminated char* */
BUILD_BLOB_ASN1_PEM,
+ /** OpenPGP key blob, chunk_t */
+ BUILD_BLOB_PGP,
+ /** RFC 3110 DNS public key blob, chunk_t */
+ BUILD_BLOB_RFC_3110,
/** key size in bits, as used for key generation, u_int */
BUILD_KEY_SIZE,
/** private key to use for signing, private_key_t* */
diff --git a/src/libstrongswan/credentials/certificates/ac.h b/src/libstrongswan/credentials/certificates/ac.h
index 39ab8fe71..fb99b4756 100644
--- a/src/libstrongswan/credentials/certificates/ac.h
+++ b/src/libstrongswan/credentials/certificates/ac.h
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $
*/
/**
diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c
index c5bc9a68d..041e2f1db 100644
--- a/src/libstrongswan/credentials/certificates/certificate.c
+++ b/src/libstrongswan/credentials/certificates/certificate.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: certificate.c 3664 2008-03-26 15:21:50Z martin $
*/
#include "certificate.h"
@@ -31,11 +29,11 @@ ENUM(certificate_type_names, CERT_ANY, CERT_PGP,
"PGP",
);
-ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED,
- "VALIDATION_GOOD",
- "VALIDATION_STALE",
- "VALIDATION_REVOKED",
- "VALIDATION_FAILED",
- "VALIDATION_SKIPPED",
+ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_REVOKED,
+ "GOOD",
+ "SKIPPED",
+ "STALE",
+ "FAILED",
+ "REVOKED",
);
diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h
index 1fb151d9f..81fce5508 100644
--- a/src/libstrongswan/credentials/certificates/certificate.h
+++ b/src/libstrongswan/credentials/certificates/certificate.h
@@ -58,18 +58,20 @@ extern enum_name_t *certificate_type_names;
/**
* Result of a certificate validation.
+ *
+ * Order of values is relevant, sorted from good to bad.
*/
enum cert_validation_t {
/** certificate has been validated successfully */
- VALIDATION_GOOD,
+ VALIDATION_GOOD = 0,
+ /** validation has been skipped due to missing validation information */
+ VALIDATION_SKIPPED,
/** certificate has been validated, but check based on stale information */
VALIDATION_STALE,
- /** certificate has been revoked */
- VALIDATION_REVOKED,
/** validation failed due to a processing error */
VALIDATION_FAILED,
- /** validation has been skipped due to missing validation information */
- VALIDATION_SKIPPED,
+ /** certificate has been revoked */
+ VALIDATION_REVOKED,
};
/**
diff --git a/src/libstrongswan/credentials/certificates/crl.c b/src/libstrongswan/credentials/certificates/crl.c
index 1fdc095c1..0d6654075 100644
--- a/src/libstrongswan/credentials/certificates/crl.c
+++ b/src/libstrongswan/credentials/certificates/crl.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crl.c 3656 2008-03-25 22:28:27Z andreas $
*/
#include "crl.h"
diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h
index 0c0493940..3fef0d710 100644
--- a/src/libstrongswan/credentials/certificates/crl.h
+++ b/src/libstrongswan/credentials/certificates/crl.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crl.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h
index 25ecb8d35..0b1871309 100644
--- a/src/libstrongswan/credentials/certificates/ocsp_request.h
+++ b/src/libstrongswan/credentials/certificates/ocsp_request.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.c b/src/libstrongswan/credentials/certificates/ocsp_response.c
index 02e12f761..c4a39e28d 100644
--- a/src/libstrongswan/credentials/certificates/ocsp_response.c
+++ b/src/libstrongswan/credentials/certificates/ocsp_response.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "ocsp_response.h"
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h
index 3c9794956..a70f3eee4 100644
--- a/src/libstrongswan/credentials/certificates/ocsp_response.h
+++ b/src/libstrongswan/credentials/certificates/ocsp_response.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/credentials/certificates/x509.c b/src/libstrongswan/credentials/certificates/x509.c
index 15d223e3e..5d53f0c68 100644
--- a/src/libstrongswan/credentials/certificates/x509.c
+++ b/src/libstrongswan/credentials/certificates/x509.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509.c 3656 2008-03-25 22:28:27Z andreas $
*/
#include "x509.h"
diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h
index 704f11522..eedab78f7 100644
--- a/src/libstrongswan/credentials/certificates/x509.h
+++ b/src/libstrongswan/credentials/certificates/x509.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c
index 5ae6980be..2e9a541d4 100644
--- a/src/libstrongswan/credentials/credential_factory.c
+++ b/src/libstrongswan/credentials/credential_factory.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: credential_factory.c 4777 2008-12-09 15:57:51Z martin $
*/
#include "credential_factory.h"
@@ -158,6 +156,8 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
case BUILD_END:
break;
case BUILD_BLOB_ASN1_DER:
+ case BUILD_BLOB_PGP:
+ case BUILD_BLOB_RFC_3110:
case BUILD_SERIAL:
builder->add(builder, part, va_arg(args, chunk_t));
continue;
diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h
index 42fb2df6d..5057a7aae 100644
--- a/src/libstrongswan/credentials/credential_factory.h
+++ b/src/libstrongswan/credentials/credential_factory.h
@@ -24,9 +24,6 @@
typedef struct credential_factory_t credential_factory_t;
typedef enum credential_type_t credential_type_t;
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/public_key.h>
-#include <credentials/certificates/certificate.h>
#include <credentials/builder.h>
/**
diff --git a/src/libstrongswan/credentials/keys/private_key.c b/src/libstrongswan/credentials/keys/private_key.c
index 018cab1c0..0a01d0385 100644
--- a/src/libstrongswan/credentials/keys/private_key.c
+++ b/src/libstrongswan/credentials/keys/private_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: private_key.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "private_key.h"
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
index 219926af1..f38af8ff4 100644
--- a/src/libstrongswan/credentials/keys/private_key.h
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: private_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -82,6 +80,14 @@ struct private_key_t {
public_key_t* (*get_public_key)(private_key_t *this);
/**
+ * Check if two private keys are equal.
+ *
+ * @param other other private key
+ * @return TRUE, if equality
+ */
+ bool (*equals) (private_key_t *this, private_key_t *other);
+
+ /**
* Check if a private key belongs to a public key.
*
* @param public public key
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 80b9f03c3..c94c27f0a 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -11,27 +11,60 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: public_key.c 4051 2008-06-10 09:08:27Z tobias $
*/
+#include <asn1/oid.h>
+
#include "public_key.h"
-ENUM(key_type_names, KEY_RSA, KEY_ECDSA,
+ENUM(key_type_names, KEY_RSA, KEY_DSA,
"RSA",
- "ECDSA"
+ "ECDSA",
+ "DSA"
);
-ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_ECDSA_521,
- "DEFAULT",
+ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
+ "UNKNOWN",
+ "RSA_EMSA_PKCS1_NULL",
"RSA_EMSA_PKCS1_MD5",
"RSA_EMSA_PKCS1_SHA1",
"RSA_EMSA_PKCS1_SHA256",
"RSA_EMSA_PKCS1_SHA384",
"RSA_EMSA_PKCS1_SHA512",
+ "ECDSA_WITH_NULL",
"ECDSA_WITH_SHA1",
"ECDSA-256",
"ECDSA-384",
"ECDSA-521",
);
+/*
+ * Defined in header.
+ */
+signature_scheme_t signature_scheme_from_oid(int oid)
+{
+ switch (oid)
+ {
+ case OID_MD5_WITH_RSA:
+ case OID_MD5:
+ return SIGN_RSA_EMSA_PKCS1_MD5;
+ case OID_SHA1_WITH_RSA:
+ case OID_SHA1:
+ return SIGN_RSA_EMSA_PKCS1_SHA1;
+ case OID_SHA256_WITH_RSA:
+ case OID_SHA256:
+ return SIGN_RSA_EMSA_PKCS1_SHA256;
+ case OID_SHA384_WITH_RSA:
+ case OID_SHA384:
+ return SIGN_RSA_EMSA_PKCS1_SHA384;
+ case OID_SHA512_WITH_RSA:
+ case OID_SHA512:
+ return SIGN_RSA_EMSA_PKCS1_SHA512;
+ case OID_ECDSA_WITH_SHA1:
+ case OID_EC_PUBLICKEY:
+ return SIGN_ECDSA_WITH_SHA1;
+ default:
+ return SIGN_UNKNOWN;
+ }
+}
+
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 65bb5f64d..c58531b73 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: public_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -36,12 +34,14 @@ typedef enum signature_scheme_t signature_scheme_t;
*/
enum key_type_t {
/** key type wildcard */
- KEY_ANY,
+ KEY_ANY = 0,
/** RSA crypto system as in PKCS#1 */
- KEY_RSA,
+ KEY_RSA = 1,
/** ECDSA as in ANSI X9.62 */
- KEY_ECDSA,
- /** DSS, ElGamal, ... */
+ KEY_ECDSA = 2,
+ /** DSA */
+ KEY_DSA = 3,
+ /** ElGamal, ... */
};
/**
@@ -52,29 +52,35 @@ extern enum_name_t *key_type_names;
/**
* Signature scheme for signature creation
*
- * EMSA-PKCS1 signatures are from the PKCS#1 standard. They include
- * the ASN1-OID of the used hash algorithm.
+ * EMSA-PKCS1 signatures are defined in PKCS#1 standard.
+ * A prepended ASN.1 encoded digestInfo field contains the
+ * OID of the used hash algorithm. The ASN.1 type of the PKCS#7
+ * variants is OCTET_STRING instead of the default BIT_STRING.
*/
enum signature_scheme_t {
- /** default scheme of that underlying crypto system */
- SIGN_DEFAULT,
- /** EMSA-PKCS1 with MD5 */
+ /** Unknown signature scheme */
+ SIGN_UNKNOWN,
+ /** EMSA-PKCS1_v1.5 signature over digest without digestInfo */
+ SIGN_RSA_EMSA_PKCS1_NULL,
+ /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and MD5 */
SIGN_RSA_EMSA_PKCS1_MD5,
- /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash. */
+ /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-1 */
SIGN_RSA_EMSA_PKCS1_SHA1,
- /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */
+ /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-256 */
SIGN_RSA_EMSA_PKCS1_SHA256,
- /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */
+ /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-384 */
SIGN_RSA_EMSA_PKCS1_SHA384,
- /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */
+ /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-512 */
SIGN_RSA_EMSA_PKCS1_SHA512,
- /** ECDSA using SHA-1 as hash. */
+ /** ECDSA over precomputed digest */
+ SIGN_ECDSA_WITH_NULL,
+ /** ECDSA with SHA-1 */
SIGN_ECDSA_WITH_SHA1,
- /** ECDSA with SHA-256 on the P-256 curve as in RFC 4754 */
+ /** ECDSA on the P-256 curve with SHA-256 as in RFC 4754 */
SIGN_ECDSA_256,
- /** ECDSA with SHA-384 on the P-384 curve as in RFC 4754 */
+ /** ECDSA on the P-384 curve with SHA-384 as in RFC 4754 */
SIGN_ECDSA_384,
- /** ECDSA with SHA-512 on the P-521 curve as in RFC 4754 */
+ /** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */
SIGN_ECDSA_521,
};
@@ -109,13 +115,21 @@ struct public_key_t {
/**
* Encrypt a chunk of data.
*
- * @param crypto chunk containing plaintext data
- * @param plain where to allocate encrypted data
+ * @param plain chunk containing plaintext data
+ * @param crypto where to allocate encrypted data
* @return TRUE if data successfully encrypted
*/
- bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain);
+ bool (*encrypt)(public_key_t *this, chunk_t plain, chunk_t *crypto);
/**
+ * Check if two public keys are equal.
+ *
+ * @param other other public key
+ * @return TRUE, if equality
+ */
+ bool (*equals)(public_key_t *this, public_key_t *other);
+
+ /**
* Get the strength of the key in bytes.
*
* @return strength of the key in bytes
@@ -152,4 +166,12 @@ struct public_key_t {
void (*destroy)(public_key_t *this);
};
+/**
+ * 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
+ */
+signature_scheme_t signature_scheme_from_oid(int oid);
+
#endif /** PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/credentials/keys/shared_key.c b/src/libstrongswan/credentials/keys/shared_key.c
index f55b52c3a..c6f141446 100644
--- a/src/libstrongswan/credentials/keys/shared_key.c
+++ b/src/libstrongswan/credentials/keys/shared_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: shared_key.c 3600 2008-03-14 15:11:29Z martin $
*/
#include "shared_key.h"
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 13ba9c6e2..ebd35a8a0 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -12,22 +12,20 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crypter.c 4880 2009-02-18 19:45:46Z tobias $
*/
+#include <asn1/oid.h>
+
#include "crypter.h"
-ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
- "UNDEFINED");
-ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
+ENUM_BEGIN(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32,
"DES_IV64",
- "DES",
- "3DES",
- "RC5",
- "IDEA",
- "CAST",
- "BLOWFISH",
+ "DES_CBC",
+ "3DES_CBC",
+ "RC5_CBC",
+ "IDEA_CBC",
+ "CAST_CBC",
+ "BLOWFISH_CBC",
"3IDEA",
"DES_IV32");
ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CCM_ICV16, ENCR_DES_IV32,
@@ -37,11 +35,128 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CCM_ICV16, ENCR_DES_IV
"AES_CCM_8",
"AES_CCM_12",
"AES_CCM_16");
-ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_AES_GCM_ICV16, ENCR_AES_CCM_ICV16,
+ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_NULL_AUTH_AES_GMAC, ENCR_AES_CCM_ICV16,
"AES_GCM_8",
"AES_GCM_12",
- "AES_GCM_16");
-ENUM_NEXT(encryption_algorithm_names, ENCR_DES_ECB, ENCR_DES_ECB, ENCR_AES_GCM_ICV16,
- "DES_ECB");
-ENUM_END(encryption_algorithm_names, ENCR_DES_ECB);
+ "AES_GCM_16",
+ "NULL_AES_GMAC");
+ENUM_NEXT(encryption_algorithm_names, ENCR_CAMELLIA_CBC, ENCR_CAMELLIA_CCM_ICV16, ENCR_NULL_AUTH_AES_GMAC,
+ "CAMELLIA_CBC",
+ "CAMELLIA_CTR",
+ "CAMELLIA_CCM_8",
+ "CAMELLIA_CCM_12",
+ "CAMELLIA_CCM_16");
+ENUM_NEXT(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_TWOFISH_CBC, ENCR_CAMELLIA_CCM_ICV16,
+ "UNDEFINED",
+ "DES_ECB",
+ "SERPENT_CBC",
+ "TWOFISH_CBC");
+ENUM_END(encryption_algorithm_names, ENCR_TWOFISH_CBC);
+
+/*
+ * Described in header.
+ */
+encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size)
+{
+ encryption_algorithm_t alg;
+ size_t alg_key_size;
+
+ switch (oid)
+ {
+ case OID_DES_CBC:
+ alg = ENCR_DES;
+ alg_key_size = 0;
+ break;
+ case OID_3DES_EDE_CBC:
+ alg = ENCR_3DES;
+ alg_key_size = 0;
+ break;
+ case OID_AES128_CBC:
+ alg = ENCR_AES_CBC;
+ alg_key_size = 128;
+ break;
+ case OID_AES192_CBC:
+ alg = ENCR_AES_CBC;
+ alg_key_size = 192;
+ break;
+ case OID_AES256_CBC:
+ alg = ENCR_AES_CBC;
+ alg_key_size = 256;
+ break;
+ case OID_CAMELLIA128_CBC:
+ alg = ENCR_CAMELLIA_CBC;
+ alg_key_size = 128;
+ break;
+ case OID_CAMELLIA192_CBC:
+ alg = ENCR_CAMELLIA_CBC;
+ alg_key_size = 192;
+ break;
+ case OID_CAMELLIA256_CBC:
+ alg = ENCR_CAMELLIA_CBC;
+ alg_key_size = 256;
+ break;
+ default:
+ alg = ENCR_UNDEFINED;
+ alg_key_size = 0;
+ }
+ if (key_size)
+ {
+ *key_size = alg_key_size;
+ }
+ return alg;
+}
+
+/*
+ * Described in header.
+ */
+int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size)
+{
+ int oid;
+
+ switch(alg)
+ {
+ case ENCR_DES:
+ oid = OID_DES_CBC;
+ break;
+ case ENCR_3DES:
+ oid = OID_3DES_EDE_CBC;
+ break;
+ case ENCR_AES_CBC:
+ switch (key_size)
+ {
+ case 128:
+ oid = OID_AES128_CBC;
+ break;
+ case 192:
+ oid = OID_AES192_CBC;
+ break;
+ case 256:
+ oid = OID_AES256_CBC;
+ break;
+ default:
+ oid = OID_UNKNOWN;
+ }
+ break;
+ case ENCR_CAMELLIA_CBC:
+ switch (key_size)
+ {
+ case 128:
+ oid = OID_CAMELLIA128_CBC;
+ break;
+ case 192:
+ oid = OID_CAMELLIA192_CBC;
+ break;
+ case 256:
+ oid = OID_CAMELLIA256_CBC;
+ break;
+ default:
+ oid = OID_UNKNOWN;
+ }
+ break;
+ default:
+ oid = OID_UNKNOWN;
+ }
+ return oid;
+}
+
diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h
index d61d98f95..2879e24c0 100644
--- a/src/libstrongswan/crypto/crypters/crypter.h
+++ b/src/libstrongswan/crypto/crypters/crypter.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crypter.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -33,28 +31,42 @@ typedef struct crypter_t crypter_t;
* Encryption algorithm, as in IKEv2 RFC 3.3.2.
*/
enum encryption_algorithm_t {
- ENCR_UNDEFINED = 1024,
- ENCR_DES_IV64 = 1,
- ENCR_DES = 2,
- ENCR_3DES = 3,
- ENCR_RC5 = 4,
- ENCR_IDEA = 5,
- ENCR_CAST = 6,
- ENCR_BLOWFISH = 7,
- ENCR_3IDEA = 8,
- ENCR_DES_IV32 = 9,
- ENCR_NULL = 11,
- ENCR_AES_CBC = 12,
- ENCR_AES_CTR = 13,
- ENCR_AES_CCM_ICV8 = 14,
- ENCR_AES_CCM_ICV12 = 15,
- ENCR_AES_CCM_ICV16 = 16,
- ENCR_AES_GCM_ICV8 = 18,
- ENCR_AES_GCM_ICV12 = 19,
- ENCR_AES_GCM_ICV16 = 20,
- ENCR_DES_ECB = 1025
+ ENCR_DES_IV64 = 1,
+ ENCR_DES = 2,
+ ENCR_3DES = 3,
+ ENCR_RC5 = 4,
+ ENCR_IDEA = 5,
+ ENCR_CAST = 6,
+ ENCR_BLOWFISH = 7,
+ ENCR_3IDEA = 8,
+ ENCR_DES_IV32 = 9,
+ ENCR_NULL = 11,
+ ENCR_AES_CBC = 12,
+ ENCR_AES_CTR = 13,
+ ENCR_AES_CCM_ICV8 = 14,
+ ENCR_AES_CCM_ICV12 = 15,
+ ENCR_AES_CCM_ICV16 = 16,
+ ENCR_AES_GCM_ICV8 = 18,
+ ENCR_AES_GCM_ICV12 = 19,
+ ENCR_AES_GCM_ICV16 = 20,
+ ENCR_NULL_AUTH_AES_GMAC = 21,
+ ENCR_CAMELLIA_CBC = 23,
+ ENCR_CAMELLIA_CTR = 24,
+ ENCR_CAMELLIA_CCM_ICV8 = 25,
+ ENCR_CAMELLIA_CCM_ICV12 = 26,
+ ENCR_CAMELLIA_CCM_ICV16 = 27,
+ ENCR_UNDEFINED = 1024,
+ ENCR_DES_ECB = 1025,
+ ENCR_SERPENT_CBC = 1026,
+ ENCR_TWOFISH_CBC = 1027
};
+#define DES_BLOCK_SIZE 8
+#define BLOWFISH_BLOCK_SIZE 8
+#define AES_BLOCK_SIZE 16
+#define SERPENT_BLOCK_SIZE 16
+#define TWOFISH_BLOCK_SIZE 16
+
/**
* enum name for encryption_algorithm_t.
*/
@@ -122,4 +134,22 @@ struct crypter_t {
void (*destroy) (crypter_t *this);
};
+/**
+ * Conversion of ASN.1 OID to encryption algorithm.
+ *
+ * @param oid ASN.1 OID
+ * @param key_size returns size of encryption key in bits
+ * @return encryption algorithm, ENCR_UNDEFINED if OID unsupported
+ */
+encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size);
+
+/**
+ * Conversion of encryption algorithm to ASN.1 OID.
+ *
+ * @param alg encryption algorithm
+ * @param key_size size of encryption key in bits
+ * @return ASN.1 OID, OID_UNKNOWN if OID is unknown
+ */
+int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size);
+
#endif /** CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
index dcc881f1d..fea8d0793 100644
--- a/src/libstrongswan/crypto/crypto_factory.c
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -11,14 +11,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: crypto_factory.c 4592 2008-11-05 16:21:57Z martin $
*/
#include "crypto_factory.h"
-#include <utils/linked_list.h>
+#include <debug.h>
#include <utils/mutex.h>
+#include <utils/linked_list.h>
+#include <crypto/crypto_tester.h>
typedef struct entry_t entry_t;
struct entry_t {
@@ -78,6 +78,21 @@ struct private_crypto_factory_t {
linked_list_t *dhs;
/**
+ * test manager to test crypto algorithms
+ */
+ crypto_tester_t *tester;
+
+ /**
+ * whether to test algorithms during registration
+ */
+ bool test_on_add;
+
+ /**
+ * whether to test algorithms on each crypto primitive construction
+ */
+ bool test_on_create;
+
+ /**
* rwlock to lock access to modules
*/
rwlock_t *lock;
@@ -92,13 +107,19 @@ static crypter_t* create_crypter(private_crypto_factory_t *this,
enumerator_t *enumerator;
entry_t *entry;
crypter_t *crypter = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->crypters->create_enumerator(this->crypters);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_crypter(this->tester, algo, key_size,
+ entry->create_crypter))
+ {
+ continue;
+ }
crypter = entry->create_crypter(algo, key_size);
if (crypter)
{
@@ -120,13 +141,19 @@ static signer_t* create_signer(private_crypto_factory_t *this,
enumerator_t *enumerator;
entry_t *entry;
signer_t *signer = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->signers->create_enumerator(this->signers);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_signer(this->tester, algo,
+ entry->create_signer))
+ {
+ continue;
+ }
signer = entry->create_signer(algo);
if (signer)
{
@@ -136,7 +163,7 @@ static signer_t* create_signer(private_crypto_factory_t *this,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
-
+
return signer;
}
@@ -156,6 +183,12 @@ static hasher_t* create_hasher(private_crypto_factory_t *this,
{
if (algo == HASH_PREFERRED || entry->algo == algo)
{
+ if (this->test_on_create && algo != HASH_PREFERRED &&
+ !this->tester->test_hasher(this->tester, algo,
+ entry->create_hasher))
+ {
+ continue;
+ }
hasher = entry->create_hasher(entry->algo);
if (hasher)
{
@@ -184,6 +217,11 @@ static prf_t* create_prf(private_crypto_factory_t *this,
{
if (entry->algo == algo)
{
+ if (this->test_on_create &&
+ !this->tester->test_prf(this->tester, algo, entry->create_prf))
+ {
+ continue;
+ }
prf = entry->create_prf(algo);
if (prf)
{
@@ -205,13 +243,18 @@ static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
entry_t *entry;
u_int diff = ~0;
rng_constructor_t constr = NULL;
-
+
this->lock->read_lock(this->lock);
enumerator = this->rngs->create_enumerator(this->rngs);
while (enumerator->enumerate(enumerator, &entry))
{ /* find the best matching quality, but at least as good as requested */
if (entry->algo >= quality && diff > entry->algo - quality)
{
+ if (this->test_on_create &&
+ !this->tester->test_rng(this->tester, quality, entry->create_rng))
+ {
+ continue;
+ }
diff = entry->algo - quality;
constr = entry->create_rng;
if (diff == 0)
@@ -264,13 +307,17 @@ static void add_crypter(private_crypto_factory_t *this,
encryption_algorithm_t algo,
crypter_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_crypter = create;
- this->lock->write_lock(this->lock);
- this->crypters->insert_last(this->crypters, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_crypter(this->tester, algo, 0, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_crypter = create;
+ this->lock->write_lock(this->lock);
+ this->crypters->insert_last(this->crypters, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -302,13 +349,17 @@ static void remove_crypter(private_crypto_factory_t *this,
static void add_signer(private_crypto_factory_t *this,
integrity_algorithm_t algo, signer_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_signer = create;
- this->lock->write_lock(this->lock);
- this->signers->insert_last(this->signers, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_signer(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_signer = create;
+ this->lock->write_lock(this->lock);
+ this->signers->insert_last(this->signers, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -340,13 +391,17 @@ static void remove_signer(private_crypto_factory_t *this,
static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
hasher_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_hasher = create;
- this->lock->write_lock(this->lock);
- this->hashers->insert_last(this->hashers, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_hasher(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_hasher = create;
+ this->lock->write_lock(this->lock);
+ this->hashers->insert_last(this->hashers, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -378,13 +433,17 @@ static void remove_hasher(private_crypto_factory_t *this,
static void add_prf(private_crypto_factory_t *this,
pseudo_random_function_t algo, prf_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = algo;
- entry->create_prf = create;
- this->lock->write_lock(this->lock);
- this->prfs->insert_last(this->prfs, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_prf(this->tester, algo, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = algo;
+ entry->create_prf = create;
+ this->lock->write_lock(this->lock);
+ this->prfs->insert_last(this->prfs, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -415,13 +474,17 @@ static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
static void add_rng(private_crypto_factory_t *this, rng_quality_t quality,
rng_constructor_t create)
{
- entry_t *entry = malloc_thing(entry_t);
-
- entry->algo = quality;
- entry->create_rng = create;
- this->lock->write_lock(this->lock);
- this->rngs->insert_last(this->rngs, entry);
- this->lock->unlock(this->lock);
+ if (!this->test_on_add ||
+ this->tester->test_rng(this->tester, quality, create))
+ {
+ entry_t *entry = malloc_thing(entry_t);
+
+ entry->algo = quality;
+ entry->create_rng = create;
+ this->lock->write_lock(this->lock);
+ this->rngs->insert_last(this->rngs, entry);
+ this->lock->unlock(this->lock);
+ }
}
/**
@@ -605,6 +668,30 @@ static enumerator_t* create_dh_enumerator(private_crypto_factory_t *this)
}
/**
+ * Implementation of crypto_factory_t.add_test_vector
+ */
+static void add_test_vector(private_crypto_factory_t *this,
+ transform_type_t type, void *vector)
+{
+ switch (type)
+ {
+ case ENCRYPTION_ALGORITHM:
+ return this->tester->add_crypter_vector(this->tester, vector);
+ case INTEGRITY_ALGORITHM:
+ return this->tester->add_signer_vector(this->tester, vector);
+ case HASH_ALGORITHM:
+ return this->tester->add_hasher_vector(this->tester, vector);
+ case PSEUDO_RANDOM_FUNCTION:
+ return this->tester->add_prf_vector(this->tester, vector);
+ case RANDOM_NUMBER_GENERATOR:
+ return this->tester->add_rng_vector(this->tester, vector);
+ default:
+ DBG1("%N test vectors not supported, ignored",
+ transform_type_names, type);
+ }
+}
+
+/**
* Implementation of crypto_factory_t.destroy
*/
static void destroy(private_crypto_factory_t *this)
@@ -615,6 +702,7 @@ static void destroy(private_crypto_factory_t *this)
this->prfs->destroy_function(this->prfs, free);
this->rngs->destroy_function(this->rngs, free);
this->dhs->destroy_function(this->dhs, free);
+ this->tester->destroy(this->tester);
this->lock->destroy(this->lock);
free(this);
}
@@ -649,6 +737,7 @@ crypto_factory_t *crypto_factory_create()
this->public.create_hasher_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_hasher_enumerator;
this->public.create_prf_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_prf_enumerator;
this->public.create_dh_enumerator = (enumerator_t*(*)(crypto_factory_t*))create_dh_enumerator;
+ this->public.add_test_vector = (void(*)(crypto_factory_t*, transform_type_t type, ...))add_test_vector;
this->public.destroy = (void(*)(crypto_factory_t*))destroy;
this->crypters = linked_list_create();
@@ -658,6 +747,11 @@ crypto_factory_t *crypto_factory_create()
this->rngs = linked_list_create();
this->dhs = linked_list_create();
this->lock = rwlock_create(RWLOCK_DEFAULT);
+ this->tester = crypto_tester_create();
+ this->test_on_add = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_add", FALSE);
+ this->test_on_create = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.on_create", FALSE);
return &this->public;
}
diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h
index e2d2de71a..f1ebcf90a 100644
--- a/src/libstrongswan/crypto/crypto_factory.h
+++ b/src/libstrongswan/crypto/crypto_factory.h
@@ -30,6 +30,7 @@ typedef struct crypto_factory_t crypto_factory_t;
#include <crypto/prfs/prf.h>
#include <crypto/rngs/rng.h>
#include <crypto/diffie_hellman.h>
+#include <crypto/transform.h>
/**
* Constructor function for crypters
@@ -257,9 +258,17 @@ struct crypto_factory_t {
enumerator_t* (*create_dh_enumerator)(crypto_factory_t *this);
/**
- * Destroy a crypto_factory instance.
- */
- void (*destroy)(crypto_factory_t *this);
+ * Add a test vector to the crypto factory.
+ *
+ * @param type type of the test vector
+ * @param ... pointer to a test vector, defined in crypto_tester.h
+ */
+ void (*add_test_vector)(crypto_factory_t *this, transform_type_t type, ...);
+
+ /**
+ * Destroy a crypto_factory instance.
+ */
+ void (*destroy)(crypto_factory_t *this);
};
/**
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
new file mode 100644
index 000000000..b0b5aa969
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -0,0 +1,629 @@
+/*
+ * 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 "crypto_tester.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
+typedef struct private_crypto_tester_t private_crypto_tester_t;
+
+/**
+ * Private data of an crypto_tester_t object.
+ */
+struct private_crypto_tester_t {
+
+ /**
+ * Public crypto_tester_t interface.
+ */
+ crypto_tester_t public;
+
+ /**
+ * List of crypter test vectors
+ */
+ linked_list_t *crypter;
+
+ /**
+ * List of signer test vectors
+ */
+ linked_list_t *signer;
+
+ /**
+ * List of hasher test vectors
+ */
+ linked_list_t *hasher;
+
+ /**
+ * List of PRF test vectors
+ */
+ linked_list_t *prf;
+
+ /**
+ * List of RNG test vectors
+ */
+ linked_list_t *rng;
+
+ /**
+ * Is a test vector required to pass a test?
+ */
+ bool required;
+
+ /**
+ * should we run RNG_TRUE tests? Enough entropy?
+ */
+ bool rng_true;
+};
+
+/**
+ * Implementation of crypto_tester_t.test_crypter
+ */
+static bool test_crypter(private_crypto_tester_t *this,
+ encryption_algorithm_t alg, size_t key_size, crypter_constructor_t create)
+{
+ enumerator_t *enumerator;
+ crypter_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->crypter->create_enumerator(this->crypter);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ crypter_t *crypter;
+ chunk_t key, plain, cipher, iv;
+
+ if (vector->alg != alg)
+ {
+ continue;
+ }
+ if (key_size && key_size != vector->key_size)
+ { /* test only vectors with a specific key size, if key size given */
+ continue;
+ }
+ crypter = create(alg, vector->key_size);
+ if (!crypter)
+ { /* key size not supported... */
+ continue;
+ }
+
+ failed = FALSE;
+ tested++;
+
+ key = chunk_create(vector->key, crypter->get_key_size(crypter));
+ crypter->set_key(crypter, key);
+ iv = chunk_create(vector->iv, crypter->get_block_size(crypter));
+
+ /* allocated encryption */
+ plain = chunk_create(vector->plain, vector->len);
+ crypter->encrypt(crypter, plain, iv, &cipher);
+ if (!memeq(vector->cipher, cipher.ptr, cipher.len))
+ {
+ failed = TRUE;
+ }
+ /* inline decryption */
+ crypter->decrypt(crypter, cipher, iv, NULL);
+ if (!memeq(vector->plain, cipher.ptr, cipher.len))
+ {
+ failed = TRUE;
+ }
+ free(cipher.ptr);
+ /* allocated decryption */
+ cipher = chunk_create(vector->cipher, vector->len);
+ crypter->decrypt(crypter, cipher, iv, &plain);
+ if (!memeq(vector->plain, plain.ptr, plain.len))
+ {
+ failed = TRUE;
+ }
+ /* inline encryption */
+ crypter->encrypt(crypter, plain, iv, NULL);
+ if (!memeq(vector->cipher, plain.ptr, plain.len))
+ {
+ failed = TRUE;
+ }
+ free(plain.ptr);
+
+ crypter->destroy(crypter);
+ if (failed)
+ {
+ DBG1("disabled %N: test vector %d failed",
+ encryption_algorithm_names, alg, tested);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1("%s %N: no test vectors found",
+ this->required ? "disabled" : "enabled ",
+ encryption_algorithm_names, alg);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ DBG1("enabled %N: successfully passed %d test vectors",
+ encryption_algorithm_names, alg, tested);
+ }
+ return !failed;
+}
+
+/**
+ * Implementation of crypto_tester_t.test_signer
+ */
+static bool test_signer(private_crypto_tester_t *this,
+ integrity_algorithm_t alg, signer_constructor_t create)
+{
+ enumerator_t *enumerator;
+ signer_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->signer->create_enumerator(this->signer);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ signer_t *signer;
+ chunk_t key, data, mac;
+
+ if (vector->alg != alg)
+ {
+ continue;
+ }
+
+ tested++;
+ signer = create(alg);
+ if (!signer)
+ {
+ DBG1("disabled %N: creating instance failed",
+ integrity_algorithm_names, alg);
+ failed = TRUE;
+ break;
+ }
+
+ failed = FALSE;
+
+ key = chunk_create(vector->key, signer->get_key_size(signer));
+ signer->set_key(signer, key);
+
+ /* allocated signature */
+ data = chunk_create(vector->data, vector->len);
+ signer->allocate_signature(signer, data, &mac);
+ if (mac.len != signer->get_block_size(signer))
+ {
+ failed = TRUE;
+ }
+ if (!memeq(vector->mac, mac.ptr, mac.len))
+ {
+ failed = TRUE;
+ }
+ /* signature to existing buffer */
+ memset(mac.ptr, 0, mac.len);
+ signer->get_signature(signer, data, mac.ptr);
+ if (!memeq(vector->mac, mac.ptr, mac.len))
+ {
+ failed = TRUE;
+ }
+ /* signature verification, good case */
+ if (!signer->verify_signature(signer, data, mac))
+ {
+ failed = TRUE;
+ }
+ /* signature verification, bad case */
+ *(mac.ptr + mac.len - 1) += 1;
+ if (signer->verify_signature(signer, data, mac))
+ {
+ failed = TRUE;
+ }
+ /* signature to existing buffer, using append mode */
+ if (data.len > 2)
+ {
+ memset(mac.ptr, 0, mac.len);
+ signer->allocate_signature(signer, chunk_create(data.ptr, 1), NULL);
+ signer->get_signature(signer, chunk_create(data.ptr + 1, 1), NULL);
+ signer->get_signature(signer, chunk_skip(data, 2), mac.ptr);
+ if (!memeq(vector->mac, mac.ptr, mac.len))
+ {
+ failed = TRUE;
+ }
+ }
+ free(mac.ptr);
+
+ signer->destroy(signer);
+ if (failed)
+ {
+ DBG1("disabled %N: test vector %d failed",
+ integrity_algorithm_names, alg, tested);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1("%s %N: no test vectors found",
+ this->required ? "disabled" : "enabled ",
+ integrity_algorithm_names, alg);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ DBG1("enabled %N: successfully passed %d test vectors",
+ integrity_algorithm_names, alg, tested);
+ }
+ return !failed;
+}
+
+/**
+ * Implementation of hasher_t.test_hasher
+ */
+static bool test_hasher(private_crypto_tester_t *this, hash_algorithm_t alg,
+ hasher_constructor_t create)
+{
+ enumerator_t *enumerator;
+ hasher_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->hasher->create_enumerator(this->hasher);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ hasher_t *hasher;
+ chunk_t data, hash;
+
+ if (vector->alg != alg)
+ {
+ continue;
+ }
+
+ tested++;
+ hasher = create(alg);
+ if (!hasher)
+ {
+ DBG1("disabled %N: creating instance failed",
+ hash_algorithm_names, alg);
+ failed = TRUE;
+ break;
+ }
+
+ failed = FALSE;
+
+ /* allocated hash */
+ data = chunk_create(vector->data, vector->len);
+ hasher->allocate_hash(hasher, data, &hash);
+ if (hash.len != hasher->get_hash_size(hasher))
+ {
+ failed = TRUE;
+ }
+ if (!memeq(vector->hash, hash.ptr, hash.len))
+ {
+ failed = TRUE;
+ }
+ /* hash to existing buffer */
+ memset(hash.ptr, 0, hash.len);
+ hasher->get_hash(hasher, data, hash.ptr);
+ if (!memeq(vector->hash, hash.ptr, hash.len))
+ {
+ failed = TRUE;
+ }
+ /* hasher to existing buffer, using append mode */
+ if (data.len > 2)
+ {
+ memset(hash.ptr, 0, hash.len);
+ hasher->allocate_hash(hasher, chunk_create(data.ptr, 1), NULL);
+ hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL);
+ hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr);
+ if (!memeq(vector->hash, hash.ptr, hash.len))
+ {
+ failed = TRUE;
+ }
+ }
+ free(hash.ptr);
+
+ hasher->destroy(hasher);
+ if (failed)
+ {
+ DBG1("disabled %N: test vector %d failed",
+ hash_algorithm_names, alg), tested;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1("%s %N: no test vectors found",
+ this->required ? "disabled" : "enabled ",
+ hash_algorithm_names, alg);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ DBG1("enabled %N: successfully passed %d test vectors",
+ hash_algorithm_names, alg, tested);
+ }
+ return !failed;
+}
+
+/**
+ * Implementation of crypto_tester_t.test_prf
+ */
+static bool test_prf(private_crypto_tester_t *this,
+ pseudo_random_function_t alg, prf_constructor_t create)
+{
+ enumerator_t *enumerator;
+ prf_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->prf->create_enumerator(this->prf);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ prf_t *prf;
+ chunk_t key, seed, out;
+
+ if (vector->alg != alg)
+ {
+ continue;
+ }
+
+ tested++;
+ prf = create(alg);
+ if (!prf)
+ {
+ DBG1("disabled %N: creating instance failed",
+ pseudo_random_function_names, alg);
+ failed = TRUE;
+ break;
+ }
+
+ failed = FALSE;
+
+ key = chunk_create(vector->key, vector->key_size);
+ prf->set_key(prf, key);
+
+ /* allocated bytes */
+ seed = chunk_create(vector->seed, vector->len);
+ prf->allocate_bytes(prf, seed, &out);
+ if (out.len != prf->get_block_size(prf))
+ {
+ failed = TRUE;
+ }
+ if (!memeq(vector->out, out.ptr, out.len))
+ {
+ failed = TRUE;
+ }
+ /* bytes to existing buffer */
+ memset(out.ptr, 0, out.len);
+ if (vector->stateful)
+ {
+ prf->set_key(prf, key);
+ }
+ prf->get_bytes(prf, seed, out.ptr);
+ if (!memeq(vector->out, out.ptr, out.len))
+ {
+ failed = TRUE;
+ }
+ /* bytes to existing buffer, using append mode */
+ if (seed.len > 2)
+ {
+ memset(out.ptr, 0, out.len);
+ if (vector->stateful)
+ {
+ prf->set_key(prf, key);
+ }
+ prf->allocate_bytes(prf, chunk_create(seed.ptr, 1), NULL);
+ prf->get_bytes(prf, chunk_create(seed.ptr + 1, 1), NULL);
+ prf->get_bytes(prf, chunk_skip(seed, 2), out.ptr);
+ if (!memeq(vector->out, out.ptr, out.len))
+ {
+ failed = TRUE;
+ }
+ }
+ free(out.ptr);
+
+ prf->destroy(prf);
+ if (failed)
+ {
+ DBG1("disabled %N: test vector %d failed",
+ pseudo_random_function_names, alg, tested);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1("%s %N: no test vectors found",
+ this->required ? "disabled" : "enabled ",
+ pseudo_random_function_names, alg);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ DBG1("enabled %N: successfully passed %d test vectors",
+ pseudo_random_function_names, alg, tested);
+ }
+ return !failed;
+}
+
+/**
+ * Implementation of crypto_tester_t.test_rng
+ */
+static bool test_rng(private_crypto_tester_t *this, rng_quality_t quality,
+ rng_constructor_t create)
+{
+ enumerator_t *enumerator;
+ rng_test_vector_t *vector;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ if (!this->rng_true && quality == RNG_TRUE)
+ {
+ DBG1("enabled %N: skipping test (disabled by config)",
+ rng_quality_names, quality);
+ return TRUE;
+ }
+
+ enumerator = this->rng->create_enumerator(this->rng);
+ while (enumerator->enumerate(enumerator, &vector))
+ {
+ rng_t *rng;
+ chunk_t data;
+
+ if (vector->quality != quality)
+ {
+ continue;
+ }
+
+ tested++;
+ rng = create(quality);
+ if (!rng)
+ {
+ DBG1("disabled %N: creating instance failed",
+ rng_quality_names, quality);
+ failed = TRUE;
+ break;
+ }
+
+ failed = FALSE;
+
+ /* allocated bytes */
+ rng->allocate_bytes(rng, vector->len, &data);
+ if (data.len != vector->len)
+ {
+ failed = TRUE;
+ }
+ if (!vector->test(vector->user, data))
+ {
+ failed = TRUE;
+ }
+ /* bytes to existing buffer */
+ memset(data.ptr, 0, data.len);
+ rng->get_bytes(rng, vector->len, data.ptr);
+ if (!vector->test(vector->user, data))
+ {
+ failed = TRUE;
+ }
+ free(data.ptr);
+
+ rng->destroy(rng);
+ if (failed)
+ {
+ DBG1("disabled %N: test vector %d failed",
+ rng_quality_names, quality, tested);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1("%s %N: no test vectors found",
+ this->required ? ", disabled" : "enabled ",
+ rng_quality_names, quality);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ DBG1("enabled %N: successfully passed %d test vectors",
+ rng_quality_names, quality, tested);
+ }
+ return !failed;
+}
+
+/**
+ * Implementation of crypter_tester_t.add_crypter_vector
+ */
+static void add_crypter_vector(private_crypto_tester_t *this,
+ crypter_test_vector_t *vector)
+{
+ this->crypter->insert_last(this->crypter, vector);
+}
+
+/**
+ * Implementation of crypter_tester_t.add_signer_vector
+ */
+static void add_signer_vector(private_crypto_tester_t *this,
+ signer_test_vector_t *vector)
+{
+ this->signer->insert_last(this->signer, vector);
+}
+
+/**
+ * Implementation of crypter_tester_t.add_hasher_vector
+ */
+static void add_hasher_vector(private_crypto_tester_t *this,
+ hasher_test_vector_t *vector)
+{
+ this->hasher->insert_last(this->hasher, vector);
+}
+
+/**
+ * Implementation of crypter_tester_t.add_prf_vector
+ */
+static void add_prf_vector(private_crypto_tester_t *this,
+ prf_test_vector_t *vector)
+{
+ this->prf->insert_last(this->prf, vector);
+}
+
+/**
+ * Implementation of crypter_tester_t.add_rng_vector
+ */
+static void add_rng_vector(private_crypto_tester_t *this,
+ rng_test_vector_t *vector)
+{
+ this->rng->insert_last(this->rng, vector);
+}
+
+/**
+ * Implementation of crypto_tester_t.destroy.
+ */
+static void destroy(private_crypto_tester_t *this)
+{
+ this->crypter->destroy(this->crypter);
+ this->signer->destroy(this->signer);
+ this->hasher->destroy(this->hasher);
+ this->prf->destroy(this->prf);
+ this->rng->destroy(this->rng);
+ free(this);
+}
+
+/**
+ * See header
+ */
+crypto_tester_t *crypto_tester_create()
+{
+ private_crypto_tester_t *this = malloc_thing(private_crypto_tester_t);
+
+ this->public.test_crypter = (bool(*)(crypto_tester_t*, encryption_algorithm_t alg,size_t key_size, crypter_constructor_t create))test_crypter;
+ this->public.test_signer = (bool(*)(crypto_tester_t*, integrity_algorithm_t alg, signer_constructor_t create))test_signer;
+ this->public.test_hasher = (bool(*)(crypto_tester_t*, hash_algorithm_t alg, hasher_constructor_t create))test_hasher;
+ this->public.test_prf = (bool(*)(crypto_tester_t*, pseudo_random_function_t alg, prf_constructor_t create))test_prf;
+ this->public.test_rng = (bool(*)(crypto_tester_t*, rng_quality_t quality, rng_constructor_t create))test_rng;
+ this->public.add_crypter_vector = (void(*)(crypto_tester_t*, crypter_test_vector_t *vector))add_crypter_vector;
+ this->public.add_signer_vector = (void(*)(crypto_tester_t*, signer_test_vector_t *vector))add_signer_vector;
+ this->public.add_hasher_vector = (void(*)(crypto_tester_t*, hasher_test_vector_t *vector))add_hasher_vector;
+ this->public.add_prf_vector = (void(*)(crypto_tester_t*, prf_test_vector_t *vector))add_prf_vector;
+ this->public.add_rng_vector = (void(*)(crypto_tester_t*, rng_test_vector_t *vector))add_rng_vector;
+ this->public.destroy = (void(*)(crypto_tester_t*))destroy;
+
+ this->crypter = linked_list_create();
+ this->signer = linked_list_create();
+ this->hasher = linked_list_create();
+ this->prf = linked_list_create();
+ this->rng = linked_list_create();
+
+ this->required = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.required", FALSE);
+ this->rng_true = lib->settings->get_bool(lib->settings,
+ "libstrongswan.crypto_test.rng_true", FALSE);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h
new file mode 100644
index 000000000..d2929f33d
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_tester.h
@@ -0,0 +1,205 @@
+/*
+ * 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 crypto_tester crypto_tester
+ * @{ @ingroup crypto
+ */
+
+#ifndef CRYPTO_TESTER_H_
+#define CRYPTO_TESTER_H_
+
+typedef struct crypto_tester_t crypto_tester_t;
+
+#include <crypto/crypto_factory.h>
+
+typedef struct crypter_test_vector_t crypter_test_vector_t;
+typedef struct signer_test_vector_t signer_test_vector_t;
+typedef struct hasher_test_vector_t hasher_test_vector_t;
+typedef struct prf_test_vector_t prf_test_vector_t;
+typedef struct rng_test_vector_t rng_test_vector_t;
+
+struct crypter_test_vector_t {
+ /** encryption algorithm this vector tests */
+ encryption_algorithm_t alg;
+ /** key length to use, in bytes */
+ size_t key_size;
+ /** encryption key of test vector */
+ u_char *key;
+ /** initialization vector, using crypters blocksize bytes */
+ u_char *iv;
+ /** length of plain and cipher text */
+ size_t len;
+ /** plain text */
+ u_char *plain;
+ /** cipher text */
+ u_char *cipher;
+};
+
+struct signer_test_vector_t {
+ /** signer algorithm this test vector tests */
+ pseudo_random_function_t alg;
+ /** key to use, with a length the algorithm expects */
+ u_char *key;
+ /** size of the input data */
+ size_t len;
+ /** input data */
+ u_char *data;
+ /** expected output, with ouput size of the tested algorithm */
+ u_char *mac;
+};
+
+struct hasher_test_vector_t {
+ /** hash algorithm this test vector tests */
+ hash_algorithm_t alg;
+ /** length of the input data */
+ size_t len;
+ /** input data */
+ u_char *data;
+ /** expected hash, with hash size of the tested algorithm */
+ u_char *hash;
+};
+
+struct prf_test_vector_t {
+ /** prf algorithm this test vector tests */
+ pseudo_random_function_t alg;
+ /** is this PRF stateful? */
+ bool stateful;
+ /** key length to use, in bytes */
+ size_t key_size;
+ /** key to use */
+ u_char *key;
+ /** size of the seed data */
+ size_t len;
+ /** seed data */
+ u_char *seed;
+ /** expected output, with block size of the tested algorithm */
+ u_char *out;
+};
+
+/**
+ * Test vector for a RNG.
+ *
+ * Contains a callback function to analyze the output of a RNG,
+ */
+struct rng_test_vector_t {
+ /** quality of random data this test vector tests */
+ rng_quality_t quality;
+ /** callback function to test RNG output, returns TRUE if data ok */
+ bool (*test)(void *user, chunk_t data);
+ /** number of bytes the function requests */
+ size_t len;
+ /** user data passed back to the test() function on invocation */
+ void *user;
+};
+
+/**
+ * Cryptographic primitive testing framework.
+ */
+struct crypto_tester_t {
+
+ /**
+ * Test a crypter algorithm, optionally using a specified key size.
+ *
+ * @param alg algorithm to test
+ * @param key_size key size to test, 0 for all
+ * @param create constructor function for the crypter
+ * @return TRUE if test passed
+ */
+ bool (*test_crypter)(crypto_tester_t *this, encryption_algorithm_t alg,
+ size_t key_size, crypter_constructor_t create);
+ /**
+ * Test a signer algorithm.
+ *
+ * @param alg algorithm to test
+ * @param create constructor function for the signer
+ * @return TRUE if test passed
+ */
+ bool (*test_signer)(crypto_tester_t *this, integrity_algorithm_t alg,
+ signer_constructor_t create);
+ /**
+ * Test a hasher algorithm.
+ *
+ * @param alg algorithm to test
+ * @param create constructor function for the hasher
+ * @return TRUE if test passed
+ */
+ bool (*test_hasher)(crypto_tester_t *this, hash_algorithm_t alg,
+ hasher_constructor_t create);
+ /**
+ * Test a PRF algorithm.
+ *
+ * @param alg algorithm to test
+ * @param create constructor function for the PRF
+ * @return TRUE if test passed
+ */
+ bool (*test_prf)(crypto_tester_t *this, pseudo_random_function_t alg,
+ prf_constructor_t create);
+ /**
+ * Test a RNG implementation.
+ *
+ * @param alg algorithm to test
+ * @param create constructor function for the RNG
+ * @return TRUE if test passed
+ */
+ bool (*test_rng)(crypto_tester_t *this, rng_quality_t quality,
+ rng_constructor_t create);
+ /**
+ * Add a test vector to test a crypter.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_crypter_vector)(crypto_tester_t *this,
+ crypter_test_vector_t *vector);
+ /**
+ * Add a test vector to test a signer.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_signer_vector)(crypto_tester_t *this,
+ signer_test_vector_t *vector);
+ /**
+ * Add a test vector to test a hasher.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_hasher_vector)(crypto_tester_t *this,
+ hasher_test_vector_t *vector);
+ /**
+ * Add a test vector to test a PRF.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_prf_vector)(crypto_tester_t *this, prf_test_vector_t *vector);
+
+ /**
+ * Add a test vector to test a RNG.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_rng_vector)(crypto_tester_t *this, rng_test_vector_t *vector);
+
+ /**
+ * Destroy a crypto_tester_t.
+ */
+ void (*destroy)(crypto_tester_t *this);
+};
+
+/**
+ * Create a crypto_tester instance.
+ */
+crypto_tester_t *crypto_tester_create();
+
+#endif /* CRYPTO_TESTER_ @}*/
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 53c3a1632..18d532697 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -12,30 +12,28 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: diffie_hellman.c 4685 2008-11-22 16:14:55Z martin $
*/
#include "diffie_hellman.h"
ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT,
"MODP_NONE",
- "MODP_768_BIT",
- "MODP_1024_BIT");
+ "MODP_768",
+ "MODP_1024");
ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT,
- "MODP_1536_BIT");
+ "MODP_1536");
ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT,
- "MODP_2048_BIT",
- "MODP_3072_BIT",
- "MODP_4096_BIT",
- "MODP_6144_BIT",
- "MODP_8192_BIT",
- "ECP_256_BIT",
- "ECP_384_BIT",
- "ECP_521_BIT");
+ "MODP_2048",
+ "MODP_3072",
+ "MODP_4096",
+ "MODP_6144",
+ "MODP_8192",
+ "ECP_256",
+ "ECP_384",
+ "ECP_521");
ENUM_NEXT(diffie_hellman_group_names, ECP_192_BIT, ECP_224_BIT, ECP_521_BIT,
- "ECP_192_BIT",
- "ECP_224_BIT");
+ "ECP_192",
+ "ECP_224");
ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, ECP_224_BIT,
"MODP_NULL");
ENUM_END(diffie_hellman_group_names, MODP_NULL);
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 5aaba383e..a40a73526 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: diffie_hellman.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index cf507442d..c58c2ad42 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -13,24 +13,22 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hasher.c 4880 2009-02-18 19:45:46Z tobias $
*/
#include "hasher.h"
#include <asn1/oid.h>
-ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_MD4,
+ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
"HASH_UNKNOWN",
"HASH_PREFERRED",
"HASH_MD2",
+ "HASH_MD4",
"HASH_MD5",
"HASH_SHA1",
"HASH_SHA256",
"HASH_SHA384",
- "HASH_SHA512",
- "HASH_MD4"
+ "HASH_SHA512"
);
/*
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index 1db5c14cc..098739fa3 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -13,13 +13,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hasher.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
- * @defgroup traffic_selector traffic_selector
- * @{ @ingroup config
+ * @defgroup hasher hasher
+ * @{ @ingroup crypto
*/
#ifndef HASHER_H_
@@ -39,12 +37,12 @@ enum hash_algorithm_t {
/** preferred hash function, general purpose */
HASH_PREFERRED = 1,
HASH_MD2 = 2,
- HASH_MD5 = 3,
- HASH_SHA1 = 4,
- HASH_SHA256 = 5,
- HASH_SHA384 = 6,
- HASH_SHA512 = 7,
- HASH_MD4 = 8,
+ HASH_MD4 = 3,
+ HASH_MD5 = 4,
+ HASH_SHA1 = 5,
+ HASH_SHA256 = 6,
+ HASH_SHA384 = 7,
+ HASH_SHA512 = 8
};
#define HASH_SIZE_MD2 16
diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c
index 1c1b5a586..525ea9db5 100644
--- a/src/libstrongswan/crypto/pkcs9.c
+++ b/src/libstrongswan/crypto/pkcs9.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pkcs9.c 3891 2008-04-28 16:00:52Z andreas $
*/
#include <library.h>
diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h
index 698f3c172..80d915701 100644
--- a/src/libstrongswan/crypto/pkcs9.h
+++ b/src/libstrongswan/crypto/pkcs9.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pkcs9.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c
index 3d37d4ef7..a4fc377ef 100644
--- a/src/libstrongswan/crypto/prf_plus.c
+++ b/src/libstrongswan/crypto/prf_plus.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: prf_plus.c 4524 2008-10-29 14:12:54Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/crypto/prf_plus.h b/src/libstrongswan/crypto/prf_plus.h
index 4c98e4ad1..2e5b66152 100644
--- a/src/libstrongswan/crypto/prf_plus.h
+++ b/src/libstrongswan/crypto/prf_plus.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: prf_plus.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c
index 812f6278d..8681a5b97 100644
--- a/src/libstrongswan/crypto/prfs/prf.c
+++ b/src/libstrongswan/crypto/prfs/prf.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: prf.c 3619 2008-03-19 14:02:52Z martin $
*/
#include "prf.h"
@@ -23,13 +21,14 @@ ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1,
"PRF_FIPS_SHA1_160",
"PRF_FIPS_DES",
"PRF_KEYED_SHA1");
-ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_KEYED_SHA1,
+ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_AES128_CMAC, PRF_KEYED_SHA1,
"PRF_HMAC_MD5",
"PRF_HMAC_SHA1",
"PRF_HMAC_TIGER",
- "PRF_AES128_CBC",
+ "PRF_AES128_XCBC",
"PRF_HMAC_SHA2_256",
"PRF_HMAC_SHA2_384",
- "PRF_HMAC_SHA2_512");
-ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512);
+ "PRF_HMAC_SHA2_512",
+ "PRF_AES128_CMAC");
+ENUM_END(pseudo_random_function_names, PRF_AES128_CMAC);
diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h
index e2b4f6fe0..f2a5afc45 100644
--- a/src/libstrongswan/crypto/prfs/prf.h
+++ b/src/libstrongswan/crypto/prfs/prf.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: prf.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -37,21 +35,25 @@ typedef struct prf_t prf_t;
*/
enum pseudo_random_function_t {
PRF_UNDEFINED = 1024,
- /** Implemented via hmac_prf_t. */
+ /** RFC2104 */
PRF_HMAC_MD5 = 1,
- /** Implemented via hmac_prf_t. */
+ /** RFC2104 */
PRF_HMAC_SHA1 = 2,
+ /** RFC2104 */
PRF_HMAC_TIGER = 3,
+ /** RFC4434 */
PRF_AES128_XCBC = 4,
- /** Implemented via hmac_prf_t. */
+ /** RFC4868 */
PRF_HMAC_SHA2_256 = 5,
- /** Implemented via hmac_prf_t. */
+ /** RFC4868. */
PRF_HMAC_SHA2_384 = 6,
- /** Implemented via hmac_prf_t. */
+ /** RFC4868 */
PRF_HMAC_SHA2_512 = 7,
- /** Implemented via fips_prf_t, other output sizes would be possible */
+ /** RFC4615 */
+ PRF_AES128_CMAC = 8,
+ /** FIPS 186-2-change1 */
PRF_FIPS_SHA1_160 = 1025,
- /** Could be implemented via fips_prf_t, uses fixed output size of 160bit */
+ /** FIPS 186-2-change1, uses fixed output size of 160bit */
PRF_FIPS_DES = 1026,
/**
* Keyed hash algorithm using SHA1, used in EAP-AKA:
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c
new file mode 100644
index 000000000..14321e070
--- /dev/null
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c
@@ -0,0 +1,270 @@
+/* C code produced by gperf version 3.0.3 */
+/* Command-line: /usr/bin/gperf -N proposal_get_token -m 10 -C -G -c -t -D */
+/* Computed positions: -k'1,5,7,10,$' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+
+/* proposal keywords
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <string.h>
+
+#include <crypto/transform.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/diffie_hellman.h>
+
+struct proposal_token {
+ char *name;
+ transform_type_t type;
+ u_int16_t algorithm;
+ u_int16_t keysize;
+};
+
+#define TOTAL_KEYWORDS 87
+#define MIN_WORD_LENGTH 3
+#define MAX_WORD_LENGTH 12
+#define MIN_HASH_VALUE 4
+#define MAX_HASH_VALUE 129
+/* maximum key range = 126, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+hash (str, len)
+ register const char *str;
+ register unsigned int len;
+{
+ static const unsigned char asso_values[] =
+ {
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 11,
+ 2, 15, 5, 27, 21, 8, 5, 0, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 39, 130, 24, 0, 1,
+ 8, 2, 50, 0, 9, 53, 130, 130, 0, 130,
+ 42, 0, 130, 130, 5, 9, 34, 4, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[9]];
+ /*FALLTHROUGH*/
+ case 9:
+ case 8:
+ case 7:
+ hval += asso_values[(unsigned char)str[6]];
+ /*FALLTHROUGH*/
+ case 6:
+ case 5:
+ hval += asso_values[(unsigned char)str[4]];
+ /*FALLTHROUGH*/
+ case 4:
+ case 3:
+ case 2:
+ case 1:
+ hval += asso_values[(unsigned char)str[0]+1];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+static const struct proposal_token wordlist[] =
+ {
+ {"null", ENCRYPTION_ALGORITHM, ENCR_NULL, 0},
+ {"aes192", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192},
+ {"aesxcbc", INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0},
+ {"aes", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
+ {"aes128", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128},
+ {"des", ENCRYPTION_ALGORITHM, ENCR_DES, 0},
+ {"aes192ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192},
+ {"aes128ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128},
+ {"3des", ENCRYPTION_ALGORITHM, ENCR_3DES, 0},
+ {"aes192gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"aes192ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
+ {"aes128gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
+ {"aes128ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
+ {"aes192gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
+ {"aes192ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
+ {"aes128gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
+ {"aes128ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
+ {"aes192gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"aes192ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"aes128gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
+ {"aes128ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"aes192gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192},
+ {"aes192ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192},
+ {"aes128gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128},
+ {"aes128ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128},
+ {"cast128", ENCRYPTION_ALGORITHM, ENCR_CAST, 128},
+ {"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
+ {"aes192ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192},
+ {"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
+ {"aes128ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128},
+ {"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256},
+ {"aes192gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192},
+ {"aes192ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192},
+ {"aes128gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128},
+ {"aes128ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128},
+ {"aes256gcm8", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
+ {"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
+ {"sha1", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
+ {"aes256gcm12", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
+ {"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"sha512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
+ {"aes256", ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256},
+ {"aes256gcm128", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
+ {"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
+ {"modp8192", DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0},
+ {"ecp192", DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0},
+ {"aes256gcm96", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256},
+ {"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
+ {"sha", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0},
+ {"modp2048", DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0},
+ {"ecp224", DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0},
+ {"aes256gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256},
+ {"aes256ccm64", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
+ {"ecp384", DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0},
+ {"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
+ {"modp1024", DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0},
+ {"ecp521", DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0},
+ {"aes256gcm16", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256},
+ {"aes256ccm16", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
+ {"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
+ {"blowfish192", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192},
+ {"camellia192", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192},
+ {"modp3072", DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0},
+ {"modp4096", DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0},
+ {"blowfish", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"blowfish128", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128},
+ {"camellia128", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
+ {"twofish192", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192},
+ {"modp6144", DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0},
+ {"twofish", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
+ {"serpent192", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192},
+ {"twofish128", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128},
+ {"sha256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
+ {"serpent128", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
+ {"sha2_384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
+ {"modpnull", DIFFIE_HELLMAN_GROUP, MODP_NULL, 0},
+ {"camellia", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128},
+ {"sha2_512", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0},
+ {"modp1536", DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0},
+ {"ecp256", DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0},
+ {"serpent", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128},
+ {"twofish256", ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256},
+ {"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
+ {"camellia256", ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256},
+ {"serpent256", ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256},
+ {"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0}
+ };
+
+static const short lookup[] =
+ {
+ -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, 2, -1, 3, 4,
+ 5, 6, -1, 7, 8, -1, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -1,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1,
+ 71, -1, 72, -1, 73, -1, 74, 75, 76, 77, 78, -1, -1, 79,
+ -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, -1, -1, -1, 81,
+ -1, -1, -1, -1, -1, -1, 82, 83, 84, -1, 85, -1, -1, -1,
+ -1, -1, -1, 86
+ };
+
+#ifdef __GNUC__
+__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct proposal_token *
+proposal_get_token (str, len)
+ register const char *str;
+ register unsigned int len;
+{
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register int index = lookup[key];
+
+ if (index >= 0)
+ {
+ register const char *s = wordlist[index].name;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &wordlist[index];
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/libfreeswan/ipsec_ipe4.h b/src/libstrongswan/crypto/proposal/proposal_keywords.h
index bc86ae761..86cb7ef09 100644
--- a/src/libfreeswan/ipsec_ipe4.h
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.h
@@ -1,27 +1,34 @@
-/*
- * IP-in-IP Header declarations
- * Copyright (C) 1996, 1997 John Ioannidis.
- * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
- *
+/* proposal keywords
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
+ *
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ipsec_ipe4.h 3265 2007-10-08 19:52:55Z andreas $
*/
-/* The packet header is an IP header! */
+#ifndef _PROPOSAL_KEYWORDS_H_
+#define _PROPOSAL_KEYWORDS_H_
+
+#include <crypto/transform.h>
-struct ipe4_xdata /* transform table data */
-{
- struct in_addr i4_src;
- struct in_addr i4_dst;
+typedef struct proposal_token proposal_token_t;
+
+struct proposal_token {
+ char *name;
+ transform_type_t type;
+ u_int16_t algorithm;
+ u_int16_t keysize;
};
-#define EMT_IPE4_ULEN 8 /* coming from user mode */
+extern const proposal_token_t* proposal_get_token(register const char *str,
+ register unsigned int len);
+
+#endif /* _PROPOSAL_KEYWORDS_H_ */
+
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.txt b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
new file mode 100644
index 000000000..511fdd50a
--- /dev/null
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
@@ -0,0 +1,118 @@
+%{
+/* proposal keywords
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <string.h>
+
+#include <crypto/transform.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/diffie_hellman.h>
+
+%}
+struct proposal_token {
+ char *name;
+ transform_type_t type;
+ u_int16_t algorithm;
+ u_int16_t keysize;
+};
+%%
+null, ENCRYPTION_ALGORITHM, ENCR_NULL, 0
+des, ENCRYPTION_ALGORITHM, ENCR_DES, 0
+3des, ENCRYPTION_ALGORITHM, ENCR_3DES, 0
+aes, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128
+aes128, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128
+aes192, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192
+aes256, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256
+aes128ctr, ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 128
+aes192ctr, ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 192
+aes256ctr, ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256
+aes128ccm8, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128
+aes128ccm64, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 128
+aes128ccm12, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128
+aes128ccm96, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 128
+aes128ccm16, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128
+aes128ccm128, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 128
+aes192ccm8, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192
+aes192ccm64, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 192
+aes192ccm12, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192
+aes192ccm96, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 192
+aes192ccm16, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192
+aes192ccm128, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 192
+aes256ccm8, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256
+aes256ccm64, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256
+aes256ccm12, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256
+aes256ccm96, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256
+aes256ccm16, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256
+aes256ccm128, ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256
+aes128gcm8, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128
+aes128gcm64, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128
+aes128gcm12, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128
+aes128gcm96, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 128
+aes128gcm16, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128
+aes128gcm128, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 128
+aes192gcm8, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192
+aes192gcm64, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192
+aes192gcm12, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192
+aes192gcm96, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 192
+aes192gcm16, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192
+aes192gcm128, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192
+aes256gcm8, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256
+aes256gcm64, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 256
+aes256gcm12, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256
+aes256gcm96, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12, 256
+aes256gcm16, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256
+aes256gcm128, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256
+blowfish, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128
+blowfish128, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128
+blowfish192, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192
+blowfish256, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256
+camellia, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128
+camellia128, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 128
+camellia192, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 192
+camellia256, ENCRYPTION_ALGORITHM, ENCR_CAMELLIA_CBC, 256
+cast128, ENCRYPTION_ALGORITHM, ENCR_CAST, 128
+serpent, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128
+serpent128, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 128
+serpent192, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 192
+serpent256, ENCRYPTION_ALGORITHM, ENCR_SERPENT_CBC, 256
+twofish, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128
+twofish128, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 128
+twofish192, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192
+twofish256, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256
+sha, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0
+sha1, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0
+sha256, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0
+sha2_256, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0
+sha384, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0
+sha2_384, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0
+sha512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
+sha2_512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
+md5, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0
+aesxcbc, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0
+modpnull, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0
+modp768, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0
+modp1024, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0
+modp1536, DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0
+modp2048, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0
+modp3072, DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0
+modp4096, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0
+modp6144, DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0
+modp8192, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0
+ecp192, DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0
+ecp224, DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0
+ecp256, DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0
+ecp384, DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0
+ecp521, DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0
diff --git a/src/libstrongswan/crypto/rngs/rng.c b/src/libstrongswan/crypto/rngs/rng.c
index 435e043e8..67fd76910 100644
--- a/src/libstrongswan/crypto/rngs/rng.c
+++ b/src/libstrongswan/crypto/rngs/rng.c
@@ -11,14 +11,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "rng.h"
-ENUM(rng_quality_names, RNG_WEAK, RNG_REAL,
+ENUM(rng_quality_names, RNG_WEAK, RNG_TRUE,
"RNG_WEAK",
"RNG_STRONG",
- "RNG_REAL",
+ "RNG_TRUE",
);
diff --git a/src/libstrongswan/crypto/rngs/rng.h b/src/libstrongswan/crypto/rngs/rng.h
index 1c4d204f3..89bc2f2de 100644
--- a/src/libstrongswan/crypto/rngs/rng.h
+++ b/src/libstrongswan/crypto/rngs/rng.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: rng.h 3619 2008-03-19 14:02:52Z martin $
*/
/**
@@ -36,8 +34,8 @@ enum rng_quality_t {
RNG_WEAK,
/** stronger randomness, usable for session keys */
RNG_STRONG,
- /** real random, key material */
- RNG_REAL,
+ /** true random key material */
+ RNG_TRUE,
};
/**
@@ -56,7 +54,7 @@ struct rng_t {
* @param len number of bytes to get
* @param buffer pointer where the generated bytes will be written
*/
- void (*get_bytes) (rng_t *this, u_int len, u_int8_t *buffer);
+ void (*get_bytes) (rng_t *this, size_t len, u_int8_t *buffer);
/**
* Generates random bytes and allocate space for them.
@@ -64,7 +62,7 @@ struct rng_t {
* @param len number of bytes to get
* @param chunk chunk which will hold generated bytes
*/
- void (*allocate_bytes) (rng_t *this, u_int len, chunk_t *chunk);
+ void (*allocate_bytes) (rng_t *this, size_t len, chunk_t *chunk);
/**
* Destroys a rng object.
diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c
index 8412ff62e..1147e1f26 100644
--- a/src/libstrongswan/crypto/signers/signer.c
+++ b/src/libstrongswan/crypto/signers/signer.c
@@ -12,24 +12,27 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: signer.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "signer.h"
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
"UNDEFINED",
- "AUTH_HMAC_SHA1_128");
-ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_AES_XCBC_96, AUTH_HMAC_SHA1_128,
+ "HMAC_SHA1_128");
+ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_MD5_96, AUTH_HMAC_SHA2_512_256, AUTH_HMAC_SHA1_128,
"HMAC_MD5_96",
"HMAC_SHA1_96",
"DES_MAC",
"KPDK_MD5",
- "AES_XCBC_96");
-ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_256, AUTH_AES_XCBC_96,
- "AUTH_HMAC_SHA2_256_128",
- "AUTH_HMAC_SHA2_384_192",
- "AUTH_HMAC_SHA2_512_256");
+ "AES_XCBC_96",
+ "HMAC_MD5_128",
+ "HMAC_SHA1_160",
+ "AES_CMAC_96",
+ "AES_128_GMAC",
+ "AES_192_GMAC",
+ "AES_256_GMAC",
+ "HMAC_SHA2_256_128",
+ "HMAC_SHA2_384_192",
+ "HMAC_SHA2_512_256");
ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256);
diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h
index b2be2c030..0d9bfc5af 100644
--- a/src/libstrongswan/crypto/signers/signer.h
+++ b/src/libstrongswan/crypto/signers/signer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: signer.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -36,23 +34,36 @@ typedef struct signer_t signer_t;
*/
enum integrity_algorithm_t {
AUTH_UNDEFINED = 1024,
- /** Implemented via hmac_signer_t */
+ /** RFC4306 */
AUTH_HMAC_MD5_96 = 1,
- /** Implemented via hmac_signer_t */
+ /** RFC4306 */
AUTH_HMAC_SHA1_96 = 2,
+ /** RFC4306 */
AUTH_DES_MAC = 3,
+ /** RFC1826 */
AUTH_KPDK_MD5 = 4,
+ /** RFC4306 */
AUTH_AES_XCBC_96 = 5,
- /** Implemented via hmac_signer_t */
+ /** RFC4595 */
+ AUTH_HMAC_MD5_128 = 6,
+ /** RFC4595 */
+ AUTH_HMAC_SHA1_160 = 7,
+ /** RFC4494 */
+ AUTH_AES_CMAC_96 = 8,
+ /** RFC4543 */
+ AUTH_AES_128_GMAC = 9,
+ /** RFC4543 */
+ AUTH_AES_192_GMAC = 10,
+ /** RFC4543 */
+ AUTH_AES_256_GMAC = 11,
+ /** RFC4868 */
AUTH_HMAC_SHA2_256_128 = 12,
- /** Implemented via hmac_signer_t */
+ /** RFC4868 */
AUTH_HMAC_SHA2_384_192 = 13,
- /** Implemented via hmac_signer_t */
+ /** RFC4868 */
AUTH_HMAC_SHA2_512_256 = 14,
- /** Implemented via hmac_signer_t */
+ /** private use */
AUTH_HMAC_SHA1_128 = 1025,
- /** Implemented via hmac_signer_t */
- AUTH_HMAC_MD5_128 = 1026,
};
/**
@@ -61,7 +72,7 @@ enum integrity_algorithm_t {
extern enum_name_t *integrity_algorithm_names;
/**
- * Generig interface for a symmetric signature algorithm.
+ * Generic interface for a symmetric signature algorithm.
*/
struct signer_t {
/**
diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c
new file mode 100644
index 000000000..af40f4de6
--- /dev/null
+++ b/src/libstrongswan/crypto/transform.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006-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 <crypto/transform.h>
+
+ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, RANDOM_NUMBER_GENERATOR,
+ "UNDEFINED_TRANSFORM_TYPE",
+ "HASH_ALGORITHM",
+ "RANDOM_NUMBER_GENERATOR");
+ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, RANDOM_NUMBER_GENERATOR,
+ "ENCRYPTION_ALGORITHM",
+ "PSEUDO_RANDOM_FUNCTION",
+ "INTEGRITY_ALGORITHM",
+ "DIFFIE_HELLMAN_GROUP",
+ "EXTENDED_SEQUENCE_NUMBERS");
+ENUM_END(transform_type_names, EXTENDED_SEQUENCE_NUMBERS);
+
diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h
new file mode 100644
index 000000000..d11700a73
--- /dev/null
+++ b/src/libstrongswan/crypto/transform.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006-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 transforms transforms
+ * @{ @ingroup crypto
+ */
+
+#ifndef TRANSFORM_H_
+#define TRANSFORM_H_
+
+typedef enum transform_type_t transform_type_t;
+
+#include <library.h>
+
+/**
+ * Type of a transform, as in IKEv2 RFC 3.3.2.
+ */
+enum transform_type_t {
+ UNDEFINED_TRANSFORM_TYPE = 241,
+ HASH_ALGORITHM = 242,
+ RANDOM_NUMBER_GENERATOR = 243,
+ ENCRYPTION_ALGORITHM = 1,
+ PSEUDO_RANDOM_FUNCTION = 2,
+ INTEGRITY_ALGORITHM = 3,
+ DIFFIE_HELLMAN_GROUP = 4,
+ EXTENDED_SEQUENCE_NUMBERS = 5
+};
+
+/**
+ * enum names for transform_type_t.
+ */
+extern enum_name_t *transform_type_names;
+
+#endif /** TRANSFORM_H_ @}*/
diff --git a/src/libstrongswan/database/database_factory.c b/src/libstrongswan/database/database_factory.c
index 9ceb829c6..76e0a4e89 100644
--- a/src/libstrongswan/database/database_factory.c
+++ b/src/libstrongswan/database/database_factory.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: database_factory.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "database_factory.h"
diff --git a/src/libstrongswan/debug.c b/src/libstrongswan/debug.c
index e20bef2da..b4a84cf76 100644
--- a/src/libstrongswan/debug.c
+++ b/src/libstrongswan/debug.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: debug.c 4058 2008-06-11 14:09:46Z martin $
*/
#include <stdarg.h>
diff --git a/src/libstrongswan/debug.h b/src/libstrongswan/debug.h
index 3b98f6837..1413ff54e 100644
--- a/src/libstrongswan/debug.h
+++ b/src/libstrongswan/debug.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: debug.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/enum.c b/src/libstrongswan/enum.c
index 32524d225..946a54deb 100644
--- a/src/libstrongswan/enum.c
+++ b/src/libstrongswan/enum.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: enum.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <stddef.h>
diff --git a/src/libstrongswan/enum.h b/src/libstrongswan/enum.h
index 877b3e6de..3f3ca1172 100644
--- a/src/libstrongswan/enum.h
+++ b/src/libstrongswan/enum.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: enum.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h
index 9a7cc315e..70d14bf97 100644
--- a/src/libstrongswan/fetcher/fetcher.h
+++ b/src/libstrongswan/fetcher/fetcher.h
@@ -46,6 +46,18 @@ enum fetcher_option_t {
FETCH_REQUEST_TYPE,
/**
+ * HTTP header to be sent with with the fetch request.
+ * Additional argument is a char*.
+ */
+ FETCH_REQUEST_HEADER,
+
+ /**
+ * Use HTTP Version 1.0 instead of 1.1.
+ * No additional argument is needed.
+ */
+ FETCH_HTTP_VERSION_1_0,
+
+ /**
* Timeout to use for fetch, in seconds.
* Additional argument is u_int
*/
diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c
index 5d58f224e..a30012bb1 100644
--- a/src/libstrongswan/fetcher/fetcher_manager.c
+++ b/src/libstrongswan/fetcher/fetcher_manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fetcher_manager.c 4591 2008-11-05 16:12:54Z martin $
*/
#include "fetcher_manager.h"
@@ -101,8 +99,12 @@ static status_t fetch(private_fetcher_manager_t *this,
good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
continue;
case FETCH_REQUEST_TYPE:
+ case FETCH_REQUEST_HEADER:
good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
continue;
+ case FETCH_HTTP_VERSION_1_0:
+ good = fetcher->set_option(fetcher, opt);
+ continue;
case FETCH_TIMEOUT:
good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
continue;
diff --git a/src/libstrongswan/fips/Makefile.in b/src/libstrongswan/fips/Makefile.in
index d1c3ed5b6..cdced9423 100644
--- a/src/libstrongswan/fips/Makefile.in
+++ b/src/libstrongswan/fips/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -79,6 +79,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -101,6 +102,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -112,6 +116,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -125,6 +130,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -185,6 +192,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -196,6 +204,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -217,8 +226,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -293,7 +302,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/fips/fips.c b/src/libstrongswan/fips/fips.c
index c268a7429..d2296e5e9 100644
--- a/src/libstrongswan/fips/fips.c
+++ b/src/libstrongswan/fips/fips.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fips.c 3681 2008-03-28 10:21:04Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/fips/fips.h b/src/libstrongswan/fips/fips.h
index 9b777be5f..aae18e3b2 100644
--- a/src/libstrongswan/fips/fips.h
+++ b/src/libstrongswan/fips/fips.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fips.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/fips/fips_canister_end.c b/src/libstrongswan/fips/fips_canister_end.c
index 93f78e696..247d48927 100644
--- a/src/libstrongswan/fips/fips_canister_end.c
+++ b/src/libstrongswan/fips/fips_canister_end.c
@@ -2,8 +2,6 @@
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
* and usage in source and binary forms are granted according to the
* OpenSSL license.
- *
- * $Id: fips_canister_end.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/fips/fips_canister_start.c b/src/libstrongswan/fips/fips_canister_start.c
index a15517ec1..4a5528a94 100644
--- a/src/libstrongswan/fips/fips_canister_start.c
+++ b/src/libstrongswan/fips/fips_canister_start.c
@@ -2,8 +2,6 @@
* Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
* and usage in source and binary forms are granted according to the
* OpenSSL license.
- *
- * $Id: fips_canister_start.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/fips/fips_signer.c b/src/libstrongswan/fips/fips_signer.c
index 4bf8b38dd..6f5fdcecf 100644
--- a/src/libstrongswan/fips/fips_signer.c
+++ b/src/libstrongswan/fips/fips_signer.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fips_signer.c 4258 2008-08-19 18:51:30Z andreas $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index cb8d43052..8e5a8a611 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: library.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include "library.h"
@@ -101,8 +99,6 @@ void library_init(char *settings)
PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'B', chunk_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
- pfh->add_handler(pfh, 'D', identification_printf_hook,
- PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'H', host_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
pfh->add_handler(pfh, 'N', enum_printf_hook,
@@ -114,12 +110,14 @@ void library_init(char *settings)
pfh->add_handler(pfh, 'V', time_delta_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_POINTER,
PRINTF_HOOK_ARGTYPE_END);
+ pfh->add_handler(pfh, 'Y', identification_printf_hook,
+ PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
+ this->public.settings = settings_create(settings);
this->public.crypto = crypto_factory_create();
this->public.creds = credential_factory_create();
this->public.fetcher = fetcher_manager_create();
this->public.db = database_factory_create();
- this->public.settings = settings_create(settings);
this->public.plugins = plugin_loader_create();
}
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index a6d27551e..35c6b686a 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: library.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -63,9 +61,9 @@
#include <settings.h>
#include <plugins/plugin_loader.h>
#include <crypto/crypto_factory.h>
-#include <credentials/credential_factory.h>
#include <fetcher/fetcher_manager.h>
#include <database/database_factory.h>
+#include <credentials/credential_factory.h>
typedef struct library_t library_t;
diff --git a/src/libstrongswan/pgp/pgp.c b/src/libstrongswan/pgp/pgp.c
new file mode 100644
index 000000000..613c318c1
--- /dev/null
+++ b/src/libstrongswan/pgp/pgp.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2002-2009 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "pgp.h"
+
+ENUM_BEGIN(pgp_packet_tag_names, PGP_PKT_RESERVED, PGP_PKT_PUBLIC_SUBKEY,
+ "Reserved",
+ "Public-Key Encrypted Session Key Packet",
+ "Signature Packet",
+ "Symmetric-Key Encrypted Session Key Packet",
+ "One-Pass Signature Packet",
+ "Secret Key Packet",
+ "Public Key Packet",
+ "Secret Subkey Packet",
+ "Compressed Data Packet",
+ "Symmetrically Encrypted Data Packet",
+ "Marker Packet",
+ "Literal Data Packet",
+ "Trust Packet",
+ "User ID Packet",
+ "Public Subkey Packet"
+);
+ENUM_NEXT(pgp_packet_tag_names, PGP_PKT_USER_ATTRIBUTE, PGP_PKT_MOD_DETECT_CODE, PGP_PKT_PUBLIC_SUBKEY,
+ "User Attribute Packet",
+ "Sym. Encrypted and Integrity Protected Data Packet",
+ "Modification Detection Code Packet"
+);
+ENUM_END(pgp_packet_tag_names, PGP_PKT_MOD_DETECT_CODE);
+
+
+ENUM_BEGIN(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_RSA, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
+ "RSA",
+ "RSA_ENC_ONLY",
+ "RSA_SIGN_ONLY"
+);
+ENUM_NEXT(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY, PGP_PUBKEY_ALG_DIFFIE_HELLMAN, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
+ "ELGAMAL_ENC_ONLY",
+ "DSA",
+ "ECC",
+ "ECDSA",
+ "ELGAMAL",
+ "DIFFIE_HELLMAN"
+);
+ENUM_END(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_DIFFIE_HELLMAN);
+
+
+ENUM(pgp_sym_alg_names, PGP_SYM_ALG_PLAIN, PGP_SYM_ALG_TWOFISH,
+ "PLAINTEXT",
+ "IDEA",
+ "3DES",
+ "CAST5",
+ "BLOWFISH",
+ "SAFER",
+ "DES",
+ "AES_128",
+ "AES_192",
+ "AES_256",
+ "TWOFISH"
+);
+
+/*
+ * Defined in header.
+ */
+size_t pgp_length(chunk_t *blob, size_t len)
+{
+ size_t size = 0;
+
+ if (len > blob->len)
+ {
+ return PGP_INVALID_LENGTH;
+ }
+ blob->len -= len;
+
+ while (len-- > 0)
+ {
+ size = 256*size + *blob->ptr++;
+ }
+ return size;
+}
+
diff --git a/src/libstrongswan/pgp/pgp.h b/src/libstrongswan/pgp/pgp.h
new file mode 100644
index 000000000..677c5b1cc
--- /dev/null
+++ b/src/libstrongswan/pgp/pgp.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2002-2009 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup pgpi pgp
+ * @{ @ingroup pgp
+ */
+
+#ifndef PGP_H_
+#define PGP_H_
+
+typedef enum pgp_packet_tag_t pgp_packet_tag_t;
+typedef enum pgp_pubkey_alg_t pgp_pubkey_alg_t;
+typedef enum pgp_sym_alg_t pgp_sym_alg_t;
+
+#include <chunk.h>
+#include <enum.h>
+
+/**
+ * OpenPGP packet tags as defined in section 4.3 of RFC 4880
+ */
+enum pgp_packet_tag_t {
+ PGP_PKT_RESERVED = 0,
+ PGP_PKT_PUBKEY_ENC_SESSION_KEY = 1,
+ PGP_PKT_SIGNATURE = 2,
+ PGP_PKT_SYMKEY_ENC_SESSION_KEY = 3,
+ PGP_PKT_ONE_PASS_SIGNATURE_PKT = 4,
+ PGP_PKT_SECRET_KEY = 5,
+ PGP_PKT_PUBLIC_KEY = 6,
+ PGP_PKT_SECRET_SUBKEY = 7,
+ PGP_PKT_COMPRESSED_DATA = 8,
+ PGP_PKT_SYMKEY_ENC_DATA = 9,
+ PGP_PKT_MARKER = 10,
+ PGP_PKT_LITERAL_DATA = 11,
+ PGP_PKT_TRUST = 12,
+ PGP_PKT_USER_ID = 13,
+ PGP_PKT_PUBLIC_SUBKEY = 14,
+ PGP_PKT_USER_ATTRIBUTE = 17,
+ PGP_PKT_SYM_ENC_INT_PROT_DATA = 18,
+ PGP_PKT_MOD_DETECT_CODE = 19
+};
+
+/**
+ * Enum names for pgp_packet_tag_t
+ */
+extern enum_name_t *pgp_packet_tag_names;
+
+/**
+ * OpenPGP public key algorithms as defined in section 9.1 of RFC 4880
+ */
+enum pgp_pubkey_alg_t {
+ PGP_PUBKEY_ALG_RSA = 1,
+ PGP_PUBKEY_ALG_RSA_ENC_ONLY = 2,
+ PGP_PUBKEY_ALG_RSA_SIGN_ONLY = 3,
+ PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY = 16,
+ PGP_PUBKEY_ALG_DSA = 17,
+ PGP_PUBKEY_ALG_ECC = 18,
+ PGP_PUBKEY_ALG_ECDSA = 19,
+ PGP_PUBKEY_ALG_ELGAMAL = 20,
+ PGP_PUBKEY_ALG_DIFFIE_HELLMAN = 21,
+};
+
+/**
+ * Enum names for pgp_pubkey_alg_t
+ */
+extern enum_name_t *pgp_pubkey_alg_names;
+
+/**
+ * OpenPGP symmetric key algorithms as defined in section 9.2 of RFC 4880
+ */
+enum pgp_sym_alg_t {
+ PGP_SYM_ALG_PLAIN = 0,
+ PGP_SYM_ALG_IDEA = 1,
+ PGP_SYM_ALG_3DES = 2,
+ PGP_SYM_ALG_CAST5 = 3,
+ PGP_SYM_ALG_BLOWFISH = 4,
+ PGP_SYM_ALG_SAFER = 5,
+ PGP_SYM_ALG_DES = 6,
+ PGP_SYM_ALG_AES_128 = 7,
+ PGP_SYM_ALG_AES_192 = 8,
+ PGP_SYM_ALG_AES_256 = 9,
+ PGP_SYM_ALG_TWOFISH = 10
+};
+
+/**
+ * Enum names for pgp_sym_alg_t
+ */
+extern enum_name_t *pgp_sym_alg_names;
+
+#define PGP_INVALID_LENGTH 0xffffffff
+
+/**
+ * Returns the length of an OpenPGP (RFC 4880) packet
+ * The blob pointer is advanced past the length field
+ *
+ * @param blob pointer to an OpenPGP blob
+ * @param len size of the length field
+ * @return length of the next OpenPGP packet
+ */
+size_t pgp_length(chunk_t *blob, size_t len);
+
+#endif /** PGP_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index e4eb7e5cf..19d3249b5 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +326,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/aes/aes_crypter.c b/src/libstrongswan/plugins/aes/aes_crypter.c
index ce4c6da99..c5b091750 100644
--- a/src/libstrongswan/plugins/aes/aes_crypter.c
+++ b/src/libstrongswan/plugins/aes/aes_crypter.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: aes_crypter.c 3900 2008-04-30 14:02:25Z martin $
*/
#include "aes_crypter.h"
@@ -34,8 +32,6 @@
#define AES_KS_LENGTH 120
#define AES_RC_LENGTH 29
-#define AES_BLOCK_SIZE 16
-
typedef struct private_aes_crypter_t private_aes_crypter_t;
/**
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c
index 71e49ad73..63fa48330 100644
--- a/src/libstrongswan/plugins/aes/aes_plugin.c
+++ b/src/libstrongswan/plugins/aes/aes_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: aes_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "aes_plugin.h"
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index 6b2da9cb4..5a5202262 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -320,7 +329,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/agent/agent_plugin.c b/src/libstrongswan/plugins/agent/agent_plugin.c
index 474171ad1..84b85d4bd 100644
--- a/src/libstrongswan/plugins/agent/agent_plugin.c
+++ b/src/libstrongswan/plugins/agent/agent_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "agent_plugin.h"
diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c
index 5e7d0839e..ffdc6d778 100644
--- a/src/libstrongswan/plugins/agent/agent_private_key.c
+++ b/src/libstrongswan/plugins/agent/agent_private_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "agent_private_key.h"
@@ -191,8 +189,8 @@ static bool matches_pubkey(chunk_t key, public_key_t *pubkey)
return FALSE;
}
pubkeydata = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_INTEGER, "c", n),
- asn1_wrap(ASN1_INTEGER, "c", e));
+ asn1_integer("c", n),
+ asn1_integer("c", e));
hasher->allocate_hash(hasher, pubkeydata, &hash);
free(pubkeydata.ptr);
id = pubkey->get_id(pubkey, ID_PUBKEY_SHA1);
@@ -271,7 +269,7 @@ static bool sign(private_agent_private_key_t *this, signature_scheme_t scheme,
char buf[2048];
chunk_t blob = chunk_from_buf(buf);
- if (scheme != SIGN_DEFAULT && scheme != SIGN_RSA_EMSA_PKCS1_SHA1)
+ if (scheme != SIGN_RSA_EMSA_PKCS1_SHA1)
{
DBG1("signature scheme %N not supported by ssh-agent",
signature_scheme_names, scheme);
@@ -389,8 +387,8 @@ static public_key_t* get_public_key(private_agent_private_key_t *this)
e = read_string(&key);
n = read_string(&key);
encoded = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_INTEGER, "c", n),
- asn1_wrap(ASN1_INTEGER, "c", e));
+ asn1_integer("c", n),
+ asn1_integer("c", e));
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
BUILD_BLOB_ASN1_DER, encoded, BUILD_END);
@@ -442,8 +440,8 @@ static bool build_ids(private_agent_private_key_t *this)
return FALSE;
}
publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_INTEGER, "c", n),
- asn1_wrap(ASN1_INTEGER, "c", e));
+ asn1_integer("c", n),
+ asn1_integer("c", e));
hasher->allocate_hash(hasher, publicKey, &hash);
this->keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
chunk_free(&hash);
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.am b/src/libstrongswan/plugins/blowfish/Makefile.am
new file mode 100644
index 000000000..6bb82169e
--- /dev/null
+++ b/src/libstrongswan/plugins/blowfish/Makefile.am
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-blowfish.la
+
+libstrongswan_blowfish_la_SOURCES = \
+blowfish_plugin.h blowfish_plugin.c blowfish_crypter.c blowfish_crypter.h \
+bf_skey.c blowfish.h bf_pi.h bf_locl.h bf_enc.c
+libstrongswan_blowfish_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
new file mode 100644
index 000000000..25cea73df
--- /dev/null
+++ b/src/libstrongswan/plugins/blowfish/Makefile.in
@@ -0,0 +1,513 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/blowfish
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_blowfish_la_LIBADD =
+am_libstrongswan_blowfish_la_OBJECTS = blowfish_plugin.lo \
+ blowfish_crypter.lo bf_skey.lo bf_enc.lo
+libstrongswan_blowfish_la_OBJECTS = \
+ $(am_libstrongswan_blowfish_la_OBJECTS)
+libstrongswan_blowfish_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_blowfish_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_blowfish_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_blowfish_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-blowfish.la
+libstrongswan_blowfish_la_SOURCES = \
+blowfish_plugin.h blowfish_plugin.c blowfish_crypter.c blowfish_crypter.h \
+bf_skey.c blowfish.h bf_pi.h bf_locl.h bf_enc.c
+
+libstrongswan_blowfish_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/blowfish/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/blowfish/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-blowfish.la: $(libstrongswan_blowfish_la_OBJECTS) $(libstrongswan_blowfish_la_DEPENDENCIES)
+ $(libstrongswan_blowfish_la_LINK) -rpath $(plugindir) $(libstrongswan_blowfish_la_OBJECTS) $(libstrongswan_blowfish_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bf_enc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bf_skey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcrypto/libblowfish/bf_enc.c b/src/libstrongswan/plugins/blowfish/bf_enc.c
index aa6c79812..c2f3ce2e8 100644
--- a/src/libcrypto/libblowfish/bf_enc.c
+++ b/src/libstrongswan/plugins/blowfish/bf_enc.c
@@ -70,7 +70,7 @@ to modify the code.
#endif
void BF_encrypt(BF_LONG *data, const BF_KEY *key)
- {
+{
#ifndef BF_PTR2
const BF_LONG *p,*s;
BF_LONG l,r;
@@ -142,12 +142,12 @@ void BF_encrypt(BF_LONG *data, const BF_KEY *key)
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
#endif
- }
+}
#ifndef BF_DEFAULT_OPTIONS
void BF_decrypt(BF_LONG *data, const BF_KEY *key)
- {
+{
#ifndef BF_PTR2
const BF_LONG *p,*s;
BF_LONG l,r;
@@ -219,23 +219,23 @@ void BF_decrypt(BF_LONG *data, const BF_KEY *key)
data[1]=l&0xffffffffL;
data[0]=r&0xffffffffL;
#endif
- }
+}
void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
- const BF_KEY *schedule, unsigned char *ivec, int encrypt)
- {
+ const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+{
BF_LONG tin0,tin1;
BF_LONG tout0,tout1,xor0,xor1;
long l=length;
BF_LONG tin[2];
if (encrypt)
- {
+ {
n2l(ivec,tout0);
n2l(ivec,tout1);
ivec-=8;
for (l-=8; l>=0; l-=8)
- {
+ {
n2l(in,tin0);
n2l(in,tin1);
tin0^=tout0;
@@ -247,9 +247,9 @@ void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
- }
+ }
if (l != -8)
- {
+ {
n2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
@@ -260,17 +260,17 @@ void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
- }
+ }
l2n(tout0,ivec);
l2n(tout1,ivec);
- }
+ }
else
- {
+ {
n2l(ivec,xor0);
n2l(ivec,xor1);
ivec-=8;
for (l-=8; l>=0; l-=8)
- {
+ {
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
@@ -282,9 +282,9 @@ void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
l2n(tout1,out);
xor0=tin0;
xor1=tin1;
- }
+ }
if (l != -8)
- {
+ {
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
@@ -295,12 +295,12 @@ void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
l2nn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
- }
+ }
l2n(xor0,ivec);
l2n(xor1,ivec);
- }
+ }
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
- }
+}
#endif
diff --git a/src/libcrypto/libblowfish/bf_locl.h b/src/libstrongswan/plugins/blowfish/bf_locl.h
index 283bf4c43..283bf4c43 100644
--- a/src/libcrypto/libblowfish/bf_locl.h
+++ b/src/libstrongswan/plugins/blowfish/bf_locl.h
diff --git a/src/libcrypto/libblowfish/bf_pi.h b/src/libstrongswan/plugins/blowfish/bf_pi.h
index 9949513c6..9949513c6 100644
--- a/src/libcrypto/libblowfish/bf_pi.h
+++ b/src/libstrongswan/plugins/blowfish/bf_pi.h
diff --git a/src/libcrypto/libblowfish/bf_skey.c b/src/libstrongswan/plugins/blowfish/bf_skey.c
index 8cdbbd283..8cdbbd283 100644
--- a/src/libcrypto/libblowfish/bf_skey.c
+++ b/src/libstrongswan/plugins/blowfish/bf_skey.c
diff --git a/src/libcrypto/libblowfish/blowfish.h b/src/libstrongswan/plugins/blowfish/blowfish.h
index ccb97e272..ccb97e272 100644
--- a/src/libcrypto/libblowfish/blowfish.h
+++ b/src/libstrongswan/plugins/blowfish/blowfish.h
diff --git a/src/libcrypto/libdes/fcrypt_b.c b/src/libstrongswan/plugins/blowfish/blowfish_crypter.c
index 5900645e7..5064bfef6 100644
--- a/src/libcrypto/libdes/fcrypt_b.c
+++ b/src/libstrongswan/plugins/blowfish/blowfish_crypter.c
@@ -1,6 +1,5 @@
-/* crypto/des/fcrypt_b.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/*
+ * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
@@ -56,93 +55,143 @@
* [including the GNU Public Licence.]
*/
-/* #include <stdio.h> */
+#include "blowfish.h"
-/* This version of crypt has been developed from my MIT compatable
- * DES library.
- * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
- * Eric Young (eay@cryptsoft.com)
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
*/
+
+#include "blowfish_crypter.h"
-#define DES_FCRYPT
-#include "des_locl.h"
-#undef DES_FCRYPT
+typedef struct private_blowfish_crypter_t private_blowfish_crypter_t;
-#undef PERM_OP
-#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
- (b)^=(t),\
- (a)^=((t)<<(n)))
+/**
+ * Class implementing the Blowfish symmetric encryption algorithm.
+ *
+ * @ingroup crypters
+ */
+struct private_blowfish_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ blowfish_crypter_t public;
+
+ /**
+ * Blowfish key schedule
+ */
+ BF_KEY schedule;
-#undef HPERM_OP
-#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
- (a)=(a)^(t)^(t>>(16-(n))))\
+ /**
+ * Key size of this Blowfish cipher object.
+ */
+ u_int32_t key_size;
+};
-void fcrypt_body(out, ks, Eswap0, Eswap1)
-DES_LONG *out;
-des_key_schedule ks;
-DES_LONG Eswap0;
-DES_LONG Eswap1;
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_blowfish_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted)
+{
+ u_int8_t *in, *out;
+
+ if (decrypted)
+ {
+ *decrypted = chunk_alloc(data.len);
+ out = decrypted->ptr;
+ }
+ else
+ {
+ out = data.ptr;
+ }
+ in = data.ptr;
+ iv = chunk_clone(iv);
+
+ BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 0);
+
+ free(iv.ptr);
+}
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void encrypt (private_blowfish_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted)
+{
+ u_int8_t *in, *out;
+
+ if (encrypted)
+ {
+ *encrypted = chunk_alloc(data.len);
+ out = encrypted->ptr;
+ }
+ else
{
- register DES_LONG l,r,t,u;
-#ifdef DES_PTR
- register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-#endif
- register DES_LONG *s;
- register int j;
- register DES_LONG E0,E1;
-
- l=0;
- r=0;
-
- s=(DES_LONG *)ks;
- E0=Eswap0;
- E1=Eswap1;
-
- for (j=0; j<25; j++)
- {
-#ifdef DES_UNROLL
- register int i;
-
- for (i=0; i<32; i+=8)
- {
- D_ENCRYPT(l,r,i+0); /* 1 */
- D_ENCRYPT(r,l,i+2); /* 2 */
- D_ENCRYPT(l,r,i+4); /* 1 */
- D_ENCRYPT(r,l,i+6); /* 2 */
- }
-#else
- D_ENCRYPT(l,r, 0); /* 1 */
- D_ENCRYPT(r,l, 2); /* 2 */
- D_ENCRYPT(l,r, 4); /* 3 */
- D_ENCRYPT(r,l, 6); /* 4 */
- D_ENCRYPT(l,r, 8); /* 5 */
- D_ENCRYPT(r,l,10); /* 6 */
- D_ENCRYPT(l,r,12); /* 7 */
- D_ENCRYPT(r,l,14); /* 8 */
- D_ENCRYPT(l,r,16); /* 9 */
- D_ENCRYPT(r,l,18); /* 10 */
- D_ENCRYPT(l,r,20); /* 11 */
- D_ENCRYPT(r,l,22); /* 12 */
- D_ENCRYPT(l,r,24); /* 13 */
- D_ENCRYPT(r,l,26); /* 14 */
- D_ENCRYPT(l,r,28); /* 15 */
- D_ENCRYPT(r,l,30); /* 16 */
-#endif
-
- t=l;
- l=r;
- r=t;
- }
- l=ROTATE(l,3)&0xffffffffL;
- r=ROTATE(r,3)&0xffffffffL;
-
- PERM_OP(l,r,t, 1,0x55555555L);
- PERM_OP(r,l,t, 8,0x00ff00ffL);
- PERM_OP(l,r,t, 2,0x33333333L);
- PERM_OP(r,l,t,16,0x0000ffffL);
- PERM_OP(l,r,t, 4,0x0f0f0f0fL);
-
- out[0]=r;
- out[1]=l;
+ out = data.ptr;
}
+ in = data.ptr;
+ iv = chunk_clone(iv);
+ BF_cbc_encrypt(in, out, data.len, &this->schedule, iv.ptr, 1);
+
+ free(iv.ptr);
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size (private_blowfish_crypter_t *this)
+{
+ return BLOWFISH_BLOCK_SIZE;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size (private_blowfish_crypter_t *this)
+{
+ return this->key_size;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key (private_blowfish_crypter_t *this, chunk_t key)
+{
+ BF_set_key(&this->schedule, key.len , key.ptr);
+}
+
+/**
+ * Implementation of crypter_t.destroy and blowfish_crypter_t.destroy.
+ */
+static void destroy (private_blowfish_crypter_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+blowfish_crypter_t *blowfish_crypter_create(encryption_algorithm_t algo, size_t key_size)
+{
+ private_blowfish_crypter_t *this;
+
+ if (algo != ENCR_BLOWFISH)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_blowfish_crypter_t);
+
+ this->key_size = key_size;
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
+
+ return &(this->public);
+}
diff --git a/src/libstrongswan/plugins/blowfish/blowfish_crypter.h b/src/libstrongswan/plugins/blowfish/blowfish_crypter.h
new file mode 100644
index 000000000..2bb896e64
--- /dev/null
+++ b/src/libstrongswan/plugins/blowfish/blowfish_crypter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup blowfish_crypter blowfish_crypter
+ * @{ @ingroup blowfish_p
+ */
+
+#ifndef BLOWFISH_CRYPTER_H_
+#define BLOWFISH_CRYPTER_H_
+
+typedef struct blowfish_crypter_t blowfish_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Class implementing the Blowfish encryption algorithm.
+ */
+struct blowfish_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create blowfish_crypter_t objects.
+ *
+ * @param key_size key size in bytes
+ * @param algo algorithm to implement
+ * @return blowfish_crypter_t object, NULL if not supported
+ */
+blowfish_crypter_t *blowfish_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /** BLOWFISH_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/blowfish/blowfish_plugin.c b/src/libstrongswan/plugins/blowfish/blowfish_plugin.c
new file mode 100644
index 000000000..6e2f6d4fa
--- /dev/null
+++ b/src/libstrongswan/plugins/blowfish/blowfish_plugin.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "blowfish_plugin.h"
+
+#include <library.h>
+#include "blowfish_crypter.h"
+
+typedef struct private_blowfish_plugin_t private_blowfish_plugin_t;
+
+/**
+ * private data of blowfish_plugin
+ */
+struct private_blowfish_plugin_t {
+
+ /**
+ * public functions
+ */
+ blowfish_plugin_t public;
+};
+
+/**
+ * Implementation of blowfish_plugin_t.destroy
+ */
+static void destroy(private_blowfish_plugin_t *this)
+{
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)blowfish_crypter_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_blowfish_plugin_t *this = malloc_thing(private_blowfish_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH,
+ (crypter_constructor_t)blowfish_crypter_create);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/blowfish/blowfish_plugin.h b/src/libstrongswan/plugins/blowfish/blowfish_plugin.h
new file mode 100644
index 000000000..596a7c791
--- /dev/null
+++ b/src/libstrongswan/plugins/blowfish/blowfish_plugin.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup blowfish_p blowfish
+ * @ingroup plugins
+ *
+ * @defgroup blowfish_plugin blowfish_plugin
+ * @{ @ingroup blowfish_p
+ */
+
+#ifndef BLOWFISH_PLUGIN_H_
+#define BLOWFISH_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct blowfish_plugin_t blowfish_plugin_t;
+
+/**
+ * Plugin implementing Blowfish based algorithms in software.
+ */
+struct blowfish_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a blowfish_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** BLOWFISH_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index cd916ccbe..b413e035e 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -222,8 +231,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -318,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
index cd54c76a3..7ee9fa1bd 100644
--- a/src/libstrongswan/plugins/curl/curl_fetcher.c
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: curl_fetcher.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <curl/curl.h>
@@ -35,16 +33,16 @@ struct private_curl_fetcher_t {
* Public data
*/
curl_fetcher_t public;
-
+
/**
* CURL handle
*/
CURL* curl;
/**
- * request type, as set with FETCH_REQUEST_TYPE
+ * Optional HTTP headers
*/
- char *request_type;
+ struct curl_slist *headers;
};
/**
@@ -52,15 +50,15 @@ struct private_curl_fetcher_t {
*/
static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
{
- size_t realsize = size * nmemb;
-
- data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
- if (data->ptr)
- {
+ size_t realsize = size * nmemb;
+
+ data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
+ if (data->ptr)
+ {
memcpy(&data->ptr[data->len], ptr, realsize);
data->len += realsize;
- }
- return realsize;
+ }
+ return realsize;
}
/**
@@ -68,9 +66,7 @@ static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
*/
static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
{
- struct curl_slist *headers = NULL;
char error[CURL_ERROR_SIZE];
- char buf[256];;
status_t status;
*result = chunk_empty;
@@ -85,14 +81,12 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_TIMEOUT);
curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, (void*)append);
curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void*)result);
- if (this->request_type)
+ if (this->headers)
{
- snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
- headers = curl_slist_append(headers, buf);
- curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, this->headers);
}
-
- DBG2("sending http request to '%s'...", uri);
+
+ DBG2(" sending http request to '%s'...", uri);
switch (curl_easy_perform(this->curl))
{
case CURLE_UNSUPPORTED_PROTOCOL:
@@ -102,11 +96,10 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
status = SUCCESS;
break;
default:
- DBG1("libcurl http request failed: %s", error);
+ DBG1("libcurl http request failed: %s", error);
status = FAILED;
break;
}
- curl_slist_free_all(headers);
return status;
}
@@ -123,13 +116,31 @@ static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ..
case FETCH_REQUEST_DATA:
{
chunk_t data = va_arg(args, chunk_t);
+
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, (char*)data.ptr);
curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
return TRUE;
}
case FETCH_REQUEST_TYPE:
{
- this->request_type = va_arg(args, char*);
+ char header[BUF_LEN];
+ char *request_type = va_arg(args, char*);
+
+ snprintf(header, BUF_LEN, "Content-Type: %s", request_type);
+ this->headers = curl_slist_append(this->headers, header);
+ return TRUE;
+ }
+ case FETCH_REQUEST_HEADER:
+ {
+ char *header = va_arg(args, char*);
+
+ this->headers = curl_slist_append(this->headers, header);
+ return TRUE;
+ }
+ case FETCH_HTTP_VERSION_1_0:
+ {
+ curl_easy_setopt(this->curl, CURLOPT_HTTP_VERSION,
+ CURL_HTTP_VERSION_1_0);
return TRUE;
}
case FETCH_TIMEOUT:
@@ -148,6 +159,7 @@ static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ..
*/
static void destroy(private_curl_fetcher_t *this)
{
+ curl_slist_free_all(this->headers);
curl_easy_cleanup(this->curl);
free(this);
}
@@ -158,19 +170,19 @@ static void destroy(private_curl_fetcher_t *this)
curl_fetcher_t *curl_fetcher_create()
{
private_curl_fetcher_t *this = malloc_thing(private_curl_fetcher_t);
-
+
this->curl = curl_easy_init();
if (this->curl == NULL)
{
free(this);
return NULL;
}
- this->request_type = NULL;
-
+ this->headers = NULL;
+
this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
-
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c
index a41c3815c..97fa07866 100644
--- a/src/libstrongswan/plugins/curl/curl_plugin.c
+++ b/src/libstrongswan/plugins/curl/curl_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: curl_plugin.c 3529 2008-03-05 15:26:24Z martin $
*/
#include "curl_plugin.h"
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index 415c126af..bbca6a032 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +326,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
index b0b18a2c1..680fe8b6a 100644
--- a/src/libstrongswan/plugins/des/des_crypter.c
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -56,13 +56,11 @@
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
- *
- * $Id: des_crypter.c 4938 2009-03-12 18:38:13Z tobias $
*/
#include "des_crypter.h"
-typedef u_char des_cblock[8];
+typedef u_char des_cblock[DES_BLOCK_SIZE];
typedef struct des_ks_struct {
des_cblock _;
diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c
index a0d8ce07b..e16b475d4 100644
--- a/src/libstrongswan/plugins/des/des_plugin.c
+++ b/src/libstrongswan/plugins/des/des_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: des_plugin.c 4887 2009-02-19 14:29:25Z tobias $
*/
#include "des_plugin.h"
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index 1e53f435f..881d7a36e 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -223,8 +232,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -319,7 +328,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index df3d130a9..be28f10bc 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fips_prf.c 3619 2008-03-19 14:02:52Z martin $
*/
#include "fips_prf.h"
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
index 60fce8632..7576e79ad 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: fips_prf_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "fips_prf_plugin.h"
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.am b/src/libstrongswan/plugins/gcrypt/Makefile.am
new file mode 100644
index 000000000..72cc409fc
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic $(LIBGCRYPT_CFLAGS)
+
+plugin_LTLIBRARIES = libstrongswan-gcrypt.la
+
+libstrongswan_gcrypt_la_SOURCES = gcrypt_plugin.h gcrypt_plugin.c \
+ gcrypt_rsa_public_key.h gcrypt_rsa_public_key.c \
+ gcrypt_rsa_private_key.h gcrypt_rsa_private_key.c \
+ gcrypt_dh.h gcrypt_dh.c \
+ gcrypt_rng.h gcrypt_rng.c \
+ gcrypt_crypter.h gcrypt_crypter.c \
+ gcrypt_hasher.h gcrypt_hasher.c
+
+libstrongswan_gcrypt_la_LDFLAGS = -module
+libstrongswan_gcrypt_la_LIBADD = $(LIBGCRYPT_LIBS)
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
new file mode 100644
index 000000000..49994c593
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.in
@@ -0,0 +1,522 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/gcrypt
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_gcrypt_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_gcrypt_la_OBJECTS = gcrypt_plugin.lo \
+ gcrypt_rsa_public_key.lo gcrypt_rsa_private_key.lo \
+ gcrypt_dh.lo gcrypt_rng.lo gcrypt_crypter.lo gcrypt_hasher.lo
+libstrongswan_gcrypt_la_OBJECTS = \
+ $(am_libstrongswan_gcrypt_la_OBJECTS)
+libstrongswan_gcrypt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_gcrypt_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_gcrypt_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_gcrypt_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic $(LIBGCRYPT_CFLAGS)
+plugin_LTLIBRARIES = libstrongswan-gcrypt.la
+libstrongswan_gcrypt_la_SOURCES = gcrypt_plugin.h gcrypt_plugin.c \
+ gcrypt_rsa_public_key.h gcrypt_rsa_public_key.c \
+ gcrypt_rsa_private_key.h gcrypt_rsa_private_key.c \
+ gcrypt_dh.h gcrypt_dh.c \
+ gcrypt_rng.h gcrypt_rng.c \
+ gcrypt_crypter.h gcrypt_crypter.c \
+ gcrypt_hasher.h gcrypt_hasher.c
+
+libstrongswan_gcrypt_la_LDFLAGS = -module
+libstrongswan_gcrypt_la_LIBADD = $(LIBGCRYPT_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/libstrongswan/plugins/gcrypt/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/gcrypt/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-gcrypt.la: $(libstrongswan_gcrypt_la_OBJECTS) $(libstrongswan_gcrypt_la_DEPENDENCIES)
+ $(libstrongswan_gcrypt_la_LINK) -rpath $(plugindir) $(libstrongswan_gcrypt_la_OBJECTS) $(libstrongswan_gcrypt_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_dh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_rng.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_rsa_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcrypt_rsa_public_key.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c
new file mode 100644
index 000000000..f82d23185
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.c
@@ -0,0 +1,252 @@
+/*
+ * 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 "gcrypt_crypter.h"
+
+#include <gcrypt.h>
+
+#include <debug.h>
+
+typedef struct private_gcrypt_crypter_t private_gcrypt_crypter_t;
+
+/**
+ * Private data of gcrypt_crypter_t
+ */
+struct private_gcrypt_crypter_t {
+
+ /**
+ * Public part of this class.
+ */
+ gcrypt_crypter_t public;
+
+ /**
+ * gcrypt cipher handle
+ */
+ gcry_cipher_hd_t h;
+
+ /**
+ * gcrypt algorithm identifier
+ */
+ int alg;
+};
+
+/**
+ * Implementation of crypter_t.decrypt.
+ */
+static void decrypt(private_gcrypt_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ gcry_cipher_setiv(this->h, iv.ptr, iv.len);
+
+ if (dst)
+ {
+ *dst = chunk_alloc(data.len);
+ gcry_cipher_decrypt(this->h, dst->ptr, dst->len, data.ptr, data.len);
+ }
+ else
+ {
+ gcry_cipher_decrypt(this->h, data.ptr, data.len, NULL, 0);
+ }
+}
+
+/**
+ * Implementation of crypter_t.encrypt.
+ */
+static void encrypt(private_gcrypt_crypter_t *this, chunk_t data,
+ chunk_t iv, chunk_t *dst)
+{
+ gcry_cipher_setiv(this->h, iv.ptr, iv.len);
+
+ if (dst)
+ {
+ *dst = chunk_alloc(data.len);
+ gcry_cipher_encrypt(this->h, dst->ptr, dst->len, data.ptr, data.len);
+ }
+ else
+ {
+ gcry_cipher_encrypt(this->h, data.ptr, data.len, NULL, 0);
+ }
+}
+
+/**
+ * Implementation of crypter_t.get_block_size.
+ */
+static size_t get_block_size(private_gcrypt_crypter_t *this)
+{
+ size_t len = 0;
+
+ gcry_cipher_algo_info(this->alg, GCRYCTL_GET_BLKLEN, NULL, &len);
+ return len;
+}
+
+/**
+ * Implementation of crypter_t.get_key_size.
+ */
+static size_t get_key_size(private_gcrypt_crypter_t *this)
+{
+ size_t len = 0;
+
+ gcry_cipher_algo_info(this->alg, GCRYCTL_GET_KEYLEN, NULL, &len);
+ return len;
+}
+
+/**
+ * Implementation of crypter_t.set_key.
+ */
+static void set_key(private_gcrypt_crypter_t *this, chunk_t key)
+{
+ gcry_cipher_setkey(this->h, key.ptr, key.len);
+}
+
+/**
+ * Implementation of crypter_t.destroy.
+ */
+static void destroy (private_gcrypt_crypter_t *this)
+{
+ gcry_cipher_close(this->h);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo,
+ size_t key_size)
+{
+ private_gcrypt_crypter_t *this;
+ int gcrypt_alg;
+ int mode = GCRY_CIPHER_MODE_CBC;
+ gcry_error_t err;
+
+ switch (algo)
+ {
+ case ENCR_DES:
+ gcrypt_alg = GCRY_CIPHER_DES;
+ break;
+ case ENCR_DES_ECB:
+ gcrypt_alg = GCRY_CIPHER_DES;
+ mode = GCRY_CIPHER_MODE_ECB;
+ break;
+ case ENCR_3DES:
+ gcrypt_alg = GCRY_CIPHER_3DES;
+ break;
+ case ENCR_IDEA:
+ /* currently not implemented in gcrypt */
+ return NULL;
+ case ENCR_CAST:
+ gcrypt_alg = GCRY_CIPHER_CAST5;
+ break;
+ case ENCR_BLOWFISH:
+ if (key_size != 16)
+ { /* gcrypt currently supports 128 bit blowfish only */
+ return NULL;
+ }
+ gcrypt_alg = GCRY_CIPHER_BLOWFISH;
+ break;
+ /* case ENCR_AES_CTR:
+ mode = GCRY_CIPHER_MODE_CTR; */
+ /* fall */
+ case ENCR_AES_CBC:
+ switch (key_size)
+ {
+ case 16:
+ gcrypt_alg = GCRY_CIPHER_AES128;
+ break;
+ case 24:
+ gcrypt_alg = GCRY_CIPHER_AES192;
+ break;
+ case 32:
+ gcrypt_alg = GCRY_CIPHER_AES256;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ /* case ENCR_CAMELLIA_CTR:
+ mode = GCRY_CIPHER_MODE_CTR; */
+ /* fall */
+ case ENCR_CAMELLIA_CBC:
+ switch (key_size)
+ {
+#ifdef HAVE_GCRY_CIPHER_CAMELLIA
+ case 16:
+ gcrypt_alg = GCRY_CIPHER_CAMELLIA128;
+ break;
+ case 24:
+ gcrypt_alg = GCRY_CIPHER_CAMELLIA192;
+ break;
+ case 32:
+ gcrypt_alg = GCRY_CIPHER_CAMELLIA256;
+ break;
+#endif /* HAVE_GCRY_CIPHER_CAMELLIA */
+ default:
+ return NULL;
+ }
+ break;
+ case ENCR_SERPENT_CBC:
+ switch (key_size)
+ {
+ case 16:
+ gcrypt_alg = GCRY_CIPHER_SERPENT128;
+ break;
+ case 24:
+ gcrypt_alg = GCRY_CIPHER_SERPENT192;
+ break;
+ case 32:
+ gcrypt_alg = GCRY_CIPHER_SERPENT256;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ case ENCR_TWOFISH_CBC:
+ switch (key_size)
+ {
+ case 16:
+ gcrypt_alg = GCRY_CIPHER_TWOFISH128;
+ break;
+ case 32:
+ gcrypt_alg = GCRY_CIPHER_TWOFISH;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_gcrypt_crypter_t);
+
+ this->alg = gcrypt_alg;
+ err = gcry_cipher_open(&this->h, gcrypt_alg, mode, 0);
+ if (err)
+ {
+ DBG1("grcy_cipher_open(%N) failed: %s",
+ encryption_algorithm_names, algo, gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+
+ this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *))encrypt;
+ this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *))decrypt;
+ this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *))get_block_size;
+ this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *))get_key_size;
+ this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t))set_key;
+ this->public.crypter_interface.destroy = (void (*) (crypter_t *))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h
new file mode 100644
index 000000000..c5a5e6723
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_crypter.h
@@ -0,0 +1,49 @@
+/*
+ * 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 gcrypt_crypter gcrypt_crypter
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_CRYPTER_H_
+#define GCRYPT_CRYPTER_H_
+
+typedef struct gcrypt_crypter_t gcrypt_crypter_t;
+
+#include <crypto/crypters/crypter.h>
+
+/**
+ * Implementation of crypters using gcrypt.
+ */
+struct gcrypt_crypter_t {
+
+ /**
+ * The crypter_t interface.
+ */
+ crypter_t crypter_interface;
+};
+
+/**
+ * Constructor to create gcrypt_crypter_t.
+ *
+ * @param algo algorithm to implement
+ * @param key_size key size in bytes
+ * @return gcrypt_crypter_t, NULL if not supported
+ */
+gcrypt_crypter_t *gcrypt_crypter_create(encryption_algorithm_t algo,
+ size_t key_size);
+
+#endif /** GCRYPT_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
new file mode 100644
index 000000000..89d9f2348
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
@@ -0,0 +1,564 @@
+/*
+ * 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 <gcrypt.h>
+
+#include "gcrypt_dh.h"
+
+#include <debug.h>
+
+/**
+ * Modulus of Group 1 (MODP_768_BIT).
+ */
+static u_int8_t group1_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 2 (MODP_1024_BIT).
+ */
+static u_int8_t group2_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 5 (MODP_1536_BIT).
+ */
+static u_int8_t group5_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+/**
+ * Modulus of Group 14 (MODP_2048_BIT).
+ */
+static u_int8_t group14_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 15 (MODP_3072_BIT).
+ */
+static u_int8_t group15_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 16 (MODP_4096_BIT).
+ */
+static u_int8_t group16_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 17 (MODP_6144_BIT).
+ */
+static u_int8_t group17_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/**
+ * Modulus of Group 18 (MODP_8192_BIT).
+ */
+static u_int8_t group18_modulus[] = {
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
+ 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
+ 0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
+ 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
+ 0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,
+ 0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
+ 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
+ 0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
+ 0xF1,0x74,0x6C,0x08,0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
+ 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
+ 0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
+ 0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,0x04,0x50,0x7A,0x33,
+ 0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,
+ 0x8A,0xEA,0x71,0x57,0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
+ 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,0x4A,0x25,0x61,0x9D,
+ 0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,
+ 0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
+ 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
+ 0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
+ 0x4B,0x82,0xD1,0x20,0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
+ 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,0x6A,0xF4,0xE2,0x3C,
+ 0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,
+ 0xDB,0xBB,0xC2,0xDB,0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
+ 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,0xA0,0x90,0xC3,0xA2,
+ 0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
+ 0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
+ 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
+ 0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,
+ 0xC1,0xD4,0xDC,0xB2,0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
+ 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,0x41,0x30,0x01,0xAE,
+ 0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,
+ 0xDA,0x3E,0xDB,0xEB,0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
+ 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,0x2B,0xD7,0xAF,0x42,
+ 0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,
+ 0xF0,0x32,0xEA,0x15,0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
+ 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,0x90,0x0B,0x1C,0x9E,
+ 0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,
+ 0x0F,0x1D,0x45,0xB7,0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
+ 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,0x0F,0x80,0x37,0xE0,
+ 0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,
+ 0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
+ 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
+ 0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
+ 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,0x73,0xB9,0x31,0xBA,
+ 0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,
+ 0x25,0x76,0xF6,0x93,0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
+ 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,0xE3,0x9D,0x65,0x2D,
+ 0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,
+ 0x13,0xEB,0x57,0xA8,0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
+ 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,0xA2,0xC0,0x87,0xE8,
+ 0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,
+ 0x6D,0x2A,0x13,0xF8,0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
+ 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,0x08,0x46,0x85,0x1D,
+ 0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,
+ 0xFA,0xF3,0x6B,0xC3,0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
+ 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
+ 0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
+ 0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
+ 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+};
+
+typedef struct modulus_entry_t modulus_entry_t;
+
+/**
+ * Entry of the modulus list.
+ */
+struct modulus_entry_t {
+ /** IKEv2 DH group */
+ diffie_hellman_group_t group;
+ /** modulus */
+ chunk_t modulus;
+ /** optimum length of exponent in bytes */
+ size_t opt_len;
+ /** generator */
+ u_int16_t g;
+};
+
+/**
+ * All supported modulus values - optimum exponent size according to RFC 3526.
+ */
+static modulus_entry_t modulus_entries[] = {
+ {MODP_768_BIT, {group1_modulus, sizeof(group1_modulus)}, 32, 2},
+ {MODP_1024_BIT, {group2_modulus, sizeof(group2_modulus)}, 32, 2},
+ {MODP_1536_BIT, {group5_modulus, sizeof(group5_modulus)}, 32, 2},
+ {MODP_2048_BIT, {group14_modulus, sizeof(group14_modulus)}, 48, 2},
+ {MODP_3072_BIT, {group15_modulus, sizeof(group15_modulus)}, 48, 2},
+ {MODP_4096_BIT, {group16_modulus, sizeof(group16_modulus)}, 64, 2},
+ {MODP_6144_BIT, {group17_modulus, sizeof(group17_modulus)}, 64, 2},
+ {MODP_8192_BIT, {group18_modulus, sizeof(group18_modulus)}, 64, 2},
+};
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static modulus_entry_t *find_entry(diffie_hellman_group_t group)
+{
+ int i;
+
+ for (i = 0; i < countof(modulus_entries); i++)
+ {
+ if (modulus_entries[i].group == group)
+ {
+ return &modulus_entries[i];
+ }
+ }
+ return NULL;
+}
+
+typedef struct private_gcrypt_dh_t private_gcrypt_dh_t;
+
+/**
+ * Private data of an gcrypt_dh_t object.
+ */
+struct private_gcrypt_dh_t {
+
+ /**
+ * Public gcrypt_dh_t interface
+ */
+ gcrypt_dh_t public;
+
+ /**
+ * Diffie Hellman group number
+ */
+ u_int16_t group;
+
+ /*
+ * Generator value
+ */
+ gcry_mpi_t g;
+
+ /**
+ * Own private value
+ */
+ gcry_mpi_t xa;
+
+ /**
+ * Own public value
+ */
+ gcry_mpi_t ya;
+
+ /**
+ * Other public value
+ */
+ gcry_mpi_t yb;
+
+ /**
+ * Shared secret
+ */
+ gcry_mpi_t zz;
+
+ /**
+ * Modulus
+ */
+ gcry_mpi_t p;
+
+ /**
+ * Modulus length.
+ */
+ size_t p_len;
+};
+
+/**
+ * Implementation of gcrypt_dh_t.set_other_public_value.
+ */
+static void set_other_public_value(private_gcrypt_dh_t *this, chunk_t value)
+{
+ gcry_mpi_t p_min_1;
+ gcry_error_t err;
+
+ if (this->yb)
+ {
+ gcry_mpi_release(this->yb);
+ this->yb = NULL;
+ }
+ err = gcry_mpi_scan(&this->yb, GCRYMPI_FMT_USG, value.ptr, value.len, NULL);
+ if (err)
+ {
+ DBG1("importing mpi yb failed: %s", gpg_strerror(err));
+ return;
+ }
+
+ p_min_1 = gcry_mpi_new(this->p_len * 8);
+ gcry_mpi_sub_ui(p_min_1, this->p, 1);
+
+ /* check public value:
+ * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
+ * 2. a public value larger or equal the modulus is invalid */
+ if (gcry_mpi_cmp_ui(this->yb, 1) > 0 &&
+ gcry_mpi_cmp(this->yb, p_min_1) < 0)
+ {
+ if (!this->zz)
+ {
+ this->zz = gcry_mpi_new(this->p_len * 8);
+ }
+ gcry_mpi_powm(this->zz, this->yb, this->xa, this->p);
+ }
+ else
+ {
+ DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
+ }
+ gcry_mpi_release(p_min_1);
+}
+
+/**
+ * export a gcry_mpi to an allocated chunk of len bytes
+ */
+static chunk_t export_mpi(gcry_mpi_t value, size_t len)
+{
+ chunk_t chunk;
+ size_t written;
+
+ chunk = chunk_alloc(len);
+ gcry_mpi_print(GCRYMPI_FMT_USG, chunk.ptr, chunk.len, &written, value);
+ if (written < len)
+ { /* right-align number of written bytes in chunk */
+ memmove(chunk.ptr + (len - written), chunk.ptr, written);
+ memset(chunk.ptr, 0, len - written);
+ }
+ return chunk;
+}
+
+/**
+ * Implementation of gcrypt_dh_t.get_my_public_value.
+ */
+static void get_my_public_value(private_gcrypt_dh_t *this, chunk_t *value)
+{
+ *value = export_mpi(this->ya, this->p_len);
+}
+
+/**
+ * Implementation of gcrypt_dh_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_gcrypt_dh_t *this, chunk_t *secret)
+{
+ if (!this->zz)
+ {
+ return FAILED;
+ }
+ *secret = export_mpi(this->zz, this->p_len);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of gcrypt_dh_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_gcrypt_dh_t *this)
+{
+ return this->group;
+}
+
+/**
+ * Implementation of gcrypt_dh_t.destroy.
+ */
+static void destroy(private_gcrypt_dh_t *this)
+{
+ gcry_mpi_release(this->p);
+ gcry_mpi_release(this->xa);
+ gcry_mpi_release(this->ya);
+ gcry_mpi_release(this->g);
+ gcry_mpi_release(this->yb);
+ gcry_mpi_release(this->zz);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group)
+{
+ private_gcrypt_dh_t *this;
+ modulus_entry_t *entry;
+ gcry_error_t err;
+ chunk_t random;
+ rng_t *rng;
+ size_t len;
+
+ entry = find_entry(group);
+ if (!entry)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_gcrypt_dh_t);
+
+ this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
+ this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
+ this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
+ this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
+ this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
+
+ this->group = group;
+ this->p_len = entry->modulus.len;
+ err = gcry_mpi_scan(&this->p, GCRYMPI_FMT_USG,
+ entry->modulus.ptr, entry->modulus.len, NULL);
+ if (err)
+ {
+ DBG1("importing mpi modulus failed: %s", gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+ if (lib->settings->get_int(lib->settings,
+ "libstrongswan.dh_exponent_ansi_x9_42", TRUE))
+ {
+ len = this->p_len;
+ }
+ else
+ {
+ len = entry->opt_len;
+ }
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (rng)
+ { /* prefer external randomizer */
+ rng->allocate_bytes(rng, len, &random);
+ rng->destroy(rng);
+ err = gcry_mpi_scan(&this->xa, GCRYMPI_FMT_USG,
+ random.ptr, random.len, NULL);
+ chunk_clear(&random);
+ if (err)
+ {
+ DBG1("importing mpi xa failed: %s", gpg_strerror(err));
+ gcry_mpi_release(this->p);
+ free(this);
+ return NULL;
+ }
+ }
+ else
+ { /* fallback to gcrypt internal randomizer, shouldn't ever happen */
+ this->xa = gcry_mpi_new(len * 8);
+ gcry_mpi_randomize(this->xa, len * 8, GCRY_STRONG_RANDOM);
+ }
+ if (len == this->p_len)
+ {
+ /* achieve bitsof(p)-1 by setting MSB to 0 */
+ gcry_mpi_clear_bit(this->xa, len * 8 - 1);
+ }
+
+ this->g = gcry_mpi_set_ui(NULL, entry->g);
+ this->ya = gcry_mpi_new(this->p_len * 8);
+ this->yb = NULL;
+ this->zz = NULL;
+
+ gcry_mpi_powm(this->ya, this->g, this->xa, this->p);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h
new file mode 100644
index 000000000..dbef96ca7
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h
@@ -0,0 +1,48 @@
+/*
+ * 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 gcrypt_dh gcrypt_dh
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_DH_H_
+#define GCRYPT_DH_H_
+
+typedef struct gcrypt_dh_t gcrypt_dh_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm using libgcrypt mpi.
+ */
+struct gcrypt_dh_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new gcrypt_dh_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @return gcrypt_dh_t object, NULL if not supported
+ */
+gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group);
+
+#endif /** GCRYPT_DH_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c
new file mode 100644
index 000000000..785ebda90
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.c
@@ -0,0 +1,151 @@
+/*
+ * 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 "gcrypt_hasher.h"
+
+#include <debug.h>
+
+#include <gcrypt.h>
+
+typedef struct private_gcrypt_hasher_t private_gcrypt_hasher_t;
+
+/**
+ * Private data of gcrypt_hasher_t
+ */
+struct private_gcrypt_hasher_t {
+
+ /**
+ * Public part of this class.
+ */
+ gcrypt_hasher_t public;
+
+ /**
+ * gcrypt hasher context
+ */
+ gcry_md_hd_t hd;
+};
+
+/**
+ * Implementation of hasher_t.get_hash_size.
+ */
+static size_t get_hash_size(private_gcrypt_hasher_t *this)
+{
+ return gcry_md_get_algo_dlen(gcry_md_get_algo(this->hd));
+}
+
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_gcrypt_hasher_t *this)
+{
+ gcry_md_reset(this->hd);
+}
+
+/**
+ * Implementation of hasher_t.get_hash.
+ */
+static void get_hash(private_gcrypt_hasher_t *this, chunk_t chunk,
+ u_int8_t *hash)
+{
+ gcry_md_write(this->hd, chunk.ptr, chunk.len);
+ if (hash)
+ {
+ memcpy(hash, gcry_md_read(this->hd, 0), get_hash_size(this));
+ gcry_md_reset(this->hd);
+ }
+}
+
+/**
+ * Implementation of hasher_t.allocate_hash.
+ */
+static void allocate_hash(private_gcrypt_hasher_t *this, chunk_t chunk,
+ chunk_t *hash)
+{
+ if (hash)
+ {
+ *hash = chunk_alloc(get_hash_size(this));
+ get_hash(this, chunk, hash->ptr);
+ }
+ else
+ {
+ get_hash(this, chunk, NULL);
+ }
+}
+
+/**
+ * Implementation of hasher_t.destroy.
+ */
+static void destroy (private_gcrypt_hasher_t *this)
+{
+ gcry_md_close(this->hd);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+gcrypt_hasher_t *gcrypt_hasher_create(hash_algorithm_t algo)
+{
+ private_gcrypt_hasher_t *this;
+ int gcrypt_alg;
+ gcry_error_t err;
+
+ switch (algo)
+ {
+ case HASH_MD2:
+ gcrypt_alg = GCRY_MD_MD2;
+ break;
+ case HASH_MD4:
+ gcrypt_alg = GCRY_MD_MD4;
+ break;
+ case HASH_MD5:
+ gcrypt_alg = GCRY_MD_MD5;
+ break;
+ case HASH_SHA1:
+ gcrypt_alg = GCRY_MD_SHA1;
+ break;
+ case HASH_SHA256:
+ gcrypt_alg = GCRY_MD_SHA256;
+ break;
+ case HASH_SHA384:
+ gcrypt_alg = GCRY_MD_SHA384;
+ break;
+ case HASH_SHA512:
+ gcrypt_alg = GCRY_MD_SHA512;
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_gcrypt_hasher_t);
+
+ err = gcry_md_open(&this->hd, gcrypt_alg, 0);
+ if (err)
+ {
+ DBG1("grcy_md_open(%N) failed: %s",
+ hash_algorithm_names, algo, gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+
+ this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
+ this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
+ this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
+ this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
+ this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.h b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.h
new file mode 100644
index 000000000..6f724fba8
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_hasher.h
@@ -0,0 +1,47 @@
+/*
+ * 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 gcrypt_hasher gcrypt_hasher
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_HASHER_H_
+#define GCRYPT_HASHER_H_
+
+typedef struct gcrypt_hasher_t gcrypt_hasher_t;
+
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation of hashers using libgcrypt.
+ */
+struct gcrypt_hasher_t {
+
+ /**
+ * The hasher_t interface.
+ */
+ hasher_t hasher_interface;
+};
+
+/**
+ * Constructor to create gcrypt_hasher_t.
+ *
+ * @param algo algorithm
+ * @return gcrypt_hasher_t, NULL if not supported
+ */
+gcrypt_hasher_t *gcrypt_hasher_create(hash_algorithm_t algo);
+
+#endif /** GCRYPT_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
new file mode 100644
index 000000000..547329dde
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
@@ -0,0 +1,212 @@
+/*
+ * 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 "gcrypt_plugin.h"
+
+#include "gcrypt_hasher.h"
+#include "gcrypt_crypter.h"
+#include "gcrypt_rng.h"
+#include "gcrypt_dh.h"
+#include "gcrypt_rsa_private_key.h"
+#include "gcrypt_rsa_public_key.h"
+
+#include <library.h>
+#include <debug.h>
+#include <utils/mutex.h>
+
+#include <errno.h>
+#include <gcrypt.h>
+
+typedef struct private_gcrypt_plugin_t private_gcrypt_plugin_t;
+
+/**
+ * private data of gcrypt_plugin
+ */
+struct private_gcrypt_plugin_t {
+
+ /**
+ * public functions
+ */
+ gcrypt_plugin_t public;
+};
+
+/**
+ * gcrypt mutex initialization wrapper
+ */
+static int mutex_init(void **lock)
+{
+ *lock = mutex_create(MUTEX_DEFAULT);
+ return 0;
+}
+
+/**
+ * gcrypt mutex cleanup wrapper
+ */
+static int mutex_destroy(void **lock)
+{
+ mutex_t *mutex = *lock;
+
+ mutex->destroy(mutex);
+ return 0;
+}
+
+/**
+ * gcrypt mutex lock wrapper
+ */
+static int mutex_lock(void **lock)
+{
+ mutex_t *mutex = *lock;
+
+ mutex->lock(mutex);
+ return 0;
+}
+
+/**
+ * gcrypt mutex unlock wrapper
+ */
+static int mutex_unlock(void **lock)
+{
+ mutex_t *mutex = *lock;
+
+ mutex->unlock(mutex);
+ return 0;
+}
+
+/**
+ * gcrypt locking functions using our mutex_t
+ */
+static struct gcry_thread_cbs thread_functions = {
+ GCRY_THREAD_OPTION_USER, NULL,
+ mutex_init, mutex_destroy, mutex_lock, mutex_unlock,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/**
+ * Implementation of gcrypt_plugin_t.destroy
+ */
+static void destroy(private_gcrypt_plugin_t *this)
+{
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)gcrypt_rng_create);
+ lib->crypto->remove_dh(lib->crypto,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gcrypt_rsa_private_key_builder);
+ lib->creds->remove_builder(lib->creds,
+ (builder_constructor_t)gcrypt_rsa_public_key_builder);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_gcrypt_plugin_t *this;
+
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &thread_functions);
+
+ if (!gcry_check_version(GCRYPT_VERSION))
+ {
+ DBG1("libgcrypt version mismatch");
+ return NULL;
+ }
+
+ /* we currently do not use secure memory */
+ gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
+ if (lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.gcrypt.quick_random", FALSE))
+ {
+ gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ }
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ this = malloc_thing(private_gcrypt_plugin_t);
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ /* hashers */
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD4,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ (hasher_constructor_t)gcrypt_hasher_create);
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ (hasher_constructor_t)gcrypt_hasher_create);
+
+ /* crypters */
+ lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_CAST,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_SERPENT_CBC,
+ (crypter_constructor_t)gcrypt_crypter_create);
+ lib->crypto->add_crypter(lib->crypto, ENCR_TWOFISH_CBC,
+ (crypter_constructor_t)gcrypt_crypter_create);
+
+ /* random numbers */
+ lib->crypto->add_rng(lib->crypto, RNG_WEAK,
+ (rng_constructor_t)gcrypt_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_STRONG,
+ (rng_constructor_t)gcrypt_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_TRUE,
+ (rng_constructor_t)gcrypt_rng_create);
+
+ /* diffie hellman groups, using modp */
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ (dh_constructor_t)gcrypt_dh_create);
+
+ /* RSA */
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_constructor_t)gcrypt_rsa_private_key_builder);
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ (builder_constructor_t)gcrypt_rsa_public_key_builder);
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.h b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.h
new file mode 100644
index 000000000..f2247ed5c
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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 gcrypt_p gcrypt
+ * @ingroup plugins
+ *
+ * @defgroup gcrypt_plugin gcrypt_plugin
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_PLUGIN_H_
+#define GCRYPT_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct gcrypt_plugin_t gcrypt_plugin_t;
+
+/**
+ * Plugin implementing crypto functions via libgcrypt.
+ */
+struct gcrypt_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a gcrypt_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** GCRYPT_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c
new file mode 100644
index 000000000..64b4eb8d0
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.c
@@ -0,0 +1,103 @@
+/*
+ * 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 "gcrypt_rng.h"
+
+#include <gcrypt.h>
+
+typedef struct private_gcrypt_rng_t private_gcrypt_rng_t;
+
+/**
+ * Private data of an gcrypt_rng_t object.
+ */
+struct private_gcrypt_rng_t {
+
+ /**
+ * Public gcrypt_rng_t interface.
+ */
+ gcrypt_rng_t public;
+
+ /**
+ * RNG quality of this instance
+ */
+ rng_quality_t quality;
+};
+
+/**
+ * Implementation of gcrypt_rng_t.get_bytes.
+ */
+static void get_bytes(private_gcrypt_rng_t *this, size_t bytes,
+ u_int8_t *buffer)
+{
+ switch (this->quality)
+ {
+ case RNG_WEAK:
+ gcry_create_nonce(buffer, bytes);
+ break;
+ case RNG_STRONG:
+ gcry_randomize(buffer, bytes, GCRY_STRONG_RANDOM);
+ break;
+ case RNG_TRUE:
+ gcry_randomize(buffer, bytes, GCRY_VERY_STRONG_RANDOM);
+ break;
+ }
+}
+
+/**
+ * Implementation of gcrypt_rng_t.allocate_bytes.
+ */
+static void allocate_bytes(private_gcrypt_rng_t *this, size_t bytes,
+ chunk_t *chunk)
+{
+ *chunk = chunk_alloc(bytes);
+ get_bytes(this, chunk->len, chunk->ptr);
+}
+
+/**
+ * Implementation of gcrypt_rng_t.destroy.
+ */
+static void destroy(private_gcrypt_rng_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+gcrypt_rng_t *gcrypt_rng_create(rng_quality_t quality)
+{
+ private_gcrypt_rng_t *this;
+
+ switch (quality)
+ {
+ case RNG_WEAK:
+ case RNG_STRONG:
+ case RNG_TRUE:
+ break;
+ default:
+ return NULL;
+ }
+
+ this = malloc_thing(private_gcrypt_rng_t);
+
+ this->public.rng.get_bytes = (void (*) (rng_t *, size_t, u_int8_t*)) get_bytes;
+ this->public.rng.allocate_bytes = (void (*) (rng_t *, size_t, chunk_t*)) allocate_bytes;
+ this->public.rng.destroy = (void (*) (rng_t *))destroy;
+
+ this->quality = quality;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rng.h b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.h
new file mode 100644
index 000000000..3cfde8447
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rng.h
@@ -0,0 +1,47 @@
+/*
+ * 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 gcrypt_rng gcrypt_rng
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_RNG_H_
+#define GCRYPT_RNG_H_
+
+typedef struct gcrypt_rng_t gcrypt_rng_t;
+
+#include <library.h>
+
+/**
+ * rng_t implementation using libgcrypt.
+ */
+struct gcrypt_rng_t {
+
+ /**
+ * Implements rng_t.
+ */
+ rng_t rng;
+};
+
+/**
+ * Creates an gcrypt_rng_t instance.
+ *
+ * @param quality required quality of gcryptness
+ * @return created gcrypt_rng_t
+ */
+gcrypt_rng_t *gcrypt_rng_create(rng_quality_t quality);
+
+#endif /** GCRYPT_RNG_H_ @} */
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
new file mode 100644
index 000000000..611ab2467
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2005-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 <gcrypt.h>
+
+#include "gcrypt_rsa_private_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+
+typedef struct private_gcrypt_rsa_private_key_t private_gcrypt_rsa_private_key_t;
+
+/**
+ * Private data of a gcrypt_rsa_private_key_t object.
+ */
+struct private_gcrypt_rsa_private_key_t {
+
+ /**
+ * Public interface
+ */
+ gcrypt_rsa_private_key_t public;
+
+ /**
+ * gcrypt S-expression representing an RSA key
+ */
+ gcry_sexp_t key;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implemented in gcrypt_rsa_public_key.c
+ */
+public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key);
+
+/**
+ * find a token in a S-expression
+ */
+chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name)
+{
+ gcry_sexp_t token;
+ chunk_t data = chunk_empty;
+
+ token = gcry_sexp_find_token(sexp, name, 1);
+ if (token)
+ {
+ data.ptr = (char*)gcry_sexp_nth_data(token, 1, &data.len);
+ if (!data.ptr)
+ {
+ data.len = 0;
+ }
+ data = chunk_clone(data);
+ gcry_sexp_release(token);
+ }
+ return data;
+}
+
+/**
+ * Sign a chunk of data with direct PKCS#1 encoding, no hash OID
+ */
+static bool sign_raw(private_gcrypt_rsa_private_key_t *this,
+ chunk_t data, chunk_t *signature)
+{
+ gcry_sexp_t in, out;
+ gcry_error_t err;
+ chunk_t em;
+ size_t k;
+
+ /* EM = 0x00 || 0x01 || PS || 0x00 || T
+ * PS = 0xFF padding, with length to fill em
+ * T = data
+ */
+ k = gcry_pk_get_nbits(this->key) / 8;
+ if (data.len > k - 3)
+ {
+ return FALSE;
+ }
+ em = chunk_alloc(k);
+ memset(em.ptr, 0xFF, em.len);
+ em.ptr[0] = 0x00;
+ em.ptr[1] = 0x01;
+ em.ptr[em.len - data.len - 1] = 0x00;
+ memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
+
+ err = gcry_sexp_build(&in, NULL, "(data(flags raw)(value %b))",
+ em.len, em.ptr);
+ chunk_free(&em);
+ if (err)
+ {
+ DBG1("building signature S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_sign(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ *signature = gcrypt_rsa_find_token(out, "s");
+ gcry_sexp_release(out);
+ return !!signature->len;
+}
+
+/**
+ * Sign a chunk of data using hashing and PKCS#1 encoding
+ */
+static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this,
+ hash_algorithm_t hash_algorithm, char *hash_name,
+ chunk_t data, chunk_t *signature)
+{
+ hasher_t *hasher;
+ chunk_t hash;
+ gcry_error_t err;
+ gcry_sexp_t in, out;
+ int hash_oid;
+
+ hash_oid = hasher_algorithm_to_oid(hash_algorithm);
+ if (hash_oid == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
+ hash_name, hash.len, hash.ptr);
+ chunk_free(&hash);
+ if (err)
+ {
+ DBG1("building signature S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_sign(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ *signature = gcrypt_rsa_find_token(out, "s");
+ gcry_sexp_release(out);
+ return !!signature->len;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_gcrypt_rsa_private_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.destroy.
+ */
+static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *sig)
+{
+ switch (scheme)
+ {
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return sign_raw(this, data, sig);
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return sign_pkcs1(this, HASH_SHA256, "sha256", data, sig);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return sign_pkcs1(this, HASH_SHA384, "sha384", data, sig);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return sign_pkcs1(this, HASH_SHA512, "sha512", data, sig);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return sign_pkcs1(this, HASH_MD5, "md5", data, sig);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.destroy.
+ */
+static bool decrypt(private_gcrypt_rsa_private_key_t *this,
+ chunk_t encrypted, chunk_t *plain)
+{
+ gcry_error_t err;
+ gcry_sexp_t in, out;
+ chunk_t padded;
+ u_char *pos = NULL;;
+
+ err = gcry_sexp_build(&in, NULL, "(enc-val(flags)(rsa(a %b)))",
+ encrypted.len, encrypted.ptr);
+ if (err)
+ {
+ DBG1("building decryption S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_decrypt(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("decrypting pkcs1 data failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ padded.ptr = (u_char*)gcry_sexp_nth_data(out, 1, &padded.len);
+ /* result is padded, but gcrypt strips leading zero:
+ * 00 | 02 | RANDOM | 00 | DATA */
+ if (padded.ptr && padded.len > 2 && padded.ptr[0] == 0x02)
+ {
+ pos = memchr(padded.ptr, 0x00, padded.len - 1);
+ if (pos)
+ {
+ pos++;
+ *plain = chunk_clone(chunk_create(
+ pos, padded.len - (pos - padded.ptr)));
+ }
+ }
+ gcry_sexp_release(out);
+ if (!pos)
+ {
+ DBG1("decrypted data has invalid pkcs1 padding");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.get_keysize.
+ */
+static size_t get_keysize(private_gcrypt_rsa_private_key_t *this)
+{
+ return gcry_pk_get_nbits(this->key) / 8;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_gcrypt_rsa_private_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.get_public_key.
+ */
+static public_key_t* get_public_key(private_gcrypt_rsa_private_key_t *this)
+{
+ return gcrypt_rsa_public_key_create_from_sexp(this->key);
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.equals.
+ */
+static bool equals(private_gcrypt_rsa_private_key_t *this, private_key_t *other)
+{
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.belongs_to.
+ */
+static bool belongs_to(private_gcrypt_rsa_private_key_t *this,
+ public_key_t *public)
+{
+ identification_t *keyid;
+
+ if (public->get_type(public) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gcrypt_rsa_private_key_t *this)
+{
+ chunk_t cp, cq, cd, cexp1 = chunk_empty, cexp2 = chunk_empty;
+ gcry_mpi_t p = NULL, q = NULL, d = NULL, exp1, exp2;
+ gcry_error_t err;
+
+ /* p and q are swapped, gcrypt expects p < q */
+ cp = gcrypt_rsa_find_token(this->key, "q");
+ cq = gcrypt_rsa_find_token(this->key, "p");
+ cd = gcrypt_rsa_find_token(this->key, "d");
+
+ err = gcry_mpi_scan(&p, GCRYMPI_FMT_USG, cp.ptr, cp.len, NULL)
+ | gcry_mpi_scan(&q, GCRYMPI_FMT_USG, cq.ptr, cq.len, NULL)
+ | gcry_mpi_scan(&d, GCRYMPI_FMT_USG, cd.ptr, cd.len, NULL);
+ if (err)
+ {
+ gcry_mpi_release(p);
+ gcry_mpi_release(q);
+ gcry_mpi_release(d);
+ chunk_clear(&cp);
+ chunk_clear(&cq);
+ chunk_clear(&cd);
+ DBG1("scanning mpi for export failed: %s", gpg_strerror(err));
+ return chunk_empty;
+ }
+
+ gcry_mpi_sub_ui(p, p, 1);
+ exp1 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
+ gcry_mpi_mod(exp1, d, p);
+ gcry_mpi_release(p);
+
+ gcry_mpi_sub_ui(q, q, 1);
+ exp2 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
+ gcry_mpi_mod(exp1, d, q);
+ gcry_mpi_release(q);
+
+ err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp1.ptr, &cexp1.len, exp1)
+ | gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp2.ptr, &cexp2.len, exp2);
+
+ gcry_mpi_release(d);
+ gcry_mpi_release(exp1);
+ gcry_mpi_release(exp2);
+
+ if (err)
+ {
+ DBG1("printing mpi for export failed: %s", gpg_strerror(err));
+ chunk_clear(&cp);
+ chunk_clear(&cq);
+ chunk_clear(&cd);
+ chunk_clear(&cexp1);
+ chunk_clear(&cexp2);
+ return chunk_empty;
+ }
+
+ return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", ASN1_INTEGER_0,
+ asn1_integer("m", gcrypt_rsa_find_token(this->key, "n")),
+ asn1_integer("m", gcrypt_rsa_find_token(this->key, "e")),
+ asn1_integer("m", cd),
+ asn1_integer("m", cp),
+ asn1_integer("m", cq),
+ asn1_integer("m", cexp1),
+ asn1_integer("m", cexp2),
+ asn1_integer("m", gcrypt_rsa_find_token(this->key, "u")));
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.get_ref.
+ */
+static private_key_t* get_ref(private_gcrypt_rsa_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.interface;
+}
+
+/**
+ * Implementation of gcrypt_rsa_private_key.destroy.
+ */
+static void destroy(private_gcrypt_rsa_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ gcry_sexp_release(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_create_empty()
+{
+ private_gcrypt_rsa_private_key_t *this = malloc_thing(private_gcrypt_rsa_private_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
+ this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
+ this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
+ this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
+ this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+
+ this->key = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * build the keyids of a private/public key
+ */
+bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
+ identification_t **keyid_info)
+{
+ chunk_t publicKeyInfo, publicKey, hash;
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+ return FALSE;
+ }
+ publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_integer("m", gcrypt_rsa_find_token(key, "n")),
+ asn1_integer("m", gcrypt_rsa_find_token(key, "e")));
+ hasher->allocate_hash(hasher, publicKey, &hash);
+ *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
+ chunk_free(&hash);
+
+ publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", publicKey));
+ hasher->allocate_hash(hasher, publicKeyInfo, &hash);
+ *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
+ chunk_free(&hash);
+
+ hasher->destroy(hasher);
+ chunk_free(&publicKeyInfo);
+
+ return TRUE;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static gcrypt_rsa_private_key_t *generate(size_t key_size)
+{
+ private_gcrypt_rsa_private_key_t *this;
+ gcry_sexp_t param, key;
+ gcry_error_t err;
+
+ err = gcry_sexp_build(&param, NULL, "(genkey(rsa(nbits %d)))", key_size);
+ if (err)
+ {
+ DBG1("building S-expression failed: %s", gpg_strerror(err));
+ return NULL;
+ }
+
+ err = gcry_pk_genkey(&key, param);
+ gcry_sexp_release(param);
+ if (err)
+ {
+ DBG1("generating RSA key failed: %s", gpg_strerror(err));
+ return NULL;
+ }
+ this = gcrypt_rsa_private_key_create_empty();
+ this->key = key;
+
+ if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+/**
+ * ASN.1 definition of a PKCS#1 RSA private key
+ */
+static const asn1Object_t privkeyObjects[] = {
+ { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
+ { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
+ { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
+ { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 10 */
+ { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
+ { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
+ { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
+ { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
+ { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PRIV_KEY_VERSION 1
+#define PRIV_KEY_MODULUS 2
+#define PRIV_KEY_PUB_EXP 3
+#define PRIV_KEY_PRIV_EXP 4
+#define PRIV_KEY_PRIME1 5
+#define PRIV_KEY_PRIME2 6
+#define PRIV_KEY_EXP1 7
+#define PRIV_KEY_EXP2 8
+#define PRIV_KEY_COEFF 9
+
+/**
+ * load private key from a ASN1 encoded blob
+ */
+static gcrypt_rsa_private_key_t *load(chunk_t blob)
+{
+ private_gcrypt_rsa_private_key_t *this;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID ;
+ bool success = FALSE;
+ chunk_t n, e, d, u, p, q;
+ gcry_error_t err;
+
+ n = e = d = u = p = q = chunk_empty;
+
+ parser = asn1_parser_create(privkeyObjects, blob);
+ parser->set_flags(parser, FALSE, TRUE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PRIV_KEY_VERSION:
+ if (object.len > 0 && *object.ptr != 0)
+ {
+ goto end;
+ }
+ break;
+ case PRIV_KEY_MODULUS:
+ n = object;
+ break;
+ case PRIV_KEY_PUB_EXP:
+ e = object;
+ break;
+ case PRIV_KEY_PRIV_EXP:
+ d = object;
+ break;
+ case PRIV_KEY_PRIME1:
+ /* p and q are swapped, as gcrypt expects p < q */
+ q = object;
+ break;
+ case PRIV_KEY_PRIME2:
+ p = object;
+ break;
+ case PRIV_KEY_EXP1:
+ case PRIV_KEY_EXP2:
+ break;
+ case PRIV_KEY_COEFF:
+ u = object;
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+
+ if (!success)
+ {
+ return NULL;
+ }
+
+ this = gcrypt_rsa_private_key_create_empty();
+ err = gcry_sexp_build(&this->key, NULL,
+ "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
+ n.len, n.ptr, e.len, e.ptr, d.len, d.ptr,
+ p.len, p.ptr, q.len, q.ptr, u.len, u.ptr);
+ if (err)
+ {
+ DBG1("loading private key failed: %s", gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+ err = gcry_pk_testkey(this->key);
+ if (err)
+ {
+ DBG1("private key sanity check failed: %s", gpg_strerror(err));
+ destroy(this);
+ return NULL;
+ }
+ if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+
+/**
+ * Builder implementation for key loading/generation
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded/generated private key */
+ gcrypt_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gcrypt_rsa_private_key_t *build(private_builder_t *this)
+{
+ gcrypt_rsa_private_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ if (!this->key)
+ {
+ va_list args;
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ return;
+ }
+ case BUILD_KEY_SIZE:
+ {
+ va_start(args, part);
+ this->key = generate(va_arg(args, u_int));
+ va_end(args);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ if (this->key)
+ {
+ destroy((private_gcrypt_rsa_private_key_t*)this->key);
+ }
+ builder_cancel(&this->public);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gcrypt_rsa_private_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.h b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.h
new file mode 100644
index 000000000..2edd7ce5d
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.h
@@ -0,0 +1,47 @@
+/*
+ * 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 gcrypt_rsa_private_key gcrypt_rsa_private_key
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_RSA_PRIVATE_KEY_H_
+#define GCRYPT_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct gcrypt_rsa_private_key_t gcrypt_rsa_private_key_t;
+
+/**
+ * Private_key_t implementation of RSA algorithm using libgcrypt.
+ */
+struct gcrypt_rsa_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t interface;
+};
+
+/**
+ * Create the builder for a private key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gcrypt_rsa_private_key_builder(key_type_t type);
+
+#endif /** GCRYPT_RSA_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
new file mode 100644
index 000000000..8024f58a7
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2005-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 <gcrypt.h>
+
+#include "gcrypt_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/pem.h>
+#include <crypto/hashers/hasher.h>
+
+typedef struct private_gcrypt_rsa_public_key_t private_gcrypt_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_gcrypt_rsa_public_key_t {
+
+ /**
+ * Public interface for this signer.
+ */
+ gcrypt_rsa_public_key_t public;
+
+ /**
+ * gcrypt S-expression representing an public RSA key
+ */
+ gcry_sexp_t key;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKey object
+ */
+ identification_t* keyid;
+
+ /**
+ * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+ */
+ identification_t* keyid_info;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+/**
+ * Implemented in gcrypt_rsa_private_key.c
+ */
+chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name);
+bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
+ identification_t **keyid_info);
+
+/**
+ * verification of a padded PKCS1 signature without an OID
+ */
+static bool verify_raw(private_gcrypt_rsa_public_key_t *this,
+ chunk_t data, chunk_t signature)
+{
+ gcry_sexp_t in, sig;
+ gcry_error_t err;
+ chunk_t em;
+ size_t k;
+
+ /* EM = 0x00 || 0x01 || PS || 0x00 || T
+ * PS = 0xFF padding, with length to fill em
+ * T = data
+ */
+ k = gcry_pk_get_nbits(this->key) / 8;
+ if (data.len > k - 3)
+ {
+ return FALSE;
+ }
+ em = chunk_alloc(k);
+ memset(em.ptr, 0xFF, em.len);
+ em.ptr[0] = 0x00;
+ em.ptr[1] = 0x01;
+ em.ptr[em.len - data.len - 1] = 0x00;
+ memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
+
+ err = gcry_sexp_build(&in, NULL, "(data(flags raw)(value %b))",
+ em.len, em.ptr);
+ chunk_free(&em);
+ if (err)
+ {
+ DBG1("building data S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
+ signature.len, signature.ptr);
+ if (err)
+ {
+ DBG1("building signature S-expression failed: %s", gpg_strerror(err));
+ gcry_sexp_release(in);
+ return FALSE;
+ }
+ err = gcry_pk_verify(sig, in, this->key);
+ gcry_sexp_release(in);
+ gcry_sexp_release(sig);
+ if (err)
+ {
+ DBG1("RSA signature verification failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Verification of an EMSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
+ hash_algorithm_t algorithm, char *hash_name,
+ chunk_t data, chunk_t signature)
+{
+ hasher_t *hasher;
+ chunk_t hash;
+ gcry_error_t err;
+ gcry_sexp_t in, sig;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, algorithm);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
+ hash_name, hash.len, hash.ptr);
+ chunk_free(&hash);
+ if (err)
+ {
+ DBG1("building data S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+
+ err = gcry_sexp_build(&sig, NULL, "(sig-val(rsa(s %b)))",
+ signature.len, signature.ptr);
+ if (err)
+ {
+ DBG1("building signature S-expression failed: %s", gpg_strerror(err));
+ gcry_sexp_release(in);
+ return FALSE;
+ }
+ err = gcry_pk_verify(sig, in, this->key);
+ gcry_sexp_release(in);
+ gcry_sexp_release(sig);
+ if (err)
+ {
+ DBG1("RSA signature verification failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_gcrypt_rsa_public_key_t *this)
+{
+ return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_gcrypt_rsa_public_key_t *this,
+ signature_scheme_t scheme, chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return verify_raw(this, data, signature);
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return verify_pkcs1(this, HASH_SHA1, "sha1", data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return verify_pkcs1(this, HASH_SHA256, "sha256", data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return verify_pkcs1(this, HASH_SHA384, "sha384", data, signature);
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return verify_pkcs1(this, HASH_SHA512, "sha512", data, signature);
+ default:
+ DBG1("signature scheme %N not supported in RSA",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+/**
+ * Implementation of public_key_t.encrypt.
+ */
+static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t plain,
+ chunk_t *encrypted)
+{
+ gcry_sexp_t in, out;
+ gcry_error_t err;
+
+ /* "pkcs1" uses PKCS 1.5 (section 8.1) block type 2 encryption:
+ * 00 | 02 | RANDOM | 00 | DATA */
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(value %b))",
+ plain.len, plain.ptr);
+ if (err)
+ {
+ DBG1("building encryption S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_encrypt(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("encrypting data using pkcs1 failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ *encrypted = gcrypt_rsa_find_token(out, "a");
+ gcry_sexp_release(out);
+ return !!encrypted->len;
+}
+
+/**
+ * Implementation of gcrypt_rsa_public_key.equals.
+ */
+static bool equals(private_gcrypt_rsa_public_key_t *this, public_key_t *other)
+{
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static size_t get_keysize(private_gcrypt_rsa_public_key_t *this)
+{
+ return gcry_pk_get_nbits(this->key) / 8;
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_gcrypt_rsa_public_key_t *this,
+ id_type_t type)
+{
+ switch (type)
+ {
+ case ID_PUBKEY_INFO_SHA1:
+ return this->keyid_info;
+ case ID_PUBKEY_SHA1:
+ return this->keyid;
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Implementation of public_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gcrypt_rsa_public_key_t *this)
+{
+ return asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_integer("m", gcrypt_rsa_find_token(this->key, "n")),
+ asn1_integer("m", gcrypt_rsa_find_token(this->key, "e")));
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static public_key_t* get_ref(private_gcrypt_rsa_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.interface;
+}
+
+/**
+ * Implementation of gcrypt_rsa_public_key.destroy.
+ */
+static void destroy(private_gcrypt_rsa_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->keyid);
+ DESTROY_IF(this->keyid_info);
+ gcry_sexp_release(this->key);
+ free(this);
+ }
+}
+
+/**
+ * Generic private constructor
+ */
+static private_gcrypt_rsa_public_key_t *gcrypt_rsa_public_key_create_empty()
+{
+ private_gcrypt_rsa_public_key_t *this = malloc_thing(private_gcrypt_rsa_public_key_t);
+
+ this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
+ this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
+ this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+
+ this->key = NULL;
+ this->keyid = NULL;
+ this->keyid_info = NULL;
+ this->ref = 1;
+
+ return this;
+}
+
+/**
+ * Create a public key from a S-expression, used in gcrypt_rsa_private_key
+ */
+public_key_t *gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key)
+{
+ private_gcrypt_rsa_public_key_t *this;
+ gcry_error_t err;
+ chunk_t n, e;
+
+ this = gcrypt_rsa_public_key_create_empty();
+ n = gcrypt_rsa_find_token(key, "n");
+ e = gcrypt_rsa_find_token(key, "e");
+
+ err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
+ n.len, n.ptr, e.len, e.ptr);
+ chunk_free(&n);
+ chunk_free(&e);
+ if (err)
+ {
+ DBG1("loading public key failed: %s", gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+ if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public.interface;
+}
+
+/**
+ * ASN.1 definition of RSApublicKey
+ */
+static const asn1Object_t pubkeyObjects[] = {
+ { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PUB_KEY_RSA_PUBLIC_KEY 0
+#define PUB_KEY_MODULUS 1
+#define PUB_KEY_EXPONENT 2
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static gcrypt_rsa_public_key_t *load(chunk_t blob)
+{
+ private_gcrypt_rsa_public_key_t *this;
+ asn1_parser_t *parser;
+ chunk_t object, n, e;
+ int objectID;
+ bool success = FALSE;
+ gcry_error_t err;
+
+ n = e = chunk_empty;
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PUB_KEY_MODULUS:
+ n = object;
+ break;
+ case PUB_KEY_EXPONENT:
+ e = object;
+ break;
+ }
+ }
+ success = parser->success(parser);
+ parser->destroy(parser);
+
+ if (!success)
+ {
+ return NULL;
+ }
+
+ this = gcrypt_rsa_public_key_create_empty();
+ err = gcry_sexp_build(&this->key, NULL, "(public-key(rsa(n %b)(e %b)))",
+ n.len, n.ptr, e.len, e.ptr);
+ if (err)
+ {
+ DBG1("loading public key failed: %s", gpg_strerror(err));
+ free(this);
+ return NULL;
+ }
+ if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for key loading
+ */
+struct private_builder_t {
+ /** implements the builder interface */
+ builder_t public;
+ /** loaded public key */
+ gcrypt_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gcrypt_rsa_public_key_t *build(private_builder_t *this)
+{
+ gcrypt_rsa_public_key_t *key = this->key;
+
+ free(this);
+ return key;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+ if (!this->key)
+ {
+ va_list args;
+
+ switch (part)
+ {
+ case BUILD_BLOB_ASN1_DER:
+ {
+ va_start(args, part);
+ this->key = load(va_arg(args, chunk_t));
+ va_end(args);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ if (this->key)
+ {
+ destroy((private_gcrypt_rsa_public_key_t*)this->key);
+ }
+ builder_cancel(&this->public);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gcrypt_rsa_public_key_builder(key_type_t type)
+{
+ private_builder_t *this;
+
+ if (type != KEY_RSA)
+ {
+ return NULL;
+ }
+
+ this = malloc_thing(private_builder_t);
+
+ this->key = NULL;
+ this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
+ this->public.build = (void*(*)(builder_t *this))build;
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.h b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.h
new file mode 100644
index 000000000..102547276
--- /dev/null
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.h
@@ -0,0 +1,47 @@
+/*
+ * 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 gcrypt_rsa_public_key gcrypt_rsa_public_key
+ * @{ @ingroup gcrypt_p
+ */
+
+#ifndef GCRYPT_RSA_PUBLIC_KEY_H_
+#define GCRYPT_RSA_PUBLIC_KEY_H_
+
+typedef struct gcrypt_rsa_public_key_t gcrypt_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using libgcrypt.
+ */
+struct gcrypt_rsa_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t interface;
+};
+
+/**
+ * Create the builder for a public key.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @return builder instance
+ */
+builder_t *gcrypt_rsa_public_key_builder(key_type_t type);
+
+#endif /** GCRYPT_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index c406f3af6..a60cd998c 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -227,8 +236,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -325,7 +334,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
index 294fb722f..a03e83e66 100644
--- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gmp_diffie_hellman.c 4566 2008-11-04 13:12:11Z martin $
*/
#include <gmp.h>
@@ -30,7 +28,7 @@
*/
static u_int8_t group1_modulus[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
- 0xC4,0xC6,0x62,0x8B,0x80 ,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
+ 0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
@@ -562,7 +560,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
}
ansi_x9_42 = lib->settings->get_int(lib->settings,
- "charon.dh_exponent_ansi_x9_42", TRUE);
+ "libstrongswan.dh_exponent_ansi_x9_42", TRUE);
exponent_len = (ansi_x9_42) ? this->p_len : this->opt_exponent_len;
rng->allocate_bytes(rng, exponent_len, &random);
rng->destroy(rng);
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
index 7711b6d34..f6ea964c1 100644
--- a/src/libstrongswan/plugins/gmp/gmp_plugin.c
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gmp_plugin.c 4309 2008-08-28 11:07:57Z martin $
*/
#include "gmp_plugin.h"
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
index e445dd670..cbc112762 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gmp_rsa_private_key.c 4345 2008-09-17 08:10:48Z martin $
*/
#include <gmp.h>
@@ -28,6 +26,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
+#include <pgp/pgp.h>
/**
* Public exponent to use for key generation.
@@ -112,11 +111,12 @@ struct private_gmp_rsa_private_key_t {
};
/**
- * shared functions, implemented in gmp_rsa_public_key.c
+ * Shared functions defined in gmp_rsa_public_key.c
*/
-bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
- identification_t **keyid_info);
-gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
+extern bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e,
+ identification_t **keyid,
+ identification_t **keyid_info);
+extern gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
/**
* Auxiliary function overwriting private key material with zero bytes
@@ -141,10 +141,10 @@ static status_t compute_prime(private_gmp_rsa_private_key_t *this,
rng_t *rng;
chunk_t random_bytes;
- rng = lib->crypto->create_rng(lib->crypto, RNG_REAL);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
if (!rng)
{
- DBG1("no RNG of quality %N found", rng_quality_names, RNG_REAL);
+ DBG1("no RNG of quality %N found", rng_quality_names, RNG_TRUE);
return FAILED;
}
@@ -217,33 +217,44 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
hash_algorithm_t hash_algorithm,
chunk_t data, chunk_t *signature)
{
- hasher_t *hasher;
- chunk_t em, digestInfo, hash;
- int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
-
- if (hash_oid == OID_UNKNOWN)
+ chunk_t digestInfo = chunk_empty;
+ chunk_t em;
+
+ if (hash_algorithm != HASH_UNKNOWN)
{
- return FALSE;
+ hasher_t *hasher;
+ chunk_t hash;
+ int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
+
+ if (hash_oid == OID_UNKNOWN)
+ {
+ return FALSE;
+ }
+
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (hasher == NULL)
+ {
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+
+ /* build DER-encoded digestInfo */
+ digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(hash_oid),
+ asn1_simple_object(ASN1_OCTET_STRING, hash)
+ );
+ chunk_free(&hash);
+ data = digestInfo;
}
- /* get hasher */
- hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
- if (hasher == NULL)
+ if (data.len > this->k - 3)
{
+ free(digestInfo.ptr);
+ DBG1("unable to sign %d bytes using a %dbit key", data.len, this->k * 8);
return FALSE;
}
- /* build hash */
- hasher->allocate_hash(hasher, data, &hash);
- hasher->destroy(hasher);
-
- /* build DER-encoded digestInfo */
- digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_algorithmIdentifier(hash_oid),
- asn1_simple_object(ASN1_OCTET_STRING, hash)
- );
- chunk_free(&hash);
-
/* build chunk to rsa-decrypt:
* EM = 0x00 || 0x01 || PS || 0x00 || T.
* PS = 0xFF padding, with length to fill em
@@ -257,9 +268,9 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
/* set magic bytes */
*(em.ptr) = 0x00;
*(em.ptr+1) = 0x01;
- *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
+ *(em.ptr + em.len - data.len - 1) = 0x00;
/* set DER-encoded hash */
- memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
+ memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
/* build signature */
*signature = rsasp1(this, em);
@@ -271,7 +282,7 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.get_type.
*/
static key_type_t get_type(private_gmp_rsa_private_key_t *this)
{
@@ -279,15 +290,15 @@ static key_type_t get_type(private_gmp_rsa_private_key_t *this)
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.sign.
*/
static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
{
switch (scheme)
{
- case SIGN_DEFAULT:
- /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return build_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -306,17 +317,46 @@ static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.decrypt.
*/
-static bool decrypt(private_gmp_rsa_private_key_t *this,
- chunk_t crypto, chunk_t *plain)
+static bool decrypt(private_gmp_rsa_private_key_t *this, chunk_t crypto,
+ chunk_t *plain)
{
- DBG1("RSA private key decryption not implemented");
- return FALSE;
+ chunk_t em, stripped;
+ bool success = FALSE;
+
+ /* rsa decryption using PKCS#1 RSADP */
+ stripped = em = rsadp(this, crypto);
+
+ /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
+
+ /* check for hex pattern 00 02 in decrypted message */
+ if ((*stripped.ptr++ != 0x00) || (*(stripped.ptr++) != 0x02))
+ {
+ DBG1("incorrect padding - probably wrong rsa key");
+ goto end;
+ }
+ stripped.len -= 2;
+
+ /* the plaintext data starts after first 0x00 byte */
+ while (stripped.len-- > 0 && *stripped.ptr++ != 0x00)
+
+ if (stripped.len == 0)
+ {
+ DBG1("no plaintext data");
+ goto end;
+ }
+
+ *plain = chunk_clone(stripped);
+ success = TRUE;
+
+end:
+ chunk_clear(&em);
+ return success;
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.get_keysize.
*/
static size_t get_keysize(private_gmp_rsa_private_key_t *this)
{
@@ -324,7 +364,7 @@ static size_t get_keysize(private_gmp_rsa_private_key_t *this)
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.get_id.
*/
static identification_t* get_id(private_gmp_rsa_private_key_t *this,
id_type_t type)
@@ -349,7 +389,35 @@ static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.equals.
+ */
+static bool equals(private_gmp_rsa_private_key_t *this, private_key_t *other)
+{
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.belongs_to.
*/
static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public)
{
@@ -373,19 +441,27 @@ static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public
}
/**
- * convert a MP integer into a DER coded ASN.1 object
+ * Convert a MP integer into a chunk_t
*/
-chunk_t gmp_mpz_to_asn1(const mpz_t value)
+chunk_t gmp_mpz_to_chunk(const mpz_t value)
{
chunk_t n;
- n.len = 1 + mpz_sizeinbase(value, 2) / 8; /* size in bytes */
+ n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE;
n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
if (n.ptr == NULL)
{ /* if we have zero in "value", gmp returns NULL */
n.len = 0;
}
- return asn1_wrap(ASN1_INTEGER, "m", n);
+ return n;
+}
+
+/**
+ * Convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t gmp_mpz_to_asn1(const mpz_t value)
+{
+ return asn1_wrap(ASN1_INTEGER, "m", gmp_mpz_to_chunk(value));
}
/**
@@ -406,7 +482,7 @@ static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
}
/**
- * Implementation of gmp_rsa_private_key.destroy.
+ * Implementation of gmp_rsa_private_key.get_ref.
*/
static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
{
@@ -447,14 +523,14 @@ static status_t check(private_gmp_rsa_private_key_t *this)
/* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
* We actually require more (for security).
*/
- if (this->k < 512/8)
+ if (this->k < 512 / BITS_PER_BYTE)
{
DBG1("key shorter than 512 bits");
return FAILED;
}
/* we picked a max modulus size to simplify buffer allocation */
- if (this->k > 8192/8)
+ if (this->k > 8192 / BITS_PER_BYTE)
{
DBG1("key larger than 8192 bits");
return FAILED;
@@ -542,16 +618,17 @@ static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
{
private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_rsa_private_key_t);
- this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
- this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
- this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
- this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
- this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
- this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
- this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
- this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
- this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+ this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type;
+ this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign;
+ this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
+ this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
+ this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to;
+ this->public.interface.get_encoding = (chunk_t (*) (private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref;
+ this->public.interface.destroy = (void (*) (private_key_t*))destroy;
this->keyid = NULL;
this->keyid_info = NULL;
@@ -569,7 +646,7 @@ static gmp_rsa_private_key_t *generate(size_t key_size)
mpz_t m, q1, t;
private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
- key_size = key_size / 8;
+ key_size = key_size / BITS_PER_BYTE;
/* Get values of primes p and q */
if (compute_prime(this, key_size/2, &p) != SUCCESS)
@@ -680,7 +757,7 @@ static const asn1Object_t privkeyObjects[] = {
/**
* load private key from a ASN1 encoded blob
*/
-static gmp_rsa_private_key_t *load(chunk_t blob)
+static gmp_rsa_private_key_t *load_asn1_der(chunk_t blob)
{
asn1_parser_t *parser;
chunk_t object;
@@ -708,6 +785,7 @@ static gmp_rsa_private_key_t *load(chunk_t blob)
case PRIV_KEY_VERSION:
if (object.len > 0 && *object.ptr != 0)
{
+ DBG1("PKCS#1 private key format is not version 1");
goto end;
}
break;
@@ -757,13 +835,144 @@ end:
destroy(this);
return NULL;
}
+ if (check(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+/**
+ * load private key from an OpenPGP blob coded according to section
+ */
+static gmp_rsa_private_key_t *load_pgp(chunk_t blob)
+{
+ mpz_t u;
+ int objectID;
+ chunk_t packet = blob;
+ private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+ mpz_init(this->p);
+ mpz_init(this->q);
+ mpz_init(this->d);
+ mpz_init(this->exp1);
+ mpz_init(this->exp2);
+ mpz_init(this->coeff);
+
+ for (objectID = PRIV_KEY_MODULUS; objectID <= PRIV_KEY_COEFF; objectID++)
+ {
+ chunk_t object;
+
+ switch (objectID)
+ {
+ case PRIV_KEY_PRIV_EXP:
+ {
+ pgp_sym_alg_t s2k;
+
+ /* string-to-key usage */
+ s2k = pgp_length(&packet, 1);
+ DBG2("L3 - string-to-key: %d", s2k);
+
+ if (s2k == 255 || s2k == 254)
+ {
+ DBG1("string-to-key specifiers not supported");
+ goto end;
+ }
+ DBG2(" %N", pgp_sym_alg_names, s2k);
+
+ if (s2k != PGP_SYM_ALG_PLAIN)
+ {
+ DBG1("%N encryption not supported", pgp_sym_alg_names, s2k);
+ goto end;
+ }
+ break;
+ }
+ case PRIV_KEY_EXP1:
+ case PRIV_KEY_EXP2:
+ /* not contained in OpenPGP secret key payload */
+ continue;
+ default:
+ break;
+ }
+
+ DBG2("L3 - %s:", privkeyObjects[objectID].name);
+ object.len = pgp_length(&packet, 2);
+
+ if (object.len == PGP_INVALID_LENGTH)
+ {
+ DBG1("OpenPGP length is invalid");
+ goto end;
+ }
+ object.len = (object.len + 7) / BITS_PER_BYTE;
+ if (object.len > packet.len)
+ {
+ DBG1("OpenPGP field is too short");
+ goto end;
+ }
+ object.ptr = packet.ptr;
+ packet.ptr += object.len;
+ packet.len -= object.len;
+ DBG4("%B", &object);
+
+ switch (objectID)
+ {
+ case PRIV_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PUB_EXP:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIV_EXP:
+ mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME1:
+ mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_PRIME2:
+ mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PRIV_KEY_COEFF:
+ mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+
+ /* auxiliary variable */
+ mpz_init(u);
+
+ /* exp1 = d mod (p-1) */
+ mpz_sub_ui(u, this->p, 1);
+ mpz_mod(this->exp1, this->d, u);
+
+ /* exp2 = d mod (q-1) */
+ mpz_sub_ui(u, this->q, 1);
+ mpz_mod(this->exp2, this->d, u);
+
+ mpz_clear(u);
+ chunk_clear(&blob);
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
if (check(this) != SUCCESS)
{
destroy(this);
return NULL;
}
return &this->public;
+
+end:
+ chunk_clear(&blob);
+ destroy(this);
+ return NULL;
}
typedef struct private_builder_t private_builder_t;
@@ -804,7 +1013,15 @@ static void add(private_builder_t *this, builder_part_t part, ...)
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
+ this->key = load_asn1_der(chunk_clone(chunk));
+ va_end(args);
+ return;
+ }
+ case BUILD_BLOB_PGP:
+ {
+ va_start(args, part);
+ chunk = va_arg(args, chunk_t);
+ this->key = load_pgp(chunk_clone(chunk));
va_end(args);
return;
}
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index 8a89849cd..1f3e3072f 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gmp_rsa_public_key.c 4345 2008-09-17 08:10:48Z martin $
*/
#include <gmp.h>
@@ -30,11 +28,7 @@
#include <asn1/asn1_parser.h>
#include <asn1/pem.h>
#include <crypto/hashers/hasher.h>
-
-/**
- * defined in gmp_rsa_private_key.c
- */
-extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
+#include <pgp/pgp.h>
typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t;
@@ -79,6 +73,12 @@ struct private_gmp_rsa_public_key_t {
};
/**
+ * Shared functions defined in gmp_rsa_private_key.c
+ */
+extern chunk_t gmp_mpz_to_chunk(const mpz_t value);
+extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
+
+/**
* RSAEP algorithm specified in PKCS#1.
*/
static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data)
@@ -140,11 +140,10 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
/* remove any preceding 0-bytes from signature */
while (signature.len && *(signature.ptr) == 0x00)
{
- signature.len -= 1;
- signature.ptr++;
+ signature = chunk_skip(signature, 1);
}
- if (signature.len > this->k)
+ if (signature.len == 0 || signature.len > this->k)
{
return INVALID_ARG;
}
@@ -163,8 +162,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
{
goto end;
}
- em.ptr += 2;
- em.len -= 2;
+ em = chunk_skip(em, 2);
/* find magic 0x00 */
while (em.len > 0)
@@ -172,8 +170,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
if (*em.ptr == 0x00)
{
/* found magic byte, stop */
- em.ptr++;
- em.len--;
+ em = chunk_skip(em, 1);
break;
}
else if (*em.ptr != 0xFF)
@@ -181,8 +178,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
/* bad padding, decryption failed ?!*/
goto end;
}
- em.ptr++;
- em.len--;
+ em = chunk_skip(em, 1);
}
if (em.len == 0)
@@ -191,13 +187,24 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
goto end;
}
- /* parse ASN.1-based digestInfo */
- {
+ if (algorithm == HASH_UNKNOWN)
+ { /* IKEv1 signatures without digestInfo */
+ if (em.len != data.len)
+ {
+ DBG1("hash size in signature is %u bytes instead of %u bytes",
+ em.len, data.len);
+ goto end;
+ }
+ success = memeq(em.ptr, data.ptr, data.len);
+ }
+ else
+ { /* IKEv2 and X.509 certificate signatures */
asn1_parser_t *parser;
chunk_t object;
int objectID;
hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
+ DBG2("signature verification:");
parser = asn1_parser_create(digestInfoObjects, em);
while (parser->iterate(parser, &objectID, &object))
@@ -220,8 +227,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
parser->get_level(parser)+1, NULL);
hash_algorithm = hasher_algorithm_from_oid(hash_oid);
- if (hash_algorithm == HASH_UNKNOWN ||
- (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
+ if (hash_algorithm == HASH_UNKNOWN || hash_algorithm != algorithm)
{
DBG1("expected hash algorithm %N, but found %N (OID: %#B)",
hash_algorithm_names, algorithm,
@@ -289,7 +295,7 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme
{
switch (scheme)
{
- case SIGN_DEFAULT: /* default is EMSA-PKCS1 using included OID */
+ case SIGN_RSA_EMSA_PKCS1_NULL:
return verify_emsa_pkcs1_signature(this, HASH_UNKNOWN, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
@@ -308,12 +314,96 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme
}
}
+#define MIN_PS_PADDING 8
+
/**
- * Implementation of public_key_t.get_keysize.
+ * Implementation of public_key_t.encrypt.
+ */
+static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain,
+ chunk_t *crypto)
+{
+ chunk_t em;
+ u_char *pos;
+ int padding, i;
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (rng == NULL)
+ {
+ DBG1("no random generator available");
+ return FALSE;
+ }
+
+ /* number of pseudo-random padding octets */
+ padding = this->k - plain.len - 3;
+ if (padding < MIN_PS_PADDING)
+ {
+ DBG1("pseudo-random padding must be at least %d octets", MIN_PS_PADDING);
+ return FALSE;
+ }
+
+ /* padding according to PKCS#1 7.2.1 (RSAES-PKCS1-v1.5-ENCRYPT) */
+ DBG2("padding %u bytes of data to the rsa modulus size of %u bytes",
+ plain.len, this->k);
+ em.len = this->k;
+ em.ptr = malloc(em.len);
+ pos = em.ptr;
+ *pos++ = 0x00;
+ *pos++ = 0x02;
+
+ /* fill with pseudo random octets */
+ rng->get_bytes(rng, padding, pos);
+
+ /* replace zero-valued random octets */
+ for (i = 0; i < padding; i++)
+ {
+ while (*pos == 0)
+ {
+ rng->get_bytes(rng, 1, pos);
+ }
+ pos++;
+ }
+ rng->destroy(rng);
+
+ /* append the padding terminator */
+ *pos++ = 0x00;
+
+ /* now add the data */
+ memcpy(pos, plain.ptr, plain.len);
+ DBG3("padded data before rsa encryption: %B", &em);
+
+ /* rsa encryption using PKCS#1 RSAEP */
+ *crypto = rsaep(this, em);
+ DBG3("rsa encrypted data: %B", crypto);
+ chunk_clear(&em);
+ return TRUE;
+}
+
+/**
+ * Implementation of gmp_rsa_public_key.equals.
*/
-static bool encrypt(private_gmp_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+static bool equals(private_gmp_rsa_public_key_t *this, public_key_t *other)
{
- DBG1("RSA public key encryption not implemented");
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
return FALSE;
}
@@ -326,6 +416,46 @@ static size_t get_keysize(private_gmp_rsa_public_key_t *this)
}
/**
+ * Build the PGP version 3 RSA key identifier from n and e using
+ * MD5 hashed modulus and exponent. Also used in rsa_private_key.c.
+ */
+static identification_t* gmp_rsa_build_pgp_v3_keyid(mpz_t n, mpz_t e)
+{
+ identification_t *keyid;
+ chunk_t modulus, mod, exponent, exp, hash;
+ hasher_t *hasher;
+
+ hasher= lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ if (hasher == NULL)
+ {
+ DBG1("computation of PGP V3 keyid failed, no MD5 hasher is available");
+ return NULL;
+ }
+ mod = modulus = gmp_mpz_to_chunk(n);
+ exp = exponent = gmp_mpz_to_chunk(e);
+
+ /* remove leading zero bytes before hashing modulus and exponent */
+ while (mod.len > 0 && *mod.ptr == 0x00)
+ {
+ mod.ptr++;
+ mod.len--;
+ }
+ while (exp.len > 0 && *exp.ptr == 0x00)
+ {
+ exp.ptr++;
+ exp.len--;
+ }
+ hasher->allocate_hash(hasher, mod, NULL);
+ hasher->allocate_hash(hasher, exp, &hash);
+ hasher->destroy(hasher);
+ keyid = identification_create_from_encoding(ID_KEY_ID, hash);
+ free(hash.ptr);
+ free(modulus.ptr);
+ free(exponent.ptr);
+ return keyid;
+}
+
+/**
* Implementation of public_key_t.get_id.
*/
static identification_t *get_id(private_gmp_rsa_public_key_t *this,
@@ -337,6 +467,8 @@ static identification_t *get_id(private_gmp_rsa_public_key_t *this,
return this->keyid_info;
case ID_PUBKEY_SHA1:
return this->keyid;
+ case ID_KEY_ID:
+ return gmp_rsa_build_pgp_v3_keyid(this->n, this->e);
default:
return NULL;
}
@@ -383,14 +515,15 @@ static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty()
{
private_gmp_rsa_public_key_t *this = malloc_thing(private_gmp_rsa_public_key_t);
- this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
- this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
- this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
- this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
- this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
- this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
- this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
+ this->public.interface.get_type = (key_type_t (*) (public_key_t*))get_type;
+ this->public.interface.verify = (bool (*) (public_key_t*, signature_scheme_t, chunk_t, chunk_t))verify;
+ this->public.interface.encrypt = (bool (*) (public_key_t*, chunk_t, chunk_t*))encrypt_;
+ this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
+ this->public.interface.get_keysize = (size_t (*) (public_key_t*))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (public_key_t*, id_type_t))get_id;
+ this->public.interface.get_encoding = (chunk_t(*) (public_key_t*))get_encoding;
+ this->public.interface.get_ref = (public_key_t* (*) (public_key_t *this))get_ref;
+ this->public.interface.destroy = (void (*) (public_key_t *this))destroy;
this->keyid = NULL;
this->keyid_info = NULL;
@@ -445,7 +578,7 @@ gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e)
mpz_init_set(this->n, n);
mpz_init_set(this->e, e);
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
{
@@ -469,9 +602,9 @@ static const asn1Object_t pubkeyObjects[] = {
#define PUB_KEY_EXPONENT 2
/**
- * Load a public key from an ASN1 encoded blob
+ * Load a public key from an ASN.1 encoded blob
*/
-static gmp_rsa_public_key_t *load(chunk_t blob)
+static gmp_rsa_public_key_t *load_asn1_der(chunk_t blob)
{
asn1_parser_t *parser;
chunk_t object;
@@ -507,7 +640,7 @@ static gmp_rsa_public_key_t *load(chunk_t blob)
return NULL;
}
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (!gmp_rsa_public_key_build_id(this->n, this->e,
&this->keyid, &this->keyid_info))
@@ -518,6 +651,133 @@ static gmp_rsa_public_key_t *load(chunk_t blob)
return &this->public;
}
+/**
+ * Load a public key from an OpenPGP blob
+ */
+static gmp_rsa_public_key_t* load_pgp(chunk_t blob)
+{
+ int objectID;
+ chunk_t packet = blob;
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+
+ for (objectID = PUB_KEY_MODULUS; objectID <= PUB_KEY_EXPONENT; objectID++)
+ {
+ chunk_t object;
+
+ DBG2("L3 - %s:", pubkeyObjects[objectID].name);
+ object.len = pgp_length(&packet, 2);
+
+ if (object.len == PGP_INVALID_LENGTH)
+ {
+ DBG1("OpenPGP length is invalid");
+ goto end;
+ }
+ object.len = (object.len + 7) / BITS_PER_BYTE;
+ if (object.len > packet.len)
+ {
+ DBG1("OpenPGP field is too short");
+ goto end;
+ }
+ object.ptr = packet.ptr;
+ packet.ptr += object.len;
+ packet.len -= object.len;
+ DBG4("%B", &object);
+
+ switch (objectID)
+ {
+ case PUB_KEY_MODULUS:
+ mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ case PUB_KEY_EXPONENT:
+ mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
+ break;
+ }
+ }
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+ free(blob.ptr);
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+
+end:
+ free(blob.ptr);
+ destroy(this);
+ return NULL;
+}
+
+/**
+ * Load a public key from an RFC 3110 encoded blob
+ */
+static gmp_rsa_public_key_t *load_rfc_3110(chunk_t blob)
+{
+ chunk_t exponent, modulus;
+ u_char *pos = blob.ptr;
+ size_t len = blob.len;
+ private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+ mpz_init(this->n);
+ mpz_init(this->e);
+
+ if (blob.len < 3)
+ {
+ DBG1("RFC 3110 public key blob too short for exponent length");
+ goto end;
+ }
+ if (pos[0] != 0x00)
+ {
+ exponent = chunk_create(pos + 1, pos[0]);
+ pos++;
+ len--;
+ }
+ else
+ {
+ exponent = chunk_create(pos + 3, 256*pos[1] + pos[2]);
+ pos += 3;
+ len -= 3;
+ }
+ if (exponent.len > len)
+ {
+ DBG1("RFC 3110 public key blob too short for exponent");
+ goto end;
+ }
+ pos += exponent.len;
+ len -= exponent.len;
+
+ if (len == 0)
+ {
+ DBG1("RFC 3110 public key blob has zero length modulus");
+ goto end;
+ }
+ modulus = chunk_create(pos, len);
+
+ mpz_import(this->n, modulus.len, 1, 1, 1, 0, modulus.ptr);
+ mpz_import(this->e, exponent.len, 1, 1, 1, 0, exponent.ptr);
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+ free(blob.ptr);
+
+ if (!gmp_rsa_public_key_build_id(this->n, this->e,
+ &this->keyid, &this->keyid_info))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+
+end:
+ free(blob.ptr);
+ destroy(this);
+ return NULL;
+}
+
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for key loading
@@ -556,7 +816,23 @@ static void add(private_builder_t *this, builder_part_t part, ...)
{
va_start(args, part);
chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
+ this->key = load_asn1_der(chunk_clone(chunk));
+ va_end(args);
+ return;
+ }
+ case BUILD_BLOB_PGP:
+ {
+ va_start(args, part);
+ chunk = va_arg(args, chunk_t);
+ this->key = load_pgp(chunk_clone(chunk));
+ va_end(args);
+ return;
+ }
+ case BUILD_BLOB_RFC_3110:
+ {
+ va_start(args, part);
+ chunk = va_arg(args, chunk_t);
+ this->key = load_rfc_3110(chunk_clone(chunk));
va_end(args);
return;
}
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
index 46c8c3fd8..ed7b9429f 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gmp_rsa_public_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index 067763049..fc36bd9fa 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
index b2f99bdc3..6dfa02233 100644
--- a/src/libstrongswan/plugins/hmac/hmac.c
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General hmac License
* for more details.
- *
- * $Id: hmac.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c
index 7a09b7a4e..aa1e994b0 100644
--- a/src/libstrongswan/plugins/hmac/hmac_plugin.c
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hmac_plugin.c 4997 2009-03-24 10:24:58Z martin $
*/
#include "hmac_plugin.h"
@@ -70,6 +68,8 @@ plugin_t *plugin_create()
(signer_constructor_t)hmac_signer_create);
lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128,
(signer_constructor_t)hmac_signer_create);
+ lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_160,
+ (signer_constructor_t)hmac_signer_create);
lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128,
(signer_constructor_t)hmac_signer_create);
lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96,
diff --git a/src/libstrongswan/plugins/hmac/hmac_prf.c b/src/libstrongswan/plugins/hmac/hmac_prf.c
index 8d843bc5a..454d40be3 100644
--- a/src/libstrongswan/plugins/hmac/hmac_prf.c
+++ b/src/libstrongswan/plugins/hmac/hmac_prf.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hmac_prf.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "hmac_prf.h"
diff --git a/src/libstrongswan/plugins/hmac/hmac_signer.c b/src/libstrongswan/plugins/hmac/hmac_signer.c
index 89cae1716..b44bc2109 100644
--- a/src/libstrongswan/plugins/hmac/hmac_signer.c
+++ b/src/libstrongswan/plugins/hmac/hmac_signer.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hmac_signer.c 4997 2009-03-24 10:24:58Z martin $
*/
#include <string.h>
@@ -155,6 +153,10 @@ hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo)
hash = HASH_SHA1;
trunc = 16;
break;
+ case AUTH_HMAC_SHA1_160:
+ hash = HASH_SHA1;
+ trunc = 20;
+ break;
case AUTH_HMAC_MD5_96:
hash = HASH_MD5;
trunc = 12;
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index e0109c6e8..6eefc8546 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -222,8 +231,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -318,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.c b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
index 8e55b800e..b2a40219f 100644
--- a/src/libstrongswan/plugins/ldap/ldap_fetcher.c
+++ b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ldap_fetcher.c 3693 2008-03-28 22:44:45Z andreas $
*/
#ifndef LDAP_DEPRECATED
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c
index 0925cb395..994f3db46 100644
--- a/src/libstrongswan/plugins/ldap/ldap_plugin.c
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ldap_plugin.c 3529 2008-03-05 15:26:24Z martin $
*/
#include "ldap_plugin.h"
diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index 4dbe8a6c4..efdb64e90 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +326,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/md4/md4_hasher.c b/src/libstrongswan/plugins/md4/md4_hasher.c
index 9053bc68d..3801110dc 100644
--- a/src/libstrongswan/plugins/md4/md4_hasher.c
+++ b/src/libstrongswan/plugins/md4/md4_hasher.c
@@ -17,8 +17,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: md4_hasher.c 4885 2009-02-19 10:16:45Z andreas $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/md4/md4_plugin.c b/src/libstrongswan/plugins/md4/md4_plugin.c
index df77314f7..43ae6261d 100644
--- a/src/libstrongswan/plugins/md4/md4_plugin.c
+++ b/src/libstrongswan/plugins/md4/md4_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: md4_plugin.c 4885 2009-02-19 10:16:45Z andreas $
*/
#include "md4_plugin.h"
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index a73e78b05..15c98aba4 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +326,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/md5/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c
index 2354139bb..0ec5c073a 100644
--- a/src/libstrongswan/plugins/md5/md5_hasher.c
+++ b/src/libstrongswan/plugins/md5/md5_hasher.c
@@ -17,8 +17,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: md5_hasher.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c
index c1c9a0805..b1a3b495c 100644
--- a/src/libstrongswan/plugins/md5/md5_plugin.c
+++ b/src/libstrongswan/plugins/md5/md5_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: md5_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "md5_plugin.h"
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index 9a16662b9..26b514ad6 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -320,7 +329,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
index 01f604fef..d0d5a3d15 100644
--- a/src/libstrongswan/plugins/mysql/mysql_database.c
+++ b/src/libstrongswan/plugins/mysql/mysql_database.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mysql_database.c 4193 2008-07-21 11:13:06Z martin $
*/
#define _GNU_SOURCE
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c
index 29348ac14..92914ae6d 100644
--- a/src/libstrongswan/plugins/mysql/mysql_plugin.c
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mysql_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "mysql_plugin.h"
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index 0af89d377..0ebb5acf0 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -92,6 +92,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -114,6 +115,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -125,6 +129,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -138,6 +143,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -198,6 +205,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -209,6 +217,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -237,8 +246,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -341,7 +350,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index 5eddeb5f9..7f48f1009 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_crypter.c 4879 2009-02-18 19:41:33Z tobias $
*/
#include "openssl_crypter.h"
@@ -133,10 +131,12 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data,
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
- EVP_CipherInit_ex(&ctx, this->cipher, NULL, this->key.ptr, iv.ptr, enc);
- EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */
+ EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc);
+ EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */
+ EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len);
+ EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc);
EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len);
- EVP_CipherFinal_ex(&ctx, out, &len); /* since padding is disabled this does nothing */
+ EVP_CipherFinal_ex(&ctx, out + len, &len); /* since padding is disabled this does nothing */
EVP_CIPHER_CTX_cleanup(&ctx);
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.h b/src/libstrongswan/plugins/openssl/openssl_crypter.h
index 4510fb7ee..e5a899418 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.h
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_crypter.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index 7c83b3dea..fe042efdc 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_diffie_hellman.c 4639 2008-11-12 15:09:24Z martin $
*/
#include <openssl/dh.h>
@@ -171,7 +169,7 @@ static status_t set_modulus(private_openssl_diffie_hellman_t *this)
bool ansi_x9_42;
ansi_x9_42 = lib->settings->get_bool(lib->settings,
- "charon.dh_exponent_ansi_x9_42", TRUE);
+ "libstrongswan.dh_exponent_ansi_x9_42", TRUE);
for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
{
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
index c67ce8970..bdc153812 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_diffie_hellman.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index 9a89ad045..c93acb75c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_diffie_hellman.c 4566 2008-11-04 13:12:11Z martin $
*/
#include <openssl/ec.h>
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
index 6b135b36b..9d17aed57 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_diffie_hellman.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index aeab15f26..d6b442ae9 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_private_key.c 4317 2008-09-02 11:00:13Z martin $
*/
#include "openssl_ec_private_key.h"
@@ -130,36 +128,18 @@ static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk)
* Build the signature
*/
static bool build_signature(private_openssl_ec_private_key_t *this,
- int hash_type, chunk_t data, chunk_t *signature)
+ chunk_t hash, chunk_t *signature)
{
- chunk_t hash = chunk_empty;
- ECDSA_SIG *sig;
- bool ret = FALSE;
-
- if (!openssl_hash_chunk(hash_type, data, &hash))
- {
- return FALSE;
- }
-
- sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
+ ECDSA_SIG *sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
+ bool success;
+
if (!sig)
{
- goto error;
- }
-
- if (!sig2chunk(EC_KEY_get0_group(this->ec), sig, signature))
- {
- goto error;
- }
-
- ret = TRUE;
-error:
- chunk_free(&hash);
- if (sig)
- {
- ECDSA_SIG_free(sig);
+ return FALSE;
}
- return ret;
+ success = sig2chunk(EC_KEY_get0_group(this->ec), sig, signature);
+ ECDSA_SIG_free(sig);
+ return success;
}
/**
@@ -176,36 +156,51 @@ static key_type_t get_type(private_openssl_ec_private_key_t *this)
static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
{
- EC_GROUP *req_group;
- const EC_GROUP *my_group;
- int hash, curve;
-
- if (!lookup_scheme(scheme, &hash, &curve))
- {
- DBG1("signature scheme %N not supported in EC",
- signature_scheme_names, scheme);
- return FALSE;
- }
-
- req_group = EC_GROUP_new_by_curve_name(curve);
- if (!req_group)
+ bool success;
+
+ if (scheme == SIGN_ECDSA_WITH_NULL)
{
- DBG1("signature scheme %N not supported in EC (required curve not supported)",
- signature_scheme_names, scheme);
- return FALSE;
+ success = build_signature(this, data, signature);
}
-
- my_group = EC_KEY_get0_group(this->ec);
- if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
+ else
{
- DBG1("signature scheme %N not supported by private key",
- signature_scheme_names, scheme);
- return FALSE;
- }
+ EC_GROUP *req_group;
+ const EC_GROUP *my_group;
+ chunk_t hash = chunk_empty;
+ int hash_type, curve;
+
+ if (!lookup_scheme(scheme, &hash_type, &curve))
+ {
+ DBG1("signature scheme %N not supported in EC",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
- EC_GROUP_free(req_group);
+ req_group = EC_GROUP_new_by_curve_name(curve);
+ if (!req_group)
+ {
+ DBG1("signature scheme %N not supported in EC (required curve not supported)",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
- return build_signature(this, hash, data, signature);
+ my_group = EC_KEY_get0_group(this->ec);
+ if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
+ {
+ DBG1("signature scheme %N not supported by private key",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+ EC_GROUP_free(req_group);
+
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
+ success = build_signature(this, hash, signature);
+ chunk_free(&hash);
+ }
+ return success;
}
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
index 29588ce18..6a6f7c867 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_private_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
index 923df3938..635a106dd 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_public_key.c 4317 2008-09-02 11:00:13Z martin $
*/
#include "openssl_ec_public_key.h"
@@ -75,9 +73,16 @@ static bool verify_signature(private_openssl_ec_public_key_t *this,
ECDSA_SIG *sig;
bool valid = FALSE;
- if (!openssl_hash_chunk(hash_type, data, &hash))
+ if (hash_type == NID_undef)
{
- return FALSE;
+ hash = data;
+ }
+ else
+ {
+ if (!openssl_hash_chunk(hash_type, data, &hash))
+ {
+ return FALSE;
+ }
}
sig = ECDSA_SIG_new();
@@ -90,7 +95,6 @@ static bool verify_signature(private_openssl_ec_public_key_t *this,
{
goto error;
}
-
valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
error:
@@ -98,7 +102,10 @@ error:
{
ECDSA_SIG_free(sig);
}
- chunk_free(&hash);
+ if (hash_type != NID_undef)
+ {
+ chunk_free(&hash);
+ }
return valid;
}
@@ -160,6 +167,8 @@ static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t sch
{
switch (scheme)
{
+ case SIGN_ECDSA_WITH_NULL:
+ return verify_signature(this, NID_undef, data, signature);
case SIGN_ECDSA_WITH_SHA1:
return verify_default_signature(this, data, signature);
case SIGN_ECDSA_256:
@@ -178,7 +187,7 @@ static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t sch
/**
* Implementation of public_key_t.get_keysize.
*/
-static bool encrypt(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
+static bool encrypt_(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
{
DBG1("EC public key encryption not implemented");
return FALSE;
@@ -279,7 +288,7 @@ static private_openssl_ec_public_key_t *openssl_ec_public_key_create_empty()
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
- this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
@@ -331,24 +340,6 @@ bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
}
/**
- * Create a public key from BIGNUM values, used in openssl_ec_private_key.c
- */
-openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec)
-{
- private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
-
- this->ec = EC_KEY_new();
- EC_KEY_set_public_key(this->ec, EC_KEY_get0_public_key(ec));
-
- if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/**
* Load a public key from an ASN1 encoded blob
*/
static openssl_ec_public_key_t *load(chunk_t blob)
@@ -374,6 +365,14 @@ static openssl_ec_public_key_t *load(chunk_t blob)
return &this->public;
}
+/**
+ * Create a public key from BIGNUM values, used in openssl_ec_private_key.c
+ */
+openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec)
+{
+ return (openssl_ec_public_key_t*)load(get_encoding_full(ec));
+}
+
typedef struct private_builder_t private_builder_t;
/**
* Builder implementation for key loading
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
index 83552d590..bdbb2fe6e 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_ec_public_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
index d344dbd51..ed3e57957 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.c
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_hasher.c 4879 2009-02-18 19:41:33Z tobias $
*/
#include "openssl_hasher.h"
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
index 52699f7ff..aec5bc7dd 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.h
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_hasher.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 725daff01..a90dff7f1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_plugin.c 4879 2009-02-18 19:41:33Z tobias $
*/
#include <openssl/conf.h>
@@ -121,7 +119,7 @@ static void destroy_function(struct CRYPTO_dynlock_value *lock,
*/
static unsigned long id_function(void)
{
- return pthread_self();
+ return (unsigned long)pthread_self();
}
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.h b/src/libstrongswan/plugins/openssl/openssl_plugin.h
index a6d2a060e..9f422c9d0 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.h
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_plugin.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 9730e0ab2..c5d4142da 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_rsa_private_key.c 4745 2008-12-03 10:12:20Z tobias $
*/
#include "openssl_rsa_private_key.h"
@@ -80,65 +78,75 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGN
* Build an EMPSA PKCS1 signature described in PKCS#1
*/
static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
- int type, chunk_t data, chunk_t *out)
+ int type, chunk_t data, chunk_t *sig)
{
bool success = FALSE;
- u_char *sig = NULL;
- u_int len;
- const EVP_MD *hasher = EVP_get_digestbynid(type);
- if (!hasher)
- {
- return FALSE;
- }
-
- EVP_MD_CTX *ctx = EVP_MD_CTX_create();
- EVP_PKEY *key = EVP_PKEY_new();
- if (!ctx || !key)
- {
- goto error;
- }
-
- if (!EVP_PKEY_set1_RSA(key, this->rsa))
- {
- goto error;
- }
-
- if (!EVP_SignInit_ex(ctx, hasher, NULL))
- {
- goto error;
- }
-
- if (!EVP_SignUpdate(ctx, data.ptr, data.len))
- {
- goto error;
- }
-
- sig = malloc(EVP_PKEY_size(key));
- if (EVP_SignFinal(ctx, sig, &len, key))
+
+ *sig = chunk_alloc(RSA_size(this->rsa));
+
+ if (type == NID_undef)
{
- out->ptr = sig;
- out->len = len;
- success = TRUE;
+ if (RSA_private_encrypt(data.len, data.ptr, sig->ptr, this->rsa,
+ RSA_PKCS1_PADDING) == sig->len)
+ {
+ success = TRUE;
+ }
}
else
{
- free(sig);
- }
+ EVP_MD_CTX *ctx;
+ EVP_PKEY *key;
+ const EVP_MD *hasher;
+ u_int len;
+
+ hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_create();
+ key = EVP_PKEY_new();
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+ if (!EVP_SignInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+ if (!EVP_SignUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+ if (EVP_SignFinal(ctx, sig->ptr, &len, key))
+ {
+ success = TRUE;
+ }
error:
- if (key)
- {
- EVP_PKEY_free(key);
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
}
- if (ctx)
+ if (!success)
{
- EVP_MD_CTX_destroy(ctx);
+ free(sig->ptr);
}
return success;
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.get_type.
*/
static key_type_t get_type(private_openssl_rsa_private_key_t *this)
{
@@ -146,15 +154,15 @@ static key_type_t get_type(private_openssl_rsa_private_key_t *this)
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.sign.
*/
static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
{
switch (scheme)
{
- case SIGN_DEFAULT:
- /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return build_emsa_pkcs1_signature(this, NID_undef, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -173,7 +181,7 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.decrypt.
*/
static bool decrypt(private_openssl_rsa_private_key_t *this,
chunk_t crypto, chunk_t *plain)
@@ -183,7 +191,7 @@ static bool decrypt(private_openssl_rsa_private_key_t *this,
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.get_keysize.
*/
static size_t get_keysize(private_openssl_rsa_private_key_t *this)
{
@@ -191,7 +199,7 @@ static size_t get_keysize(private_openssl_rsa_private_key_t *this)
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.get_id.
*/
static identification_t* get_id(private_openssl_rsa_private_key_t *this,
id_type_t type)
@@ -208,7 +216,7 @@ static identification_t* get_id(private_openssl_rsa_private_key_t *this,
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.get_public_key.
*/
static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
{
@@ -216,7 +224,35 @@ static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.equals.
+ */
+static bool equals(private_openssl_rsa_private_key_t *this, private_key_t *other)
+{
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of openssl_rsa_private_key.belongs_to.
*/
static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
{
@@ -255,7 +291,7 @@ static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
}
/**
- * Implementation of openssl_rsa_private_key.destroy.
+ * Implementation of openssl_rsa_private_key.get_ref.
*/
static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
{
@@ -288,16 +324,17 @@ static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(v
{
private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
- this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
- this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
- this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
- this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
- this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
- this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
- this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
- this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
- this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
+ this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type;
+ this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign;
+ this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt;
+ this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize;
+ this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id;
+ this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
+ this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
+ this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to;
+ this->public.interface.get_encoding = (chunk_t(*) (private_key_t*))get_encoding;
+ this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref;
+ this->public.interface.destroy = (void (*) (private_key_t*))destroy;
this->engine = FALSE;
this->keyid = NULL;
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
index 05d83416c..53ec44b28 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_rsa_private_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index 794fa8123..89912f24c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_rsa_public_key.c 4567 2008-11-04 14:05:42Z martin $
*/
#include "openssl_rsa_public_key.h"
@@ -62,49 +60,65 @@ static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
int type, chunk_t data, chunk_t signature)
{
bool valid = FALSE;
- const EVP_MD *hasher = EVP_get_digestbynid(type);
- if (!hasher)
- {
- return FALSE;
- }
-
- EVP_MD_CTX *ctx = EVP_MD_CTX_create();
- EVP_PKEY *key = EVP_PKEY_new();
- if (!ctx || !key)
- {
- goto error;
- }
-
- if (!EVP_PKEY_set1_RSA(key, this->rsa))
- {
- goto error;
- }
-
- if (!EVP_VerifyInit_ex(ctx, hasher, NULL))
+ int rsa_size = RSA_size(this->rsa);
+
+ /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
+ if (signature.len > rsa_size)
{
- goto error;
+ signature = chunk_skip(signature, signature.len - rsa_size);
}
-
- if (!EVP_VerifyUpdate(ctx, data.ptr, data.len))
+
+ if (type == NID_undef)
{
- goto error;
+ chunk_t hash = chunk_alloc(rsa_size);
+
+ hash.len = RSA_public_decrypt(signature.len, signature.ptr, hash.ptr,
+ this->rsa, RSA_PKCS1_PADDING);
+ valid = chunk_equals(data, hash);
+ free(hash.ptr);
}
-
- /* VerifyFinal expects a signature of exactly RSA size (no leading 0x00) */
- if (signature.len > RSA_size(this->rsa))
+ else
{
- signature = chunk_skip(signature, signature.len - RSA_size(this->rsa));
- }
- valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
+ EVP_MD_CTX *ctx;
+ EVP_PKEY *key;
+ const EVP_MD *hasher;
+
+ hasher = EVP_get_digestbynid(type);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ ctx = EVP_MD_CTX_create();
+ key = EVP_PKEY_new();
+
+ if (!ctx || !key)
+ {
+ goto error;
+ }
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+ if (!EVP_VerifyInit_ex(ctx, hasher, NULL))
+ {
+ goto error;
+ }
+ if (!EVP_VerifyUpdate(ctx, data.ptr, data.len))
+ {
+ goto error;
+ }
+ valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
error:
- if (key)
- {
- EVP_PKEY_free(key);
- }
- if (ctx)
- {
- EVP_MD_CTX_destroy(ctx);
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (ctx)
+ {
+ EVP_MD_CTX_destroy(ctx);
+ }
}
return valid;
}
@@ -125,8 +139,8 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
{
switch (scheme)
{
- case SIGN_DEFAULT:
- /* default is EMSA-PKCS1 using SHA1 */
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ return verify_emsa_pkcs1_signature(this, NID_undef, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA256:
@@ -147,13 +161,41 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
/**
* Implementation of public_key_t.get_keysize.
*/
-static bool encrypt(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+static bool encrypt_(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
{
DBG1("RSA public key encryption not implemented");
return FALSE;
}
/**
+ * Implementation of public_key_t.equals.
+ */
+static bool equals(private_openssl_rsa_public_key_t *this, public_key_t *other)
+{
+ identification_t *keyid;
+
+ if (&this->public.interface == other)
+ {
+ return TRUE;
+ }
+ if (other->get_type(other) != KEY_RSA)
+ {
+ return FALSE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid))
+ {
+ return TRUE;
+ }
+ keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
+ if (keyid && keyid->equals(keyid, this->keyid_info))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* Implementation of public_key_t.get_keysize.
*/
static size_t get_keysize(private_openssl_rsa_public_key_t *this)
@@ -263,7 +305,8 @@ static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty()
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
- this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt;
+ this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
+ this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
index c97ba1b92..ff99ddbc5 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_rsa_public_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
index 3c4f6595b..bb0c296e1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.c
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_util.c 4051 2008-06-10 09:08:27Z tobias $
*/
#include "openssl_util.h"
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h
index e780e2a25..6ba1ff07b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.h
+++ b/src/libstrongswan/plugins/openssl/openssl_util.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: openssl_util.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 290b4836d..7fe0cc198 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -227,8 +236,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -325,7 +334,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
index f6f9b3501..afdd85b79 100644
--- a/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
+++ b/src/libstrongswan/plugins/padlock/padlock_aes_crypter.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "padlock_aes_crypter.h"
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.c b/src/libstrongswan/plugins/padlock/padlock_plugin.c
index d0b55bcd9..dddb73551 100644
--- a/src/libstrongswan/plugins/padlock/padlock_plugin.c
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "padlock_plugin.h"
@@ -159,7 +157,7 @@ plugin_t *plugin_create()
if (this->features & PADLOCK_RNG_ENABLED)
{
- lib->crypto->add_rng(lib->crypto, RNG_REAL,
+ lib->crypto->add_rng(lib->crypto, RNG_TRUE,
(rng_constructor_t)padlock_rng_create);
lib->crypto->add_rng(lib->crypto, RNG_STRONG,
(rng_constructor_t)padlock_rng_create);
diff --git a/src/libstrongswan/plugins/padlock/padlock_rng.c b/src/libstrongswan/plugins/padlock/padlock_rng.c
index 50d9f0c43..8a04dccfc 100644
--- a/src/libstrongswan/plugins/padlock/padlock_rng.c
+++ b/src/libstrongswan/plugins/padlock/padlock_rng.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "padlock_rng.h"
@@ -126,7 +124,7 @@ padlock_rng_t *padlock_rng_create(rng_quality_t quality)
case RNG_STRONG:
this->quality = PADLOCK_QF1;
break;
- case RNG_REAL:
+ case RNG_TRUE:
this->quality = PADLOCK_QF3;
break;
}
diff --git a/src/libstrongswan/plugins/padlock/padlock_rng.h b/src/libstrongswan/plugins/padlock/padlock_rng.h
index 505f4649c..237d8fbe2 100644
--- a/src/libstrongswan/plugins/padlock/padlock_rng.h
+++ b/src/libstrongswan/plugins/padlock/padlock_rng.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
index 4ac5ddf4d..b5a6abc64 100644
--- a/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
+++ b/src/libstrongswan/plugins/padlock/padlock_sha1_hasher.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 6480a2760..ad5a9e240 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: plugin_loader.c 4144 2008-07-02 08:19:43Z martin $
*/
#define _GNU_SOURCE
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index eb5e19f08..4514424f2 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -323,7 +332,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
index 762557094..863a8a1d4 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "pubkey_cert.h"
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.h b/src/libstrongswan/plugins/pubkey/pubkey_cert.h
index b04824fee..394fc8b98 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_cert.h
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
index dd7ac6fd1..7672e8dc1 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "pubkey_plugin.h"
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.c b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
index 4b5f4aac2..6d3ae66ab 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pubkey_public_key.c 4379 2008-10-08 01:19:26Z andreas $
*/
#include "pubkey_public_key.h"
@@ -147,7 +145,7 @@ static void add(private_builder_t *this, builder_part_t part, ...)
va_start(args, part);
pem = va_arg(args, char *);
blob = chunk_clone(chunk_create(pem, strlen(pem)));
- if (pem_to_bin(&blob, &chunk_empty, &pgp))
+ if (pem_to_bin(&blob, chunk_empty, &pgp) == SUCCESS)
{
this->key = pubkey_public_key_load(chunk_clone(blob));
}
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_public_key.h b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
index 0545feeee..d3198fab2 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
+++ b/src/libstrongswan/plugins/pubkey/pubkey_public_key.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: pubkey_public_key.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index f5e3c4cc9..0bed27468 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -320,7 +329,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c
index 3eff81ee0..5f04f1d79 100644
--- a/src/libstrongswan/plugins/random/random_plugin.c
+++ b/src/libstrongswan/plugins/random/random_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "random_plugin.h"
@@ -54,7 +52,7 @@ plugin_t *plugin_create()
lib->crypto->add_rng(lib->crypto, RNG_STRONG,
(rng_constructor_t)random_rng_create);
- lib->crypto->add_rng(lib->crypto, RNG_REAL,
+ lib->crypto->add_rng(lib->crypto, RNG_TRUE,
(rng_constructor_t)random_rng_create);
return &this->public.plugin;
diff --git a/src/libstrongswan/plugins/random/random_rng.c b/src/libstrongswan/plugins/random/random_rng.c
index 45a1b5138..22d21574e 100644
--- a/src/libstrongswan/plugins/random/random_rng.c
+++ b/src/libstrongswan/plugins/random/random_rng.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <string.h>
@@ -114,7 +112,7 @@ random_rng_t *random_rng_create(rng_quality_t quality)
this->public.rng.allocate_bytes = (void (*) (rng_t *, size_t, chunk_t*)) allocate_bytes;
this->public.rng.destroy = (void (*) (rng_t *))destroy;
- if (quality == RNG_REAL)
+ if (quality == RNG_TRUE)
{
this->file = DEV_RANDOM;
}
diff --git a/src/libstrongswan/plugins/random/random_rng.h b/src/libstrongswan/plugins/random/random_rng.h
index 3426d694e..bcb9cb204 100644
--- a/src/libstrongswan/plugins/random/random_rng.h
+++ b/src/libstrongswan/plugins/random/random_rng.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index ece7381b2..c8b8905bb 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -321,7 +330,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c
index ea0882cb5..ba3dd9592 100644
--- a/src/libstrongswan/plugins/sha1/sha1_hasher.c
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c
@@ -15,8 +15,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sha1_hasher.c 4308 2008-08-28 10:57:24Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
index 58f0faf56..b9eb62ac5 100644
--- a/src/libstrongswan/plugins/sha1/sha1_plugin.c
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sha1_plugin.c 4308 2008-08-28 10:57:24Z martin $
*/
#include "sha1_plugin.h"
diff --git a/src/libstrongswan/plugins/sha1/sha1_prf.c b/src/libstrongswan/plugins/sha1/sha1_prf.c
index 668801caf..4a5f7c293 100644
--- a/src/libstrongswan/plugins/sha1/sha1_prf.c
+++ b/src/libstrongswan/plugins/sha1/sha1_prf.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "sha1_prf.h"
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index 6b28b68a1..f37c93502 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -87,6 +87,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -109,6 +110,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -120,6 +124,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -133,6 +138,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -193,6 +200,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -204,6 +212,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -221,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +326,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c
index ca9c2f926..0e8811cca 100644
--- a/src/libstrongswan/plugins/sha2/sha2_hasher.c
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sha2_hasher.c 3488 2008-02-21 15:10:02Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c
index ebb2947ef..21bc592dc 100644
--- a/src/libstrongswan/plugins/sha2/sha2_plugin.c
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sha2_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "sha2_plugin.h"
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index e6732a195..547548bd7 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -226,8 +235,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c
index c8d9e5beb..ce873b714 100644
--- a/src/libstrongswan/plugins/sqlite/sqlite_database.c
+++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sqlite_database.c 4268 2008-08-21 11:58:58Z andreas $
*/
#include "sqlite_database.h"
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
index 441e59a5e..bedf91e0f 100644
--- a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: sqlite_plugin.c 3488 2008-02-21 15:10:02Z martin $
*/
#include "sqlite_plugin.h"
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.am b/src/libstrongswan/plugins/test_vectors/Makefile.am
new file mode 100644
index 000000000..27d17c084
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.am
@@ -0,0 +1,33 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-test-vectors.la
+
+libstrongswan_test_vectors_la_SOURCES = \
+ test_vectors_plugin.h test_vectors_plugin.c test_vectors.h \
+ test_vectors/3des_cbc.c \
+ test_vectors/aes_cbc.c \
+ test_vectors/aes_xcbc.c \
+ test_vectors/blowfish.c \
+ test_vectors/camellia_cbc.c \
+ test_vectors/cast.c \
+ test_vectors/des.c \
+ test_vectors/idea.c \
+ test_vectors/null.c \
+ test_vectors/rc5.c \
+ test_vectors/serpent_cbc.c \
+ test_vectors/twofish_cbc.c \
+ test_vectors/md2.c \
+ test_vectors/md4.c \
+ test_vectors/md5.c \
+ test_vectors/md5_hmac.c \
+ test_vectors/sha1.c \
+ test_vectors/sha1_hmac.c \
+ test_vectors/sha2.c \
+ test_vectors/sha2_hmac.c \
+ test_vectors/fips_prf.c \
+ test_vectors/rng.c
+libstrongswan_test_vectors_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
new file mode 100644
index 000000000..bb877620c
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -0,0 +1,710 @@
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libstrongswan/plugins/test_vectors
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(plugindir)"
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+libstrongswan_test_vectors_la_LIBADD =
+am_libstrongswan_test_vectors_la_OBJECTS = test_vectors_plugin.lo \
+ 3des_cbc.lo aes_cbc.lo aes_xcbc.lo blowfish.lo camellia_cbc.lo \
+ cast.lo des.lo idea.lo null.lo rc5.lo serpent_cbc.lo \
+ twofish_cbc.lo md2.lo md4.lo md5.lo md5_hmac.lo sha1.lo \
+ sha1_hmac.lo sha2.lo sha2_hmac.lo fips_prf.lo rng.lo
+libstrongswan_test_vectors_la_OBJECTS = \
+ $(am_libstrongswan_test_vectors_la_OBJECTS)
+libstrongswan_test_vectors_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_test_vectors_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_test_vectors_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_test_vectors_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
+IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipsecuser = @ipsecuser@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libstrongswan_plugins = @libstrongswan_plugins@
+linuxdir = @linuxdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+piddir = @piddir@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+resolv_conf = @resolv_conf@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+simreader = @simreader@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS = -rdynamic
+plugin_LTLIBRARIES = libstrongswan-test-vectors.la
+libstrongswan_test_vectors_la_SOURCES = \
+ test_vectors_plugin.h test_vectors_plugin.c test_vectors.h \
+ test_vectors/3des_cbc.c \
+ test_vectors/aes_cbc.c \
+ test_vectors/aes_xcbc.c \
+ test_vectors/blowfish.c \
+ test_vectors/camellia_cbc.c \
+ test_vectors/cast.c \
+ test_vectors/des.c \
+ test_vectors/idea.c \
+ test_vectors/null.c \
+ test_vectors/rc5.c \
+ test_vectors/serpent_cbc.c \
+ test_vectors/twofish_cbc.c \
+ test_vectors/md2.c \
+ test_vectors/md4.c \
+ test_vectors/md5.c \
+ test_vectors/md5_hmac.c \
+ test_vectors/sha1.c \
+ test_vectors/sha1_hmac.c \
+ test_vectors/sha2.c \
+ test_vectors/sha2_hmac.c \
+ test_vectors/fips_prf.c \
+ test_vectors/rng.c
+
+libstrongswan_test_vectors_la_LDFLAGS = -module
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/test_vectors/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/test_vectors/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-test-vectors.la: $(libstrongswan_test_vectors_la_OBJECTS) $(libstrongswan_test_vectors_la_DEPENDENCIES)
+ $(libstrongswan_test_vectors_la_LINK) -rpath $(plugindir) $(libstrongswan_test_vectors_la_OBJECTS) $(libstrongswan_test_vectors_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/3des_cbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_xcbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia_cbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idea.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/null.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent_cbc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1_hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha2_hmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_vectors_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish_cbc.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+3des_cbc.lo: test_vectors/3des_cbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT 3des_cbc.lo -MD -MP -MF $(DEPDIR)/3des_cbc.Tpo -c -o 3des_cbc.lo `test -f 'test_vectors/3des_cbc.c' || echo '$(srcdir)/'`test_vectors/3des_cbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/3des_cbc.Tpo $(DEPDIR)/3des_cbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/3des_cbc.c' object='3des_cbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o 3des_cbc.lo `test -f 'test_vectors/3des_cbc.c' || echo '$(srcdir)/'`test_vectors/3des_cbc.c
+
+aes_cbc.lo: test_vectors/aes_cbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cbc.lo -MD -MP -MF $(DEPDIR)/aes_cbc.Tpo -c -o aes_cbc.lo `test -f 'test_vectors/aes_cbc.c' || echo '$(srcdir)/'`test_vectors/aes_cbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_cbc.Tpo $(DEPDIR)/aes_cbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/aes_cbc.c' object='aes_cbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cbc.lo `test -f 'test_vectors/aes_cbc.c' || echo '$(srcdir)/'`test_vectors/aes_cbc.c
+
+aes_xcbc.lo: test_vectors/aes_xcbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_xcbc.lo -MD -MP -MF $(DEPDIR)/aes_xcbc.Tpo -c -o aes_xcbc.lo `test -f 'test_vectors/aes_xcbc.c' || echo '$(srcdir)/'`test_vectors/aes_xcbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/aes_xcbc.Tpo $(DEPDIR)/aes_xcbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/aes_xcbc.c' object='aes_xcbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_xcbc.lo `test -f 'test_vectors/aes_xcbc.c' || echo '$(srcdir)/'`test_vectors/aes_xcbc.c
+
+blowfish.lo: test_vectors/blowfish.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT blowfish.lo -MD -MP -MF $(DEPDIR)/blowfish.Tpo -c -o blowfish.lo `test -f 'test_vectors/blowfish.c' || echo '$(srcdir)/'`test_vectors/blowfish.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/blowfish.Tpo $(DEPDIR)/blowfish.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/blowfish.c' object='blowfish.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o blowfish.lo `test -f 'test_vectors/blowfish.c' || echo '$(srcdir)/'`test_vectors/blowfish.c
+
+camellia_cbc.lo: test_vectors/camellia_cbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT camellia_cbc.lo -MD -MP -MF $(DEPDIR)/camellia_cbc.Tpo -c -o camellia_cbc.lo `test -f 'test_vectors/camellia_cbc.c' || echo '$(srcdir)/'`test_vectors/camellia_cbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/camellia_cbc.Tpo $(DEPDIR)/camellia_cbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/camellia_cbc.c' object='camellia_cbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o camellia_cbc.lo `test -f 'test_vectors/camellia_cbc.c' || echo '$(srcdir)/'`test_vectors/camellia_cbc.c
+
+cast.lo: test_vectors/cast.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cast.lo -MD -MP -MF $(DEPDIR)/cast.Tpo -c -o cast.lo `test -f 'test_vectors/cast.c' || echo '$(srcdir)/'`test_vectors/cast.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/cast.Tpo $(DEPDIR)/cast.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/cast.c' object='cast.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cast.lo `test -f 'test_vectors/cast.c' || echo '$(srcdir)/'`test_vectors/cast.c
+
+des.lo: test_vectors/des.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT des.lo -MD -MP -MF $(DEPDIR)/des.Tpo -c -o des.lo `test -f 'test_vectors/des.c' || echo '$(srcdir)/'`test_vectors/des.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/des.Tpo $(DEPDIR)/des.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/des.c' object='des.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o des.lo `test -f 'test_vectors/des.c' || echo '$(srcdir)/'`test_vectors/des.c
+
+idea.lo: test_vectors/idea.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT idea.lo -MD -MP -MF $(DEPDIR)/idea.Tpo -c -o idea.lo `test -f 'test_vectors/idea.c' || echo '$(srcdir)/'`test_vectors/idea.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/idea.Tpo $(DEPDIR)/idea.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/idea.c' object='idea.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o idea.lo `test -f 'test_vectors/idea.c' || echo '$(srcdir)/'`test_vectors/idea.c
+
+null.lo: test_vectors/null.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT null.lo -MD -MP -MF $(DEPDIR)/null.Tpo -c -o null.lo `test -f 'test_vectors/null.c' || echo '$(srcdir)/'`test_vectors/null.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/null.Tpo $(DEPDIR)/null.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/null.c' object='null.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o null.lo `test -f 'test_vectors/null.c' || echo '$(srcdir)/'`test_vectors/null.c
+
+rc5.lo: test_vectors/rc5.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rc5.lo -MD -MP -MF $(DEPDIR)/rc5.Tpo -c -o rc5.lo `test -f 'test_vectors/rc5.c' || echo '$(srcdir)/'`test_vectors/rc5.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rc5.Tpo $(DEPDIR)/rc5.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/rc5.c' object='rc5.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rc5.lo `test -f 'test_vectors/rc5.c' || echo '$(srcdir)/'`test_vectors/rc5.c
+
+serpent_cbc.lo: test_vectors/serpent_cbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT serpent_cbc.lo -MD -MP -MF $(DEPDIR)/serpent_cbc.Tpo -c -o serpent_cbc.lo `test -f 'test_vectors/serpent_cbc.c' || echo '$(srcdir)/'`test_vectors/serpent_cbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/serpent_cbc.Tpo $(DEPDIR)/serpent_cbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/serpent_cbc.c' object='serpent_cbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o serpent_cbc.lo `test -f 'test_vectors/serpent_cbc.c' || echo '$(srcdir)/'`test_vectors/serpent_cbc.c
+
+twofish_cbc.lo: test_vectors/twofish_cbc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT twofish_cbc.lo -MD -MP -MF $(DEPDIR)/twofish_cbc.Tpo -c -o twofish_cbc.lo `test -f 'test_vectors/twofish_cbc.c' || echo '$(srcdir)/'`test_vectors/twofish_cbc.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/twofish_cbc.Tpo $(DEPDIR)/twofish_cbc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/twofish_cbc.c' object='twofish_cbc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o twofish_cbc.lo `test -f 'test_vectors/twofish_cbc.c' || echo '$(srcdir)/'`test_vectors/twofish_cbc.c
+
+md2.lo: test_vectors/md2.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md2.lo -MD -MP -MF $(DEPDIR)/md2.Tpo -c -o md2.lo `test -f 'test_vectors/md2.c' || echo '$(srcdir)/'`test_vectors/md2.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md2.Tpo $(DEPDIR)/md2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/md2.c' object='md2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md2.lo `test -f 'test_vectors/md2.c' || echo '$(srcdir)/'`test_vectors/md2.c
+
+md4.lo: test_vectors/md4.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md4.lo -MD -MP -MF $(DEPDIR)/md4.Tpo -c -o md4.lo `test -f 'test_vectors/md4.c' || echo '$(srcdir)/'`test_vectors/md4.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md4.Tpo $(DEPDIR)/md4.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/md4.c' object='md4.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md4.lo `test -f 'test_vectors/md4.c' || echo '$(srcdir)/'`test_vectors/md4.c
+
+md5.lo: test_vectors/md5.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5.lo -MD -MP -MF $(DEPDIR)/md5.Tpo -c -o md5.lo `test -f 'test_vectors/md5.c' || echo '$(srcdir)/'`test_vectors/md5.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5.Tpo $(DEPDIR)/md5.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/md5.c' object='md5.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5.lo `test -f 'test_vectors/md5.c' || echo '$(srcdir)/'`test_vectors/md5.c
+
+md5_hmac.lo: test_vectors/md5_hmac.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5_hmac.lo -MD -MP -MF $(DEPDIR)/md5_hmac.Tpo -c -o md5_hmac.lo `test -f 'test_vectors/md5_hmac.c' || echo '$(srcdir)/'`test_vectors/md5_hmac.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_hmac.Tpo $(DEPDIR)/md5_hmac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/md5_hmac.c' object='md5_hmac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5_hmac.lo `test -f 'test_vectors/md5_hmac.c' || echo '$(srcdir)/'`test_vectors/md5_hmac.c
+
+sha1.lo: test_vectors/sha1.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha1.lo -MD -MP -MF $(DEPDIR)/sha1.Tpo -c -o sha1.lo `test -f 'test_vectors/sha1.c' || echo '$(srcdir)/'`test_vectors/sha1.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha1.Tpo $(DEPDIR)/sha1.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/sha1.c' object='sha1.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha1.lo `test -f 'test_vectors/sha1.c' || echo '$(srcdir)/'`test_vectors/sha1.c
+
+sha1_hmac.lo: test_vectors/sha1_hmac.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha1_hmac.lo -MD -MP -MF $(DEPDIR)/sha1_hmac.Tpo -c -o sha1_hmac.lo `test -f 'test_vectors/sha1_hmac.c' || echo '$(srcdir)/'`test_vectors/sha1_hmac.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha1_hmac.Tpo $(DEPDIR)/sha1_hmac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/sha1_hmac.c' object='sha1_hmac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha1_hmac.lo `test -f 'test_vectors/sha1_hmac.c' || echo '$(srcdir)/'`test_vectors/sha1_hmac.c
+
+sha2.lo: test_vectors/sha2.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2.lo -MD -MP -MF $(DEPDIR)/sha2.Tpo -c -o sha2.lo `test -f 'test_vectors/sha2.c' || echo '$(srcdir)/'`test_vectors/sha2.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2.Tpo $(DEPDIR)/sha2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/sha2.c' object='sha2.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2.lo `test -f 'test_vectors/sha2.c' || echo '$(srcdir)/'`test_vectors/sha2.c
+
+sha2_hmac.lo: test_vectors/sha2_hmac.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sha2_hmac.lo -MD -MP -MF $(DEPDIR)/sha2_hmac.Tpo -c -o sha2_hmac.lo `test -f 'test_vectors/sha2_hmac.c' || echo '$(srcdir)/'`test_vectors/sha2_hmac.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sha2_hmac.Tpo $(DEPDIR)/sha2_hmac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/sha2_hmac.c' object='sha2_hmac.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sha2_hmac.lo `test -f 'test_vectors/sha2_hmac.c' || echo '$(srcdir)/'`test_vectors/sha2_hmac.c
+
+fips_prf.lo: test_vectors/fips_prf.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fips_prf.lo -MD -MP -MF $(DEPDIR)/fips_prf.Tpo -c -o fips_prf.lo `test -f 'test_vectors/fips_prf.c' || echo '$(srcdir)/'`test_vectors/fips_prf.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fips_prf.Tpo $(DEPDIR)/fips_prf.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/fips_prf.c' object='fips_prf.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fips_prf.lo `test -f 'test_vectors/fips_prf.c' || echo '$(srcdir)/'`test_vectors/fips_prf.c
+
+rng.lo: test_vectors/rng.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rng.lo -MD -MP -MF $(DEPDIR)/rng.Tpo -c -o rng.lo `test -f 'test_vectors/rng.c' || echo '$(srcdir)/'`test_vectors/rng.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/rng.Tpo $(DEPDIR)/rng.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/rng.c' object='rng.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rng.lo `test -f 'test_vectors/rng.c' || echo '$(srcdir)/'`test_vectors/rng.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h
new file mode 100644
index 000000000..df5a9c9a8
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+TEST_VECTOR_CRYPTER(aes_cbc1)
+TEST_VECTOR_CRYPTER(aes_cbc2)
+TEST_VECTOR_CRYPTER(aes_cbc3)
+TEST_VECTOR_CRYPTER(aes_cbc4)
+TEST_VECTOR_CRYPTER(aes_cbc5)
+TEST_VECTOR_CRYPTER(aes_cbc6)
+TEST_VECTOR_CRYPTER(blowfish1)
+TEST_VECTOR_CRYPTER(blowfish2)
+TEST_VECTOR_CRYPTER(camellia_cbc1)
+TEST_VECTOR_CRYPTER(camellia_cbc2)
+TEST_VECTOR_CRYPTER(camellia_cbc3)
+TEST_VECTOR_CRYPTER(camellia_cbc4)
+TEST_VECTOR_CRYPTER(camellia_cbc5)
+TEST_VECTOR_CRYPTER(camellia_cbc6)
+TEST_VECTOR_CRYPTER(cast1)
+TEST_VECTOR_CRYPTER(des_cbc1)
+TEST_VECTOR_CRYPTER(des_cbc2)
+TEST_VECTOR_CRYPTER(des_ecb1)
+TEST_VECTOR_CRYPTER(des_ecb2)
+TEST_VECTOR_CRYPTER(des3_cbc1)
+TEST_VECTOR_CRYPTER(des3_cbc2)
+TEST_VECTOR_CRYPTER(idea1)
+TEST_VECTOR_CRYPTER(idea2)
+TEST_VECTOR_CRYPTER(null1)
+TEST_VECTOR_CRYPTER(rc5_1)
+TEST_VECTOR_CRYPTER(rc5_2)
+TEST_VECTOR_CRYPTER(serpent_cbc1)
+TEST_VECTOR_CRYPTER(serpent_cbc2)
+TEST_VECTOR_CRYPTER(serpent_cbc3)
+TEST_VECTOR_CRYPTER(serpent_cbc4)
+TEST_VECTOR_CRYPTER(serpent_cbc5)
+TEST_VECTOR_CRYPTER(serpent_cbc6)
+TEST_VECTOR_CRYPTER(twofish_cbc1)
+TEST_VECTOR_CRYPTER(twofish_cbc2)
+TEST_VECTOR_CRYPTER(twofish_cbc3)
+
+TEST_VECTOR_SIGNER(aes_xcbc_s1)
+TEST_VECTOR_SIGNER(aes_xcbc_s2)
+TEST_VECTOR_SIGNER(aes_xcbc_s3)
+TEST_VECTOR_SIGNER(aes_xcbc_s4)
+TEST_VECTOR_SIGNER(aes_xcbc_s5)
+TEST_VECTOR_SIGNER(md5_hmac_s1)
+TEST_VECTOR_SIGNER(md5_hmac_s2)
+TEST_VECTOR_SIGNER(md5_hmac_s3)
+TEST_VECTOR_SIGNER(md5_hmac_s4)
+TEST_VECTOR_SIGNER(sha1_hmac_s1)
+TEST_VECTOR_SIGNER(sha1_hmac_s2)
+TEST_VECTOR_SIGNER(sha1_hmac_s3)
+TEST_VECTOR_SIGNER(sha1_hmac_s4)
+TEST_VECTOR_SIGNER(sha1_hmac_s5)
+TEST_VECTOR_SIGNER(sha1_hmac_s6)
+TEST_VECTOR_SIGNER(sha256_hmac_s1)
+TEST_VECTOR_SIGNER(sha256_hmac_s2)
+TEST_VECTOR_SIGNER(sha256_hmac_s3)
+TEST_VECTOR_SIGNER(sha384_hmac_s1)
+TEST_VECTOR_SIGNER(sha384_hmac_s2)
+TEST_VECTOR_SIGNER(sha384_hmac_s3)
+TEST_VECTOR_SIGNER(sha512_hmac_s1)
+TEST_VECTOR_SIGNER(sha512_hmac_s2)
+TEST_VECTOR_SIGNER(sha512_hmac_s3)
+
+TEST_VECTOR_HASHER(md2_1)
+TEST_VECTOR_HASHER(md2_2)
+TEST_VECTOR_HASHER(md2_3)
+TEST_VECTOR_HASHER(md2_4)
+TEST_VECTOR_HASHER(md2_5)
+TEST_VECTOR_HASHER(md2_6)
+TEST_VECTOR_HASHER(md2_7)
+TEST_VECTOR_HASHER(md4_1)
+TEST_VECTOR_HASHER(md4_2)
+TEST_VECTOR_HASHER(md4_3)
+TEST_VECTOR_HASHER(md4_4)
+TEST_VECTOR_HASHER(md4_5)
+TEST_VECTOR_HASHER(md4_6)
+TEST_VECTOR_HASHER(md4_7)
+TEST_VECTOR_HASHER(md5_1)
+TEST_VECTOR_HASHER(md5_2)
+TEST_VECTOR_HASHER(md5_3)
+TEST_VECTOR_HASHER(md5_4)
+TEST_VECTOR_HASHER(md5_5)
+TEST_VECTOR_HASHER(md5_6)
+TEST_VECTOR_HASHER(md5_7)
+TEST_VECTOR_HASHER(sha1_1)
+TEST_VECTOR_HASHER(sha1_2)
+TEST_VECTOR_HASHER(sha1_3)
+TEST_VECTOR_HASHER(sha256_1)
+TEST_VECTOR_HASHER(sha256_2)
+TEST_VECTOR_HASHER(sha256_3)
+TEST_VECTOR_HASHER(sha384_1)
+TEST_VECTOR_HASHER(sha384_2)
+TEST_VECTOR_HASHER(sha384_3)
+TEST_VECTOR_HASHER(sha512_1)
+TEST_VECTOR_HASHER(sha512_2)
+TEST_VECTOR_HASHER(sha512_3)
+
+TEST_VECTOR_PRF(aes_xcbc_p1)
+TEST_VECTOR_PRF(aes_xcbc_p2)
+TEST_VECTOR_PRF(aes_xcbc_p3)
+TEST_VECTOR_PRF(aes_xcbc_p4)
+TEST_VECTOR_PRF(aes_xcbc_p5)
+TEST_VECTOR_PRF(aes_xcbc_p6)
+TEST_VECTOR_PRF(aes_xcbc_p7)
+TEST_VECTOR_PRF(md5_hmac_p1)
+TEST_VECTOR_PRF(md5_hmac_p2)
+TEST_VECTOR_PRF(md5_hmac_p3)
+TEST_VECTOR_PRF(md5_hmac_p4)
+TEST_VECTOR_PRF(md5_hmac_p5)
+TEST_VECTOR_PRF(md5_hmac_p6)
+TEST_VECTOR_PRF(sha1_hmac_p1)
+TEST_VECTOR_PRF(sha1_hmac_p2)
+TEST_VECTOR_PRF(sha1_hmac_p3)
+TEST_VECTOR_PRF(sha1_hmac_p4)
+TEST_VECTOR_PRF(sha1_hmac_p5)
+TEST_VECTOR_PRF(sha1_hmac_p6)
+TEST_VECTOR_PRF(sha256_hmac_p1)
+TEST_VECTOR_PRF(sha256_hmac_p2)
+TEST_VECTOR_PRF(sha256_hmac_p3)
+TEST_VECTOR_PRF(sha256_hmac_p4)
+TEST_VECTOR_PRF(sha256_hmac_p5)
+TEST_VECTOR_PRF(sha256_hmac_p6)
+TEST_VECTOR_PRF(sha384_hmac_p1)
+TEST_VECTOR_PRF(sha384_hmac_p2)
+TEST_VECTOR_PRF(sha384_hmac_p3)
+TEST_VECTOR_PRF(sha384_hmac_p4)
+TEST_VECTOR_PRF(sha384_hmac_p5)
+TEST_VECTOR_PRF(sha384_hmac_p6)
+TEST_VECTOR_PRF(sha512_hmac_p1)
+TEST_VECTOR_PRF(sha512_hmac_p2)
+TEST_VECTOR_PRF(sha512_hmac_p3)
+TEST_VECTOR_PRF(sha512_hmac_p4)
+TEST_VECTOR_PRF(sha512_hmac_p5)
+TEST_VECTOR_PRF(sha512_hmac_p6)
+TEST_VECTOR_PRF(fips_prf_1)
+
+TEST_VECTOR_RNG(rng_monobit_1)
+TEST_VECTOR_RNG(rng_monobit_2)
+TEST_VECTOR_RNG(rng_monobit_3)
+TEST_VECTOR_RNG(rng_poker_1)
+TEST_VECTOR_RNG(rng_poker_2)
+TEST_VECTOR_RNG(rng_poker_3)
+TEST_VECTOR_RNG(rng_runs_1)
+TEST_VECTOR_RNG(rng_runs_2)
+TEST_VECTOR_RNG(rng_runs_3)
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/3des_cbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/3des_cbc.c
new file mode 100644
index 000000000..de5658da7
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/3des_cbc.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * Example 1 from NIST 3DES MMT
+ */
+crypter_test_vector_t des3_cbc1 = {
+ .alg = ENCR_3DES, .key_size = 24, .len = 8,
+ .key = "\x62\x7f\x46\x0e\x08\x10\x4a\x10"
+ "\x43\xcd\x26\x5d\x58\x40\xea\xf1"
+ "\x31\x3e\xdf\x97\xdf\x2a\x8a\x8c",
+ .iv = "\x8e\x29\xf7\x5e\xa7\x7e\x54\x75",
+ .plain = "\x32\x6a\x49\x4c\xd3\x3f\xe7\x56",
+ .cipher = "\xb2\x2b\x8d\x66\xde\x97\x06\x92"
+};
+
+/**
+ * Example 2 from NIST 3DES MMT
+ */
+crypter_test_vector_t des3_cbc2 = {
+ .alg = ENCR_3DES, .key_size = 24, .len = 16,
+ .key = "\x37\xae\x5e\xbf\x46\xdf\xf2\xdc"
+ "\x07\x54\xb9\x4f\x31\xcb\xb3\x85"
+ "\x5e\x7f\xd3\x6d\xc8\x70\xbf\xae",
+ .iv = "\x3d\x1d\xe3\xcc\x13\x2e\x3b\x65",
+ .plain = "\x84\x40\x1f\x78\xfe\x6c\x10\x87\x6d\x8e\xa2\x30\x94\xea\x53\x09",
+ .cipher = "\x7b\x1f\x7c\x7e\x3b\x1c\x94\x8e\xbd\x04\xa7\x5f\xfb\xa7\xd2\xf5"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cbc.c
new file mode 100644
index 000000000..26aadb444
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cbc.c
@@ -0,0 +1,113 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * Test 1 of RFC3602
+ */
+crypter_test_vector_t aes_cbc1 = {
+ .alg = ENCR_AES_CBC, .key_size = 16, .len = 16,
+ .key = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b\x51\x2e\x03\xd5\x34\x12\x00\x06",
+ .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+ .plain = "Single block msg",
+ .cipher = "\xe3\x53\x77\x9c\x10\x79\xae\xb8\x27\x08\x94\x2d\xbe\x77\x18\x1a"
+};
+
+/**
+ * Test 2 of RFC3602
+ */
+crypter_test_vector_t aes_cbc2 = {
+ .alg = ENCR_AES_CBC, .key_size = 16, .len = 32,
+ .key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
+ .iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
+ .plain = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .cipher = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
+ "\x75\x86\x60\x2d\x25\x3c\xff\xf9\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1"
+};
+
+/**
+ * Test 3 of RFC3602
+ */
+crypter_test_vector_t aes_cbc3 = {
+ .alg = ENCR_AES_CBC, .key_size = 16, .len = 64,
+ .key = "\x56\xe4\x7a\x38\xc5\x59\x89\x74\xbc\x46\x90\x3d\xba\x29\x03\x49",
+ .iv = "\x8c\xe8\x2e\xef\xbe\xa0\xda\x3c\x44\x69\x9e\xd7\xdb\x51\xb7\xd9",
+ .plain = "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
+ .cipher = "\xc3\x0e\x32\xff\xed\xc0\x77\x4e\x6a\xff\x6a\xf0\x86\x9f\x71\xaa"
+ "\x0f\x3a\xf0\x7a\x9a\x31\xa9\xc6\x84\xdb\x20\x7e\xb0\xef\x8e\x4e"
+ "\x35\x90\x7a\xa6\x32\xc3\xff\xdf\x86\x8b\xb7\xb2\x9d\x3d\x46\xad"
+ "\x83\xce\x9f\x9a\x10\x2e\xe9\x9d\x49\xa5\x3e\x87\xf4\xc3\xda\x55"
+};
+
+/**
+ * Test F.2.1 of NIST SP 800-38A 2001
+ */
+crypter_test_vector_t aes_cbc4 = {
+ .alg = ENCR_AES_CBC, .key_size = 16, .len = 64,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plain = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .cipher = "\x76\x49\xab\xac\x81\x19\xb2\x46\xce\xe9\x8e\x9b\x12\xe9\x19\x7d"
+ "\x50\x86\xcb\x9b\x50\x72\x19\xee\x95\xdb\x11\x3a\x91\x76\x78\xb2"
+ "\x73\xbe\xd6\xb8\xe3\xc1\x74\x3b\x71\x16\xe6\x9e\x22\x22\x95\x16"
+ "\x3f\xf1\xca\xa1\x68\x1f\xac\x09\x12\x0e\xca\x30\x75\x86\xe1\xa7"
+};
+
+/**
+ * Test F.2.3 of NIST SP 800-38A 2001
+ */
+crypter_test_vector_t aes_cbc5 = {
+ .alg = ENCR_AES_CBC, .key_size = 24, .len = 64,
+ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plain = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .cipher = "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
+ "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
+ "\x57\x1b\x24\x20\x12\xfb\x7a\xe0\x7f\xa9\xba\xac\x3d\xf1\x02\xe0"
+ "\x08\xb0\xe2\x79\x88\x59\x88\x81\xd9\x20\xa9\xe6\x4f\x56\x15\xcd"
+};
+
+/**
+ * Test F.2.5 of NIST SP 800-38A 2001
+ */
+crypter_test_vector_t aes_cbc6 = {
+ .alg = ENCR_AES_CBC, .key_size = 32, .len = 64,
+ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .plain = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .cipher = "\xf5\x8c\x4c\x04\xd6\xe5\xf1\xba\x77\x9e\xab\xfb\x5f\x7b\xfb\xd6"
+ "\x9c\xfc\x4e\x96\x7e\xdb\x80\x8d\x67\x9f\x77\x7b\xc6\x70\x2c\x7d"
+ "\x39\xf2\x33\x69\xa9\xd9\xba\xcf\xa5\x30\xe2\x63\x04\x23\x14\x61"
+ "\xb2\xeb\x05\xe2\xc3\x9b\xe9\xfc\xda\x6c\x19\x07\x8c\x6a\x9d\x1b"
+};
+
+
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_xcbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_xcbc.c
new file mode 100644
index 000000000..56d12f036
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_xcbc.c
@@ -0,0 +1,129 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * RFC 3566 Test Case #1: AES-XCBC-MAC-96 with 0-byte input
+ */
+signer_test_vector_t aes_xcbc_s1 = {
+ .alg = AUTH_AES_XCBC_96, .len = 0,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .data = "",
+ .mac = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c\x45\x73\xdf\xd5"
+};
+
+prf_test_vector_t aes_xcbc_p1 = {
+ .alg = PRF_AES128_XCBC, .key_size = 16, .len = 0,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "",
+ .out = "\x75\xf0\x25\x1d\x52\x8a\xc0\x1c\x45\x73\xdf\xd5\x84\xd7\x9f\x29"
+};
+
+/**
+ * RFC 3566 Test Case #2: AES-XCBC-MAC-96 with 3-byte input
+ */
+signer_test_vector_t aes_xcbc_s2 = {
+ .alg = AUTH_AES_XCBC_96, .len = 3,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .data = "\x00\x01\x02",
+ .mac = "\x5b\x37\x65\x80\xae\x2f\x19\xaf\xe7\x21\x9c\xee"
+};
+
+prf_test_vector_t aes_xcbc_p2 = {
+ .alg = PRF_AES128_XCBC, .key_size = 16, .len = 3,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "\x00\x01\x02",
+ .out = "\x5b\x37\x65\x80\xae\x2f\x19\xaf\xe7\x21\x9c\xee\xf1\x72\x75\x6f"
+};
+
+/**
+ * RFC 3566 Test Case #3: AES-XCBC-MAC-96 with 16-byte input
+ */
+signer_test_vector_t aes_xcbc_s3 = {
+ .alg = AUTH_AES_XCBC_96, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .mac = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7\x99\x98\xa4\x39"
+};
+
+prf_test_vector_t aes_xcbc_p3 = {
+ .alg = PRF_AES128_XCBC, .key_size = 16, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .out = "\xd2\xa2\x46\xfa\x34\x9b\x68\xa7\x99\x98\xa4\x39\x4f\xf7\xa2\x63"
+};
+
+/**
+ * RFC 3566 Test Case #4: AES-XCBC-MAC-96 with 20-byte input
+ */
+signer_test_vector_t aes_xcbc_s4 = {
+ .alg = AUTH_AES_XCBC_96, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .mac = "\x47\xf5\x1b\x45\x64\x96\x62\x15\xb8\x98\x5c\x63"
+};
+
+prf_test_vector_t aes_xcbc_p4 = {
+ .alg = PRF_AES128_XCBC, .key_size = 16, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x47\xf5\x1b\x45\x64\x96\x62\x15\xb8\x98\x5c\x63\x05\x5e\xd3\x08"
+};
+
+/**
+ * RFC 3566 Test Case #5: AES-XCBC-MAC-96 with 32-byte input
+ */
+signer_test_vector_t aes_xcbc_s5 = {
+ .alg = AUTH_AES_XCBC_96, .len = 32,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .data = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .mac = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3\x68\x07\x73\x4b"
+};
+
+prf_test_vector_t aes_xcbc_p5 = {
+ .alg = PRF_AES128_XCBC, .key_size = 16, .len = 32,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .out = "\xf5\x4f\x0e\xc8\xd2\xb9\xf3\xd3\x68\x07\x73\x4b\xd5\x28\x3f\xd4"
+};
+
+/**
+ * RFC4434 Test Case: AES-XCBC-PRF-128 with 20-byte input, 10 byte key
+ */
+prf_test_vector_t aes_xcbc_p6 = {
+ .alg = PRF_AES128_XCBC, .key_size = 10, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x0f\xa0\x87\xaf\x7d\x86\x6e\x76\x53\x43\x4e\x60\x2f\xdd\xe8\x35"
+};
+
+/**
+ * RFC4434 Test Case: AES-XCBC-PRF-128 with 20-byte input, 18 byte key
+ */
+prf_test_vector_t aes_xcbc_p7 = {
+ .alg = PRF_AES128_XCBC, .key_size = 18, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\xed\xcb",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x8c\xd3\xc9\x3a\xe5\x98\xa9\x80\x30\x06\xff\xb6\x7c\x40\xe9\xe4"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/blowfish.c b/src/libstrongswan/plugins/test_vectors/test_vectors/blowfish.c
new file mode 100644
index 000000000..63bbb1261
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/blowfish.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Copyright (C) 2009 Andreas Steffen
+ * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * Test vector by Eric Young
+ */
+crypter_test_vector_t blowfish1 = {
+ .alg = ENCR_BLOWFISH, .key_size = 16, .len = 32,
+ .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF\xF0\xE1\xD2\xC3\xB4\xA5\x96\x87",
+ .iv = "\xFE\xDC\xBA\x98\x76\x54\x32\x10",
+ .plain = "7654321 Now is the time for \0\0\0\0",
+ .cipher = "\x6B\x77\xB4\xD6\x30\x06\xDE\xE6\x05\xB1\x56\xE2\x74\x03\x97\x93"
+ "\x58\xDE\xB9\xE7\x15\x46\x16\xD9\x59\xF1\x65\x2B\xD5\xFF\x92\xCC"
+};
+
+/**
+ * Test vector by Chilkat Software
+ * (www.chilkatsoft.com/p/php_blowfish.asp)
+ */
+crypter_test_vector_t blowfish2 = {
+ .alg = ENCR_BLOWFISH, .key_size = 32, .len = 48,
+ .key = "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36"
+ "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50",
+ .iv = "\x31\x32\x33\x34\x35\x36\x37\x38",
+ .plain = "The quick brown fox jumped over the lazy dog\0\0\0\0",
+ .cipher = "\x27\x68\x55\xca\x6c\x0d\x60\xf7\xd9\x70\x82\x10\x44\x0c\x10\x72"
+ "\xe0\x5d\x07\x8e\x73\x3b\x34\xb4\x19\x8d\x60\x9d\xc2\xfc\xc2\xf0"
+ "\xc3\x09\x26\xcd\xef\x3b\x6d\x52\xba\xf6\xe3\x45\xaa\x03\xf8\x3e"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/camellia_cbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/camellia_cbc.c
new file mode 100644
index 000000000..28c038878
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/camellia_cbc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+ */
+
+/**
+ * Camellia 128 bit: set 8, vector #0
+ */
+crypter_test_vector_t camellia_cbc1 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 16, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x41\x0E\x33\xF3\x16\xDF\x4A\x72\xAA\x2B\xCD\x41\x14\xE2\x31\x4D",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Camellia 128 bit: set 8, vector #1
+ */
+crypter_test_vector_t camellia_cbc2 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 16, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x78\x35\x78\x66\xFD\x8B\x2C\xAE\xD4\xD1\xBB\xA3\xCF\xD5\x34\x0A",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+/**
+ * Camellia 192 bit: set 8, vector #0
+ */
+crypter_test_vector_t camellia_cbc3 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 24, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x94\x1A\xC6\x45\x3C\x3F\x48\xA1\x69\xC2\xF4\xFE\x2B\xBE\x55\x32",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Camellia 192 bit: set 8, vector #1
+ */
+crypter_test_vector_t camellia_cbc4 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 24, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48"
+ "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x29\x2C\x5B\xBF\xD7\x72\xAD\x27\x95\x09\x12\x0F\x3F\x0A\xCD\x48",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+/**
+ * Camellia 256 bit: set 8, vector #0
+ */
+crypter_test_vector_t camellia_cbc5 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 32, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x06\x36\x9B\x36\x08\xAE\x43\xCA\x79\xC8\x8B\xCF\x49\x7F\x67\x71",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Camellia 256 bit: set 8, vector #1
+ */
+crypter_test_vector_t camellia_cbc6 = {
+ .alg = ENCR_CAMELLIA_CBC, .key_size = 32, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48"
+ "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xE6\x84\x42\x17\x16\xFC\x0B\x01\xAE\xB5\xC6\x76\x51\x20\xF9\x5F",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/cast.c b/src/libstrongswan/plugins/test_vectors/test_vectors/cast.c
new file mode 100644
index 000000000..a33a219ed
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/cast.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * Test from RFC 2144
+ */
+crypter_test_vector_t cast1 = {
+ .alg = ENCR_CAST, .key_size = 16, .len = 8,
+ .key = "\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
+ .cipher = "\x23\x8B\x4F\xE5\x84\x7E\x44\xB2"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/des.c b/src/libstrongswan/plugins/test_vectors/test_vectors/des.c
new file mode 100644
index 000000000..80b5f1010
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/des.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+ */
+
+/**
+ * DES 56 bit: set 8, vector #0
+ */
+crypter_test_vector_t des_ecb1 = {
+ .alg = ENCR_DES_ECB, .key_size = 8, .len = 8,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x41\xAD\x06\x85\x48\x80\x9D\x02",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77"
+};
+
+/**
+ * DES 56 bit: set 8, vector #1
+ */
+crypter_test_vector_t des_ecb2 = {
+ .alg = ENCR_DES_ECB, .key_size = 8, .len = 8,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xB1\x0F\x84\x30\x97\xA0\xF9\x32",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+/**
+ * DES 56 bit: set 8, vector #0
+ */
+crypter_test_vector_t des_cbc1 = {
+ .alg = ENCR_DES, .key_size = 8, .len = 8,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x41\xAD\x06\x85\x48\x80\x9D\x02",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77"
+};
+
+/**
+ * DES 56 bit: set 8, vector #1
+ */
+crypter_test_vector_t des_cbc2 = {
+ .alg = ENCR_DES, .key_size = 8, .len = 8,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xB1\x0F\x84\x30\x97\xA0\xF9\x32",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/fips_prf.c b/src/libstrongswan/plugins/test_vectors/test_vectors/fips_prf.c
new file mode 100644
index 000000000..74e000419
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/fips_prf.c
@@ -0,0 +1,30 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * FIPS PRF known value test
+ */
+prf_test_vector_t fips_prf_1 = {
+ .alg = PRF_FIPS_SHA1_160, .stateful = TRUE, .key_size = 20, .len = 1,
+ .key = "\xbd\x02\x9b\xbe\x7f\x51\x96\x0b\xcf\x9e\xdb\x2b\x61\xf0\x6f\x0f"
+ "\xeb\x5a\x38\xb6",
+ .seed = "\x00",
+ .out = "\x20\x70\xb3\x22\x3d\xba\x37\x2f\xde\x1c\x0f\xfc\x7b\x2e\x3b\x49"
+ "\x8b\x26\x06\x14\x3c\x6c\x18\xba\xcb\x0f\x6c\x55\xba\xbb\x13\x78"
+ "\x8e\x20\xd7\x37\xa3\x27\x51\x16"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/idea.c b/src/libstrongswan/plugins/test_vectors/test_vectors/idea.c
new file mode 100644
index 000000000..4856a480f
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/idea.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+ */
+
+/**
+ * IDEA 128 bit: set 8, vector #0
+ */
+crypter_test_vector_t idea1 = {
+ .alg = ENCR_IDEA, .key_size = 16, .len = 8,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xDB\x2D\x4A\x92\xAA\x68\x27\x3F",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77"
+};
+
+/**
+ * IDEA 128 bit: set 8, vector #1
+ */
+crypter_test_vector_t idea2 = {
+ .alg = ENCR_IDEA, .key_size = 16, .len = 8,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xF1\x29\xA6\x60\x1E\xF6\x2A\x47",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/md2.c b/src/libstrongswan/plugins/test_vectors/test_vectors/md2.c
new file mode 100644
index 000000000..3348e12d3
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/md2.c
@@ -0,0 +1,63 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * MD2 vectors from RFC 1319
+ */
+hasher_test_vector_t md2_1 = {
+ .alg = HASH_MD2, .len = 0,
+ .data = "",
+ .hash = "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73"
+};
+
+hasher_test_vector_t md2_2 = {
+ .alg = HASH_MD2, .len = 1,
+ .data = "a",
+ .hash = "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1"
+};
+
+hasher_test_vector_t md2_3 = {
+ .alg = HASH_MD2, .len = 3,
+ .data = "abc",
+ .hash = "\xda\x85\x3b\x0d\x3f\x88\xd9\x9b\x30\x28\x3a\x69\xe6\xde\xd6\xbb"
+};
+
+hasher_test_vector_t md2_4 = {
+ .alg = HASH_MD2, .len = 14,
+ .data = "message digest",
+ .hash = "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0"
+};
+
+hasher_test_vector_t md2_5 = {
+ .alg = HASH_MD2, .len = 26,
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ .hash = "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b"
+};
+
+hasher_test_vector_t md2_6 = {
+ .alg = HASH_MD2, .len = 62,
+ .data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .hash = "\xda\x33\xde\xf2\xa4\x2d\xf1\x39\x75\x35\x28\x46\xc3\x03\x38\xcd"
+};
+
+hasher_test_vector_t md2_7 = {
+ .alg = HASH_MD2, .len = 80,
+ .data = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .hash = "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/md4.c b/src/libstrongswan/plugins/test_vectors/test_vectors/md4.c
new file mode 100644
index 000000000..ef9406f5f
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/md4.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * MD4 vectors from RFC 1320
+ */
+hasher_test_vector_t md4_1 = {
+ .alg = HASH_MD4, .len = 0,
+ .data = "",
+ .hash = "\x31\xd6\xcf\xe0\xd1\x6a\xe9\x31\xb7\x3c\x59\xd7\xe0\xc0\x89\xc0"
+};
+
+hasher_test_vector_t md4_2 = {
+ .alg = HASH_MD4, .len = 1,
+ .data = "a",
+ .hash = "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24"
+};
+
+hasher_test_vector_t md4_3 = {
+ .alg = HASH_MD4, .len = 3,
+ .data = "abc",
+ .hash = "\xa4\x48\x01\x7a\xaf\x21\xd8\x52\x5f\xc1\x0a\xe8\x7a\xa6\x72\x9d"
+};
+
+hasher_test_vector_t md4_4 = {
+ .alg = HASH_MD4, .len = 14,
+ .data = "message digest",
+ .hash = "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b"
+};
+
+hasher_test_vector_t md4_5 = {
+ .alg = HASH_MD4, .len = 26,
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ .hash = "\xd7\x9e\x1c\x30\x8a\xa5\xbb\xcd\xee\xa8\xed\x63\xdf\x41\x2d\xa9"
+};
+
+hasher_test_vector_t md4_6 = {
+ .alg = HASH_MD4, .len = 62,
+ .data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .hash = "\x04\x3f\x85\x82\xf2\x41\xdb\x35\x1c\xe6\x27\xe1\x53\xe7\xf0\xe4"
+};
+
+hasher_test_vector_t md4_7 = {
+ .alg = HASH_MD4, .len = 80,
+ .data = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .hash = "\xe3\x3b\x4d\xdc\x9c\x38\xf2\x19\x9c\x3e\x7b\x16\x4f\xcc\x05\x36"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/md5.c b/src/libstrongswan/plugins/test_vectors/test_vectors/md5.c
new file mode 100644
index 000000000..c7b213674
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/md5.c
@@ -0,0 +1,63 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * MD5 vectors from RFC1321
+ */
+hasher_test_vector_t md5_1 = {
+ .alg = HASH_MD5, .len = 0,
+ .data = "",
+ .hash = "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e"
+};
+
+hasher_test_vector_t md5_2 = {
+ .alg = HASH_MD5, .len = 1,
+ .data = "a",
+ .hash = "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61"
+};
+
+hasher_test_vector_t md5_3 = {
+ .alg = HASH_MD5, .len = 3,
+ .data = "abc",
+ .hash = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"
+};
+
+hasher_test_vector_t md5_4 = {
+ .alg = HASH_MD5, .len = 14,
+ .data = "message digest",
+ .hash = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0"
+};
+
+hasher_test_vector_t md5_5 = {
+ .alg = HASH_MD5, .len = 26,
+ .data = "abcdefghijklmnopqrstuvwxyz",
+ .hash = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1\x3b"
+};
+
+hasher_test_vector_t md5_6 = {
+ .alg = HASH_MD5, .len = 62,
+ .data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ .hash = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d\x9f"
+};
+
+hasher_test_vector_t md5_7 = {
+ .alg = HASH_MD5, .len = 80,
+ .data = "1234567890123456789012345678901234567890"
+ "1234567890123456789012345678901234567890",
+ .hash = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6\x7a"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/md5_hmac.c b/src/libstrongswan/plugins/test_vectors/test_vectors/md5_hmac.c
new file mode 100644
index 000000000..5221d530c
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/md5_hmac.c
@@ -0,0 +1,112 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * MD5 hmac test vectors from RFC2202
+ */
+signer_test_vector_t md5_hmac_s1 = {
+ .alg = AUTH_HMAC_MD5_96, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8"
+};
+
+signer_test_vector_t md5_hmac_s2 = {
+ .alg = AUTH_HMAC_MD5_128, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d"
+};
+
+prf_test_vector_t md5_hmac_p1 = {
+ .alg = PRF_HMAC_MD5, .key_size = 16, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .seed = "Hi There",
+ .out = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d"
+};
+
+prf_test_vector_t md5_hmac_p2 = {
+ .alg = PRF_HMAC_MD5, .key_size = 4, .len = 28,
+ .key = "Jefe",
+ .seed = "what do ya want for nothing?",
+ .out = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38"
+};
+
+signer_test_vector_t md5_hmac_s3 = {
+ .alg = AUTH_HMAC_MD5_96, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33"
+};
+
+signer_test_vector_t md5_hmac_s4 = {
+ .alg = AUTH_HMAC_MD5_128, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6"
+};
+
+prf_test_vector_t md5_hmac_p3 = {
+ .alg = PRF_HMAC_MD5, .key_size = 16, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .seed = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .out = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6"
+};
+
+prf_test_vector_t md5_hmac_p4 = {
+ .alg = PRF_HMAC_MD5, .key_size = 25, .len = 50,
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .seed = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ .out = "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79"
+};
+
+prf_test_vector_t md5_hmac_p5 = {
+ .alg = PRF_HMAC_MD5, .key_size = 80, .len = 54,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .out = "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd"
+};
+
+prf_test_vector_t md5_hmac_p6 = {
+ .alg = PRF_HMAC_MD5, .key_size = 80, .len = 73,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key and Larger "
+ "Than One Block-Size Data",
+ .out = "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e"
+};
+
diff --git a/src/pluto/rnd.h b/src/libstrongswan/plugins/test_vectors/test_vectors/null.c
index e32b68b47..c4f5d41b3 100644
--- a/src/pluto/rnd.h
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/null.c
@@ -1,21 +1,25 @@
-/* randomness machinery
- * Copyright (C) 1998, 1999 D. Hugh Redelmeier.
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
+ * Free Software Foundation; either version 2 of the Licenseor (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
- * This program is distributed in the hope that it will be useful, but
+ * This program is distributed in the hope that it will be usefulbut
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: rnd.h 3252 2007-10-06 21:24:50Z andreas $
*/
-extern u_char secret_of_the_day[SHA1_DIGEST_SIZE];
+#include <crypto/crypto_tester.h>
+
+crypter_test_vector_t null1 = {
+ .alg = ENCR_NULL, .key_size = 0, .len = 44,
+ .key = "",
+ .iv = "",
+ .plain = "The quick brown fox jumped over the lazy dog",
+ .cipher = "The quick brown fox jumped over the lazy dog"
+};
-extern void get_rnd_bytes(u_char *buffer, int length);
-extern void init_rnd_pool(void);
-extern void init_secret(void);
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/rc5.c b/src/libstrongswan/plugins/test_vectors/test_vectors/rc5.c
new file mode 100644
index 000000000..458f63aa9
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/rc5.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+ */
+
+/**
+ * RC5 128 bit: set 8, vector #0
+ */
+crypter_test_vector_t rc5_1 = {
+ .alg = ENCR_RC5, .key_size = 16, .len = 8,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x96\x95\x0D\xDA\x65\x4A\x3D\x62",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77"
+};
+
+/**
+ * RC5 128 bit: set 8, vector #1
+ */
+crypter_test_vector_t rc5_2 = {
+ .alg = ENCR_RC5, .key_size = 16, .len = 8,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x63\x8B\x3A\x5E\xF7\x2B\x66\x3F",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/rng.c b/src/libstrongswan/plugins/test_vectors/test_vectors/rng.c
new file mode 100644
index 000000000..8502df7ad
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/rng.c
@@ -0,0 +1,236 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+#include <debug.h>
+
+/**
+ * Monobit test
+ */
+typedef struct {
+ int lower;
+ int upper;
+} monobit_t;
+
+monobit_t monobit_all = {
+ .lower = 9654,
+ .upper = 10346
+};
+
+static bool test_monobit(monobit_t *param, chunk_t data)
+{
+ int i, j, bits = 0;
+
+ for (i = 0; i < data.len; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ if (data.ptr[i] & (1<<j))
+ {
+ bits++;
+ }
+ }
+ }
+ DBG2(" Monobit: %d/%d bits set", bits, data.len * 8);
+ if (bits > param->lower && bits < param->upper)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+rng_test_vector_t rng_monobit_1 = {
+ RNG_WEAK, .len = 2500,
+ .test = (void*)test_monobit,
+ .user = &monobit_all
+};
+
+rng_test_vector_t rng_monobit_2 = {
+ RNG_STRONG, .len = 2500,
+ .test = (void*)test_monobit,
+ .user = &monobit_all
+};
+
+rng_test_vector_t rng_monobit_3 = {
+ RNG_TRUE, .len = 2500,
+ .test = (void*)test_monobit,
+ .user = &monobit_all
+};
+
+/**
+ * Poker test
+ */
+typedef struct {
+ double lower;
+ double upper;
+} poker_t;
+
+poker_t poker_all = {
+ .lower = 1.03,
+ .upper = 57.4
+};
+
+static bool test_poker(poker_t *param, chunk_t data)
+{
+ int i, counter[16];
+ double sum = 0.0;
+
+ memset(counter, 0, sizeof(counter));
+
+ for (i = 0; i < data.len; i++)
+ {
+ counter[data.ptr[i] & 0x0F]++;
+ counter[(data.ptr[i] & 0xF0) >> 4]++;
+ }
+
+ for (i = 0; i < countof(counter); i++)
+ {
+ sum += (counter[i] * counter[i]) / 5000.0 * 16.0;
+ }
+ sum -= 5000.0;
+ DBG2(" Poker: %f", sum);
+ if (sum > param->lower && sum < param->upper)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+rng_test_vector_t rng_poker_1 = {
+ RNG_WEAK, .len = 2500,
+ .test = (void*)test_poker,
+ .user = &poker_all
+};
+
+rng_test_vector_t rng_poker_2 = {
+ RNG_STRONG, .len = 2500,
+ .test = (void*)test_poker,
+ .user = &poker_all
+};
+
+rng_test_vector_t rng_poker_3 = {
+ RNG_TRUE, .len = 2500,
+ .test = (void*)test_poker,
+ .user = &poker_all
+};
+
+/**
+ * Runs test
+ */
+typedef struct {
+ int longrun;
+ int lower[7];
+ int upper[7];
+} runs_t;
+
+runs_t runs_all = {
+ .longrun = 34,
+ .lower = {-1, 2267, 1079, 502, 223, 90, 90},
+ .upper = {-1, 2733, 1421, 748, 402, 223, 223},
+};
+
+static bool test_runs(runs_t *param, chunk_t data)
+{
+ int i, j, zero_runs[7], one_runs[7], zero = 0, one = 0, longrun = 0;
+
+ memset(one_runs, 0, sizeof(zero_runs));
+ memset(zero_runs, 0, sizeof(one_runs));
+
+ for (i = 0; i < data.len; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ if (data.ptr[i] & (1<<j))
+ {
+ if (one)
+ {
+ if (++one >= param->longrun)
+ {
+ longrun++;
+ break;
+ }
+ }
+ else
+ {
+ zero_runs[min(6, zero)]++;
+ zero = 0;
+ one = 1;
+ }
+ }
+ else
+ {
+ if (zero)
+ {
+ if (++zero >= param->longrun)
+ {
+ longrun++;
+ break;
+ }
+ }
+ else
+ {
+ one_runs[min(6, one)]++;
+ one = 0;
+ zero = 1;
+ }
+ }
+ }
+ }
+
+ DBG2(" Runs: zero: %d/%d/%d/%d/%d/%d, one: %d/%d/%d/%d/%d/%d, "
+ "longruns: %d",
+ zero_runs[1], zero_runs[2], zero_runs[3],
+ zero_runs[4], zero_runs[5], zero_runs[6],
+ one_runs[1], one_runs[2], one_runs[3],
+ one_runs[4], one_runs[5], one_runs[6],
+ longrun);
+
+ if (longrun)
+ {
+ return FALSE;
+ }
+
+ for (i = 1; i < countof(zero_runs); i++)
+ {
+ if (zero_runs[i] <= param->lower[i] ||
+ zero_runs[i] >= param->upper[i] ||
+ one_runs[i] <= param->lower[i] ||
+ one_runs[i] >= param->upper[i])
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+rng_test_vector_t rng_runs_1 = {
+ RNG_WEAK, .len = 2500,
+ .test = (void*)test_runs,
+ .user = &runs_all
+};
+
+rng_test_vector_t rng_runs_2 = {
+ RNG_STRONG, .len = 2500,
+ .test = (void*)test_runs,
+ .user = &runs_all
+};
+
+rng_test_vector_t rng_runs_3 = {
+ RNG_TRUE, .len = 2500,
+ .test = (void*)test_runs,
+ .user = &runs_all
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/serpent_cbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/serpent_cbc.c
new file mode 100644
index 000000000..256a59603
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/serpent_cbc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from https://www.cosic.esat.kuleuven.be/nessie/testvectors/
+ */
+
+/**
+ * Serpent 128 bit: set 8, vector #0
+ */
+crypter_test_vector_t serpent_cbc1 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 16, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x33\xB3\xDC\x87\xED\xDD\x9B\x0F\x6A\x1F\x40\x7D\x14\x91\x93\x65",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Serpent 128 bit: set 8, vector #1
+ */
+crypter_test_vector_t serpent_cbc2 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 16, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xBE\xB6\xC0\x69\x39\x38\x22\xD3\xBE\x73\xFF\x30\x52\x5E\xC4\x3E",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+/**
+ * Serpent 192 bit: set 8, vector #0
+ */
+crypter_test_vector_t serpent_cbc3 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 24, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x45\x28\xCA\xCC\xB9\x54\xD4\x50\x65\x5E\x8C\xFD\x71\xCB\xFA\xC7",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Serpent 192 bit: set 8, vector #1
+ */
+crypter_test_vector_t serpent_cbc4 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 24, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48"
+ "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xE0\x20\x8B\xE2\x78\xE2\x14\x20\xC4\xB1\xB9\x74\x77\x88\xA9\x54",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
+/**
+ * Serpent 256 bit: set 8, vector #0
+ */
+crypter_test_vector_t serpent_cbc5 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 32, .len = 16,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x3D\xA4\x6F\xFA\x6F\x4D\x6F\x30\xCD\x25\x83\x33\xE5\xA6\x13\x69",
+ .cipher = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+};
+
+/**
+ * Serpent 256 bit: set 8, vector #1
+ */
+crypter_test_vector_t serpent_cbc6 = {
+ .alg = ENCR_SERPENT_CBC, .key_size = 32, .len = 16,
+ .key = "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48"
+ "\x2B\xD6\x45\x9F\x82\xC5\xB3\x00\x95\x2C\x49\x10\x48\x81\xFF\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x67\x7C\x8D\xFA\xA0\x80\x71\x74\x3F\xD2\xB4\x15\xD1\xB2\x8A\xF2",
+ .cipher = "\xEA\x02\x47\x14\xAD\x5C\x4D\x84\xEA\x02\x47\x14\xAD\x5C\x4D\x84"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c
new file mode 100644
index 000000000..51f22716e
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1.c
@@ -0,0 +1,51 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * SHA-1 test vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
+ */
+hasher_test_vector_t sha1_1 = {
+ .alg = HASH_SHA1, .len = 1,
+ .data = "\x5e",
+ .hash = "\x5e\x6f\x80\xa3\x4a\x97\x98\xca\xfc\x6a\x5d\xb9\x6c\xc5\x7b\xa4"
+ "\xc4\xdb\x59\xc2"
+};
+
+hasher_test_vector_t sha1_2 = {
+ .alg = HASH_SHA1, .len = 16,
+ .data = "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46",
+ .hash = "\x82\xab\xff\x66\x05\xdb\xe1\xc1\x7d\xef\x12\xa3\x94\xfa\x22\xa8"
+ "\x2b\x54\x4a\x35"
+};
+
+hasher_test_vector_t sha1_3 = {
+ .alg = HASH_SHA1, .len = 163,
+ .data = "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f"
+ "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15"
+ "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92"
+ "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f"
+ "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04"
+ "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca"
+ "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b"
+ "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60"
+ "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80"
+ "\x7c\x7d\x52\x3d\x6d\x79\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27"
+ "\xcd\xbb\xfb",
+ .hash = "\xcb\x00\x82\xc8\xf1\x97\xd2\x60\x99\x1b\xa6\xa4\x60\xe7\x6e\x20"
+ "\x2b\xad\x27\xb3"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/sha1_hmac.c b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1_hmac.c
new file mode 100644
index 000000000..8d6f66373
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/sha1_hmac.c
@@ -0,0 +1,146 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * SHA1 hmac test vectors from RFC2202
+ */
+signer_test_vector_t sha1_hmac_s1 = {
+ .alg = AUTH_HMAC_SHA1_96, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6"
+};
+
+signer_test_vector_t sha1_hmac_s2 = {
+ .alg = AUTH_HMAC_SHA1_128, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
+};
+
+signer_test_vector_t sha1_hmac_s3 = {
+ .alg = AUTH_HMAC_SHA1_160, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
+ "\xf1\x46\xbe\x00"
+};
+
+prf_test_vector_t sha1_hmac_p1 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 20, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .seed = "Hi There",
+ .out = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e"
+ "\xf1\x46\xbe\x00"
+};
+
+prf_test_vector_t sha1_hmac_p2 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 4, .len = 28,
+ .key = "Jefe",
+ .seed = "what do ya want for nothing?",
+ .out = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c"
+ "\x25\x9a\x7c\x79"
+};
+
+signer_test_vector_t sha1_hmac_s4 = {
+ .alg = AUTH_HMAC_SHA1_96, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4"
+ "\x63\xf1\x75\xd3"
+};
+
+signer_test_vector_t sha1_hmac_s5 = {
+ .alg = AUTH_HMAC_SHA1_128, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
+};
+
+signer_test_vector_t sha1_hmac_s6 = {
+ .alg = AUTH_HMAC_SHA1_160, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
+ "\x63\xf1\x75\xd3"
+};
+
+prf_test_vector_t sha1_hmac_p3 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 20, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .seed = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .out = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f"
+ "\x63\xf1\x75\xd3"
+};
+
+prf_test_vector_t sha1_hmac_p4 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 25, .len = 50,
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .seed = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ .out = "\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c"
+ "\x2d\x72\x35\xda"
+};
+
+prf_test_vector_t sha1_hmac_p5 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 80, .len = 54,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .out = "\xaa\x4a\xe5\xe1\x52\x72\xd0\x0e\x95\x70\x56\x37\xce\x8a\x3b\x55"
+ "\xed\x40\x21\x12"
+};
+
+prf_test_vector_t sha1_hmac_p6 = {
+ .alg = PRF_HMAC_SHA1, .key_size = 80, .len = 73,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key and Larger "
+ "Than One Block-Size Data",
+ .out = "\xe8\xe9\x9d\x0f\x45\x23\x7d\x78\x6d\x6b\xba\xa7\x96\x5c\x78\x08"
+ "\xbb\xff\x1a\x91"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/sha2.c b/src/libstrongswan/plugins/test_vectors/test_vectors/sha2.c
new file mode 100644
index 000000000..e2bd42240
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/sha2.c
@@ -0,0 +1,136 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * SHA-256 vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
+ */
+hasher_test_vector_t sha256_1 = {
+ .alg = HASH_SHA256, .len = 1,
+ .data = "\x19",
+ .hash = "\x68\xaa\x2e\x2e\xe5\xdf\xf9\x6e\x33\x55\xe6\xc7\xee\x37\x3e\x3d"
+ "\x6a\x4e\x17\xf7\x5f\x95\x18\xd8\x43\x70\x9c\x0c\x9b\xc3\xe3\xd4"
+};
+
+hasher_test_vector_t sha256_2 = {
+ .alg = HASH_SHA256, .len = 16,
+ .data = "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52",
+ .hash = "\x17\x5e\xe6\x9b\x02\xba\x9b\x58\xe2\xb0\xa5\xfd\x13\x81\x9c\xea"
+ "\x57\x3f\x39\x40\xa9\x4f\x82\x51\x28\xcf\x42\x09\xbe\xab\xb4\xe8"
+};
+
+hasher_test_vector_t sha256_3 = {
+ .alg = HASH_SHA256, .len = 163,
+ .data = "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0"
+ "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00"
+ "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77"
+ "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74"
+ "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b"
+ "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca"
+ "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4"
+ "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09"
+ "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a"
+ "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39"
+ "\x3d\x54\xd6",
+ .hash = "\x97\xdb\xca\x7d\xf4\x6d\x62\xc8\xa4\x22\xc9\x41\xdd\x7e\x83\x5b"
+ "\x8a\xd3\x36\x17\x63\xf7\xe9\xb2\xd9\x5f\x4f\x0d\xa6\xe1\xcc\xbc"
+};
+
+/**
+ * SHA-384 vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
+ */
+hasher_test_vector_t sha384_1 = {
+ .alg = HASH_SHA384, .len = 1,
+ .data = "\xb9",
+ .hash = "\xbc\x80\x89\xa1\x90\x07\xc0\xb1\x41\x95\xf4\xec\xc7\x40\x94\xfe"
+ "\xc6\x4f\x01\xf9\x09\x29\x28\x2c\x2f\xb3\x92\x88\x15\x78\x20\x8a"
+ "\xd4\x66\x82\x8b\x1c\x6c\x28\x3d\x27\x22\xcf\x0a\xd1\xab\x69\x38"
+};
+
+hasher_test_vector_t sha384_2 = {
+ .alg = HASH_SHA384, .len = 16,
+ .data = "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39",
+ .hash = "\xc9\xa6\x84\x43\xa0\x05\x81\x22\x56\xb8\xec\x76\xb0\x05\x16\xf0"
+ "\xdb\xb7\x4f\xab\x26\xd6\x65\x91\x3f\x19\x4b\x6f\xfb\x0e\x91\xea"
+ "\x99\x67\x56\x6b\x58\x10\x9c\xbc\x67\x5c\xc2\x08\xe4\xc8\x23\xf7"
+};
+
+hasher_test_vector_t sha384_3 = {
+ .alg = HASH_SHA384, .len = 227,
+ .data = "\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb\x69\x12\xec\x10\xff\xcf"
+ "\x74\x79\x03\x49\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21\xdb\x0f"
+ "\x3e\x7d\xc8\x7f\x82\x32\x64\xbb\xe4\x0d\x18\x11\xc9\xea\x20\x61"
+ "\xe1\xc8\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02\xfc\x3f\x50\x42"
+ "\xe6\xbf\x58\xcb\xa8\xa2\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71"
+ "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86\x5f\x25\xcc\x22\xb5\xe8"
+ "\x77\x84\xa1\x2f\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a\x2c\xe6"
+ "\x56\x5c\xbd\xf1\x3d\xca\x40\x38\x32\xcf\xcb\x0e\x8b\x72\x11\xe8"
+ "\x3a\xf3\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5\x1c\xc0\x27\xaa"
+ "\xed\xef\xf8\x5a\xad\x7c\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a"
+ "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15\x1c\xb9\xbc\x51\x25\xa4"
+ "\x22\xe9\x41\xde\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd\xd0\x96"
+ "\x76\x71\x1c\xf3\xdb\x0a\x34\x40\x72\x0e\x16\x15\xc1\xf2\x2f\xbc"
+ "\x3c\x72\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77\x40\x86\x42\x14"
+ "\x7e\xd0\x96",
+ .hash = "\x4f\x44\x0d\xb1\xe6\xed\xd2\x89\x9f\xa3\x35\xf0\x95\x15\xaa\x02"
+ "\x5e\xe1\x77\xa7\x9f\x4b\x4a\xaf\x38\xe4\x2b\x5c\x4d\xe6\x60\xf5"
+ "\xde\x8f\xb2\xa5\xb2\xfb\xd2\xa3\xcb\xff\xd2\x0c\xff\x12\x88\xc0"
+};
+
+/**
+ * SHA-512 vectors from "The Secure Hash Algorithm Validation System (SHAVS)"
+ */
+hasher_test_vector_t sha512_1 = {
+ .alg = HASH_SHA512, .len = 1,
+ .data = "\xd0",
+ .hash = "\x99\x92\x20\x29\x38\xe8\x82\xe7\x3e\x20\xf6\xb6\x9e\x68\xa0\xa7"
+ "\x14\x90\x90\x42\x3d\x93\xc8\x1b\xab\x3f\x21\x67\x8d\x4a\xce\xee"
+ "\xe5\x0e\x4e\x8c\xaf\xad\xa4\xc8\x5a\x54\xea\x83\x06\x82\x6c\x4a"
+ "\xd6\xe7\x4c\xec\xe9\x63\x1b\xfa\x8a\x54\x9b\x4a\xb3\xfb\xba\x15"
+};
+
+hasher_test_vector_t sha512_2 = {
+ .alg = HASH_SHA512, .len = 16,
+ .data = "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0",
+ .hash = "\xcb\x0b\x67\xa4\xb8\x71\x2c\xd7\x3c\x9a\xab\xc0\xb1\x99\xe9\x26"
+ "\x9b\x20\x84\x4a\xfb\x75\xac\xbd\xd1\xc1\x53\xc9\x82\x89\x24\xc3"
+ "\xdd\xed\xaa\xfe\x66\x9c\x5f\xdd\x0b\xc6\x6f\x63\x0f\x67\x73\x98"
+ "\x82\x13\xeb\x1b\x16\xf5\x17\xad\x0d\xe4\xb2\xf0\xc9\x5c\x90\xf8"
+};
+
+hasher_test_vector_t sha512_3 = {
+ .alg = HASH_SHA512, .len = 227,
+ .data = "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31"
+ "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde"
+ "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4"
+ "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2"
+ "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3"
+ "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95"
+ "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65"
+ "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f"
+ "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41"
+ "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28"
+ "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1"
+ "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8"
+ "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b"
+ "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7"
+ "\xfb\x40\xd2",
+ .hash = "\xc6\x65\xbe\xfb\x36\xda\x18\x9d\x78\x82\x2d\x10\x52\x8c\xbf\x3b"
+ "\x12\xb3\xee\xf7\x26\x03\x99\x09\xc1\xa1\x6a\x27\x0d\x48\x71\x93"
+ "\x77\x96\x6b\x95\x7a\x87\x8e\x72\x05\x84\x77\x9a\x62\x82\x5c\x18"
+ "\xda\x26\x41\x5e\x49\xa7\x17\x6a\x89\x4e\x75\x10\xfd\x14\x51\xf5"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/sha2_hmac.c b/src/libstrongswan/plugins/test_vectors/test_vectors/sha2_hmac.c
new file mode 100644
index 000000000..536eba8f6
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/sha2_hmac.c
@@ -0,0 +1,353 @@
+/*
+ * 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 Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * SHA-256, SHA384, SHA512 hmac test vectors from RFC 4868
+ */
+prf_test_vector_t sha256_hmac_p1 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 20, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .seed = "Hi There",
+ .out = "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b"
+ "\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7"
+};
+
+signer_test_vector_t sha256_hmac_s1 = {
+ .alg = AUTH_HMAC_SHA2_256_128, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\x19\x8a\x60\x7e\xb4\x4b\xfb\xc6\x99\x03\xa0\xf1\xcf\x2b\xbd\xc5"
+};
+
+prf_test_vector_t sha384_hmac_p1 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 20, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .seed = "Hi There",
+ .out = "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f"
+ "\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c"
+ "\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6"
+};
+
+signer_test_vector_t sha384_hmac_s1 = {
+ .alg = AUTH_HMAC_SHA2_384_192, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\xb6\xa8\xd5\x63\x6f\x5c\x6a\x72\x24\xf9\x97\x7d\xcf\x7e\xe6\xc7"
+ "\xfb\x6d\x0c\x48\xcb\xde\xe9\x73"
+};
+
+prf_test_vector_t sha512_hmac_p1 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 20, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ .seed = "Hi There",
+ .out = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+ "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+ "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+ "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54"
+};
+
+signer_test_vector_t sha512_hmac_s1 = {
+ .alg = AUTH_HMAC_SHA2_512_256, .len = 8,
+ .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ .data = "Hi There",
+ .mac = "\x63\x7e\xdc\x6e\x01\xdc\xe7\xe6\x74\x2a\x99\x45\x1a\xae\x82\xdf"
+ "\x23\xda\x3e\x92\x43\x9e\x59\x0e\x43\xe7\x61\xb3\x3e\x91\x0f\xb8"
+};
+
+prf_test_vector_t sha256_hmac_p2 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 4, .len = 28,
+ .key = "Jefe",
+ .seed = "what do ya want for nothing?",
+ .out = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7"
+ "\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43"
+};
+
+signer_test_vector_t sha256_hmac_s2 = {
+ .alg = AUTH_HMAC_SHA2_256_128, .len = 28,
+ .key = "JefeJefeJefeJefeJefeJefeJefeJefe",
+ .data = "what do ya want for nothing?",
+ .mac = "\x16\x7f\x92\x85\x88\xc5\xcc\x2e\xef\x8e\x30\x93\xca\xa0\xe8\x7c"
+};
+
+prf_test_vector_t sha384_hmac_p2 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 4, .len = 28,
+ .key = "Jefe",
+ .seed = "what do ya want for nothing?",
+ .out = "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+ "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+ "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49"
+};
+
+signer_test_vector_t sha384_hmac_s2 = {
+ .alg = AUTH_HMAC_SHA2_384_192, .len = 28,
+ .key = "JefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefe",
+ .data = "what do ya want for nothing?",
+ .mac = "\x2c\x73\x53\x97\x4f\x18\x42\xfd\x66\xd5\x3c\x45\x2c\xa4\x21\x22"
+ "\xb2\x8c\x0b\x59\x4c\xfb\x18\x4d"
+};
+
+prf_test_vector_t sha512_hmac_p2 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 4, .len = 28,
+ .key = "Jefe",
+ .seed = "what do ya want for nothing?",
+ .out = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+ "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54"
+ "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+ "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37"
+};
+
+signer_test_vector_t sha512_hmac_s2 = {
+ .alg = AUTH_HMAC_SHA2_512_256, .len = 28,
+ .key = "JefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefeJefe",
+ .data = "what do ya want for nothing?",
+ .mac = "\xcb\x37\x09\x17\xae\x8a\x7c\xe2\x8c\xfd\x1d\x8f\x47\x05\xd6\x14"
+ "\x1c\x17\x3b\x2a\x93\x62\xc1\x5d\xf2\x35\xdf\xb2\x51\xb1\x54\x54"
+};
+
+prf_test_vector_t sha256_hmac_p3 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 20, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .seed = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .out = "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7"
+ "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe"
+};
+
+signer_test_vector_t sha256_hmac_s3 = {
+ .alg = AUTH_HMAC_SHA2_256_128, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\xcd\xcb\x12\x20\xd1\xec\xcc\xea\x91\xe5\x3a\xba\x30\x92\xf9\x62"
+};
+
+prf_test_vector_t sha384_hmac_p3 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 20, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .seed = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .out = "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f"
+ "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b"
+ "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27"
+};
+
+signer_test_vector_t sha384_hmac_s3 = {
+ .alg = AUTH_HMAC_SHA2_384_192, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x80\x9f\x43\x9b\xe0\x02\x74\x32\x1d\x4a\x53\x86\x52\x16\x4b\x53"
+ "\x55\x4a\x50\x81\x84\xa0\xc3\x16"
+};
+
+prf_test_vector_t sha512_hmac_p3 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 20, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ .seed = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .out = "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9"
+ "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39"
+ "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07"
+ "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb"
+};
+
+signer_test_vector_t sha512_hmac_s3 = {
+ .alg = AUTH_HMAC_SHA2_512_256, .len = 50,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ .data = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ .mac = "\x2e\xe7\xac\xd7\x83\x62\x4c\xa9\x39\x87\x10\xf3\xee\x05\xae\x41"
+ "\xb9\xf9\xb0\x51\x0c\x87\xe4\x9e\x58\x6c\xc9\xbf\x96\x17\x33\xd8"
+};
+
+prf_test_vector_t sha256_hmac_p4 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 25, .len = 50,
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .seed = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ .out = "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a"
+ "\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b"
+};
+
+prf_test_vector_t sha384_hmac_p4 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 25, .len = 50,
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .seed = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ .out = "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7"
+ "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e"
+ "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb"
+};
+
+prf_test_vector_t sha512_hmac_p4 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 25, .len = 50,
+ .key = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ .seed = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ .out = "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7"
+ "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb"
+ "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63"
+ "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd"
+};
+
+prf_test_vector_t sha256_hmac_p5 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 131, .len = 54,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .out = "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f"
+ "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54"
+};
+
+prf_test_vector_t sha384_hmac_p5 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 131, .len = 54,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .out = "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+ "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+ "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52"
+};
+
+prf_test_vector_t sha512_hmac_p5 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 131, .len = 54,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "Test Using Larger Than Block-Size Key - Hash Key First",
+ .out = "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+ "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+ "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+ "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98"
+};
+
+prf_test_vector_t sha256_hmac_p6 = {
+ .alg = PRF_HMAC_SHA2_256, .key_size = 131, .len = 152,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ .out = "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44"
+ "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2"
+};
+
+prf_test_vector_t sha384_hmac_p6 = {
+ .alg = PRF_HMAC_SHA2_384, .key_size = 131, .len = 152,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ .out = "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+ "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+ "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e"
+};
+
+prf_test_vector_t sha512_hmac_p6 = {
+ .alg = PRF_HMAC_SHA2_512, .key_size = 131, .len = 152,
+ .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ .seed = "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ .out = "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+ "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
+ "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
+ "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/twofish_cbc.c b/src/libstrongswan/plugins/test_vectors/test_vectors/twofish_cbc.c
new file mode 100644
index 000000000..9c3ca20cc
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/twofish_cbc.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the Licenseor (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be usefulbut
+ * WITHOUT 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 <crypto/crypto_tester.h>
+
+/**
+ * All testvectors from http://www.schneier.com/code/ecb_ival.txt
+ */
+
+/**
+ * Twofish 128 bit: I=49
+ */
+crypter_test_vector_t twofish_cbc1 = {
+ .alg = ENCR_TWOFISH_CBC, .key_size = 16, .len = 16,
+ .key = "\xBC\xA7\x24\xA5\x45\x33\xC6\x98\x7E\x14\xAA\x82\x79\x52\xF9\x21",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x6B\x45\x92\x86\xF3\xFF\xD2\x8D\x49\xF1\x5B\x15\x81\xB0\x8E\x42",
+ .cipher = "\x5D\x9D\x4E\xEF\xFA\x91\x51\x57\x55\x24\xF1\x15\x81\x5A\x12\xE0"
+};
+
+/**
+ * Twofish 192 bit: I=49
+ */
+crypter_test_vector_t twofish_cbc2 = {
+ .alg = ENCR_TWOFISH_CBC, .key_size = 24, .len = 16,
+ .key = "\xFB\x66\x52\x2C\x33\x2F\xCC\x4C\x04\x2A\xBE\x32\xFA\x9E\x90\x2F"
+ "\xDE\xA4\xF3\xDA\x75\xEC\x7A\x8E",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\xF0\xAB\x73\x30\x11\x25\xFA\x21\xEF\x70\xBE\x53\x85\xFB\x76\xB6",
+ .cipher = "\xE7\x54\x49\x21\x2B\xEE\xF9\xF4\xA3\x90\xBD\x86\x0A\x64\x09\x41"
+};
+
+/**
+ * Twofish 256 bit: I=49
+ */
+crypter_test_vector_t twofish_cbc3 = {
+ .alg = ENCR_TWOFISH_CBC, .key_size = 32, .len = 16,
+ .key = "\x24\x8A\x7F\x35\x28\xB1\x68\xAC\xFD\xD1\x38\x6E\x3F\x51\xE3\x0C"
+ "\x2E\x21\x58\xBC\x3E\x5F\xC7\x14\xC1\xEE\xEC\xA0\xEA\x69\x6D\x48",
+ .iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ .plain = "\x43\x10\x58\xF4\xDB\xC7\xF7\x34\xDA\x4F\x02\xF0\x4C\xC4\xF4\x59",
+ .cipher = "\x37\xFE\x26\xFF\x1C\xF6\x61\x75\xF5\xDD\xF4\xC3\x3B\x97\xA2\x05"
+};
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c
new file mode 100644
index 000000000..b96dc0c9a
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c
@@ -0,0 +1,142 @@
+/*
+ * 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 "test_vectors_plugin.h"
+
+#include <crypto/crypto_factory.h>
+#include <crypto/crypto_tester.h>
+
+/* define symbols of all test vectors */
+#define TEST_VECTOR_CRYPTER(x) crypter_test_vector_t x;
+#define TEST_VECTOR_SIGNER(x) signer_test_vector_t x;
+#define TEST_VECTOR_HASHER(x) hasher_test_vector_t x;
+#define TEST_VECTOR_PRF(x) prf_test_vector_t x;
+#define TEST_VECTOR_RNG(x) rng_test_vector_t x;
+
+#include "test_vectors.h"
+
+#undef TEST_VECTOR_CRYPTER
+#undef TEST_VECTOR_SIGNER
+#undef TEST_VECTOR_HASHER
+#undef TEST_VECTOR_PRF
+#undef TEST_VECTOR_RNG
+
+#define TEST_VECTOR_CRYPTER(x)
+#define TEST_VECTOR_SIGNER(x)
+#define TEST_VECTOR_HASHER(x)
+#define TEST_VECTOR_PRF(x)
+#define TEST_VECTOR_RNG(x)
+
+/* create test vector arrays */
+#undef TEST_VECTOR_CRYPTER
+#define TEST_VECTOR_CRYPTER(x) &x,
+static crypter_test_vector_t *crypter[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_CRYPTER
+#define TEST_VECTOR_CRYPTER(x)
+
+#undef TEST_VECTOR_SIGNER
+#define TEST_VECTOR_SIGNER(x) &x,
+static signer_test_vector_t *signer[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_SIGNER
+#define TEST_VECTOR_SIGNER(x)
+
+#undef TEST_VECTOR_HASHER
+#define TEST_VECTOR_HASHER(x) &x,
+static hasher_test_vector_t *hasher[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_HASHER
+#define TEST_VECTOR_HASHER(x)
+
+#undef TEST_VECTOR_PRF
+#define TEST_VECTOR_PRF(x) &x,
+static prf_test_vector_t *prf[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_PRF
+#define TEST_VECTOR_PRF(x)
+
+#undef TEST_VECTOR_RNG
+#define TEST_VECTOR_RNG(x) &x,
+static rng_test_vector_t *rng[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_RNG
+#define TEST_VECTOR_RNG(x)
+
+typedef struct private_test_vectors_plugin_t private_test_vectors_plugin_t;
+
+/**
+ * private data of test_vectors_plugin
+ */
+struct private_test_vectors_plugin_t {
+
+ /**
+ * public functions
+ */
+ test_vectors_plugin_t public;
+};
+
+/**
+ * Implementation of test_vectors_plugin_t.test_vectorstroy
+ */
+static void destroy(private_test_vectors_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+ private_test_vectors_plugin_t *this = malloc_thing(private_test_vectors_plugin_t);
+ int i;
+
+ this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ for (i = 0; i < countof(crypter); i++)
+ {
+ lib->crypto->add_test_vector(lib->crypto,
+ ENCRYPTION_ALGORITHM, crypter[i]);
+ }
+ for (i = 0; i < countof(signer); i++)
+ {
+ lib->crypto->add_test_vector(lib->crypto,
+ INTEGRITY_ALGORITHM, signer[i]);
+ }
+ for (i = 0; i < countof(hasher); i++)
+ {
+ lib->crypto->add_test_vector(lib->crypto,
+ HASH_ALGORITHM, hasher[i]);
+ }
+ for (i = 0; i < countof(prf); i++)
+ {
+ lib->crypto->add_test_vector(lib->crypto,
+ PSEUDO_RANDOM_FUNCTION, prf[i]);
+ }
+ for (i = 0; i < countof(rng); i++)
+ {
+ lib->crypto->add_test_vector(lib->crypto,
+ RANDOM_NUMBER_GENERATOR, rng[i]);
+ }
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.h b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.h
new file mode 100644
index 000000000..9cb959c88
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * 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 test_vectors_p test_vectors
+ * @ingroup plugins
+ *
+ * @defgroup test_vectors_plugin test_vectors_plugin
+ * @{ @ingroup test_vectors_p
+ */
+
+#ifndef TEST_VECTORS_PLUGIN_H_
+#define TEST_VECTORS_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct test_vectors_plugin_t test_vectors_plugin_t;
+
+/**
+ * Plugin providing various crypto test vectors.
+ */
+struct test_vectors_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a test_vectors_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /** TEST_VECTORS_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 028bbd41a..0c62ad3b3 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -89,6 +89,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -111,6 +112,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -122,6 +126,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -135,6 +140,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -195,6 +202,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -206,6 +214,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -230,8 +239,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -331,7 +340,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/x509/ietf_attr_list.h b/src/libstrongswan/plugins/x509/ietf_attr_list.h
index 983c67d14..5807a899e 100644
--- a/src/libstrongswan/plugins/x509/ietf_attr_list.h
+++ b/src/libstrongswan/plugins/x509/ietf_attr_list.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index 2168f9bc7..638f96b44 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "x509_ac.h"
@@ -32,6 +30,7 @@
#include <utils/identification.h>
#include <utils/linked_list.h>
#include <credentials/certificates/x509.h>
+#include <credentials/keys/private_key.h>
extern identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob,
int level0, chunk_t *authKeySerialNumber);
@@ -780,31 +779,11 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
return FALSE;
}
}
- /* TODO: generic OID to scheme mapper? */
- switch (this->algorithm)
- {
- case OID_MD5_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_MD5;
- break;
- case OID_SHA1_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- break;
- case OID_SHA256_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
- break;
- case OID_SHA384_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
- break;
- case OID_SHA512_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
- break;
- case OID_ECDSA_WITH_SHA1:
- scheme = SIGN_ECDSA_WITH_SHA1;
- break;
- default:
- return FALSE;
- }
- if (key == NULL)
+
+ /* determine signature scheme */
+ scheme = signature_scheme_from_oid(this->algorithm);
+
+ if (scheme == SIGN_UNKNOWN || key == NULL)
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/x509/x509_ac.h b/src/libstrongswan/plugins/x509/x509_ac.h
index 5df9c5f8a..958d5c57a 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.h
+++ b/src/libstrongswan/plugins/x509/x509_ac.h
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 4c6b45394..6fe1809c2 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -16,8 +16,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_cert.c 4936 2009-03-12 18:07:32Z tobias $
*/
#define _GNU_SOURCE
@@ -37,6 +35,7 @@
#include <asn1/asn1_parser.h>
#include <asn1/pem.h>
#include <crypto/hashers/hasher.h>
+#include <credentials/keys/private_key.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
@@ -353,7 +352,7 @@ static identification_t *parse_generalName(chunk_t blob, int level0)
if (id_type != ID_ANY)
{
gn = identification_create_from_encoding(id_type, object);
- DBG2(" '%D'", gn);
+ DBG2(" '%Y'", gn);
goto end;
}
}
@@ -510,9 +509,9 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0,
/* parsing went wrong - abort */
goto end;
}
- DBG2(" '%D'", id);
+ DBG2(" '%Y'", id);
if (accessMethod == OID_OCSP &&
- asprintf(&uri, "%D", id) > 0)
+ asprintf(&uri, "%Y", id) > 0)
{
this->ocsp_uris->insert_last(this->ocsp_uris, uri);
}
@@ -619,7 +618,7 @@ static void parse_crlDistributionPoints(chunk_t blob, int level0,
{
char *uri;
- if (asprintf(&uri, "%D", id) > 0)
+ if (asprintf(&uri, "%Y", id) > 0)
{
this->crl_uris->insert_last(this->crl_uris, uri);
}
@@ -714,7 +713,7 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
case X509_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->issuer);
+ DBG2(" '%Y'", this->issuer);
break;
case X509_OBJ_NOT_BEFORE:
this->notBefore = asn1_parse_time(object, level);
@@ -724,14 +723,13 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
case X509_OBJ_SUBJECT:
this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->subject);
+ DBG2(" '%Y'", this->subject);
break;
case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
if (this->public_key == NULL)
{
- DBG1("could not create public key");
goto end;
}
break;
@@ -911,32 +909,14 @@ static bool issued_by(private_x509_cert_t *this, certificate_t *issuer)
{
return FALSE;
}
- /* TODO: generic OID to scheme mapper? */
- switch (this->algorithm)
- {
- case OID_MD5_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_MD5;
- break;
- case OID_SHA1_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- break;
- case OID_SHA256_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
- break;
- case OID_SHA384_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
- break;
- case OID_SHA512_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
- break;
- case OID_ECDSA_WITH_SHA1:
- scheme = SIGN_ECDSA_WITH_SHA1;
- break;
- default:
- return FALSE;
- }
+
+ /* get the public key of the issuer */
key = issuer->get_public_key(issuer);
- if (key == NULL)
+
+ /* determine signature scheme */
+ scheme = signature_scheme_from_oid(this->algorithm);
+
+ if (scheme == SIGN_UNKNOWN || key == NULL)
{
return FALSE;
}
@@ -1124,19 +1104,19 @@ static private_x509_cert_t* create_empty(void)
{
private_x509_cert_t *this = malloc_thing(private_x509_cert_t);
- this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
- this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
- this->public.interface.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
- this->public.interface.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
- this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
- this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
+ this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
+ this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
+ this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_issuer;
+ this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
+ this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_issuer;
+ this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
+ this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
+ this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
+ this->public.interface.interface.is_newer = (bool (*) (certificate_t*,certificate_t*))is_newer;
+ this->public.interface.interface.get_encoding = (chunk_t (*) (certificate_t*))get_encoding;
+ this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
+ this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
+ this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
this->public.interface.get_flags = (x509_flag_t (*)(x509_t*))get_flags;
this->public.interface.get_serial = (chunk_t (*)(x509_t*))get_serial;
this->public.interface.get_authKeyIdentifier = (identification_t* (*)(x509_t*))get_authKeyIdentifier;
@@ -1178,6 +1158,7 @@ static private_x509_cert_t *create_from_chunk(chunk_t chunk)
private_x509_cert_t *this = create_empty();
this->encoding = chunk;
+ this->parsed = TRUE;
if (!parse_certificate(this))
{
destroy(this);
@@ -1191,17 +1172,15 @@ static private_x509_cert_t *create_from_chunk(chunk_t chunk)
}
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (hasher != NULL)
- {
- hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
- hasher->destroy(hasher);
- }
- else
+ if (hasher == NULL)
{
- DBG1(" unable to create hash of certificate, SHA1 not supported");
+ DBG1(" unable to create hash of certificate, SHA1 not supported");
+ destroy(this);
+ return NULL;
}
+ hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
+ hasher->destroy(hasher);
- this->parsed = TRUE;
return this;
}
@@ -1316,7 +1295,7 @@ static bool generate(private_builder_t *this)
this->cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
- asn1_simple_object(ASN1_INTEGER, this->cert->serialNumber),
+ asn1_integer("c", this->cert->serialNumber),
asn1_algorithmIdentifier(this->cert->algorithm),
issuer->get_encoding(issuer),
asn1_wrap(ASN1_SEQUENCE, "mm",
@@ -1352,33 +1331,22 @@ static bool generate(private_builder_t *this)
static private_x509_cert_t *build(private_builder_t *this)
{
private_x509_cert_t *cert;
- x509_flag_t flags;
- if (this->cert && !this->cert->encoding.ptr)
+ if (this->cert)
{
- if (!this->sign_key || !this->cert ||
- !generate(this))
- {
- destroy(this->cert);
- free(this);
- return NULL;
+ this->cert->flags |= this->flags;
+ if (!this->cert->encoding.ptr)
+ { /* generate a new certificate */
+ if (!this->sign_key || !generate(this))
+ {
+ destroy(this->cert);
+ free(this);
+ return NULL;
+ }
}
}
cert = this->cert;
- flags = this->flags;
free(this);
- if (cert == NULL)
- {
- return NULL;
- }
-
- if ((flags & X509_CA) && !(cert->flags & X509_CA))
- {
- DBG1(" ca certificate must have ca basic constraint set, discarded");
- destroy(cert);
- return NULL;
- }
- cert->flags |= flags;
return cert;
}
diff --git a/src/libstrongswan/plugins/x509/x509_cert.h b/src/libstrongswan/plugins/x509/x509_cert.h
index 8dbd8050a..5ebe1567d 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.h
+++ b/src/libstrongswan/plugins/x509/x509_cert.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_cert.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index fd14dfebd..f502668cb 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_crl.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include "x509_crl.h"
@@ -226,7 +224,7 @@ static bool parse(private_x509_crl_t *this)
break;
case CRL_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->issuer);
+ DBG2(" '%Y'", this->issuer);
break;
case CRL_OBJ_THIS_UPDATE:
this->thisUpdate = asn1_parse_time(object, level);
@@ -436,31 +434,11 @@ static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
return FALSE;
}
}
- /* TODO: generic OID to scheme mapper? */
- switch (this->algorithm)
- {
- case OID_MD5_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_MD5;
- break;
- case OID_SHA1_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- break;
- case OID_SHA256_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
- break;
- case OID_SHA384_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
- break;
- case OID_SHA512_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
- break;
- case OID_ECDSA_WITH_SHA1:
- scheme = SIGN_ECDSA_WITH_SHA1;
- break;
- default:
- return FALSE;
- }
- if (key == NULL)
+
+ /* determine signature scheme */
+ scheme = signature_scheme_from_oid(this->algorithm);
+
+ if (scheme == SIGN_UNKNOWN || key == NULL)
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index 7b97b990d..4020d8d95 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_ocsp_request.c 4317 2008-09-02 11:00:13Z martin $
*/
#include "x509_ocsp_request.h"
@@ -26,6 +24,7 @@
#include <utils/linked_list.h>
#include <debug.h>
#include <credentials/certificates/x509.h>
+#include <credentials/keys/private_key.h>
#define NONCE_LEN 16
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index 6bb59d8e6..1b3187258 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_ocsp_response.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include "x509_ocsp_response.h"
@@ -523,12 +521,12 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
case BASIC_RESPONSE_ID_BY_NAME:
this->responderId = identification_create_from_encoding(
ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->responderId);
+ DBG2(" '%Y'", this->responderId);
break;
case BASIC_RESPONSE_ID_BY_KEY:
this->responderId = identification_create_from_encoding(
ID_PUBKEY_INFO_SHA1, object);
- DBG2(" '%D'", this->responderId);
+ DBG2(" '%Y'", this->responderId);
break;
case BASIC_RESPONSE_PRODUCED_AT:
this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
@@ -726,32 +724,14 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
{
return FALSE;
}
- /* TODO: generic OID to scheme mapper? */
- switch (this->signatureAlgorithm)
- {
- case OID_MD5_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_MD5;
- break;
- case OID_SHA1_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
- break;
- case OID_SHA256_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
- break;
- case OID_SHA384_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
- break;
- case OID_SHA512_WITH_RSA:
- scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
- break;
- case OID_ECDSA_WITH_SHA1:
- scheme = SIGN_ECDSA_WITH_SHA1;
- break;
- default:
- return FALSE;
- }
+
+ /* get the public key of the issuer */
key = issuer->get_public_key(issuer);
- if (key == NULL)
+
+ /* determine signature scheme */
+ scheme = signature_scheme_from_oid(this->signatureAlgorithm);
+
+ if (scheme == SIGN_UNKNOWN || key == NULL)
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
index 42768487d..9ed7f95bd 100644
--- a/src/libstrongswan/plugins/x509/x509_plugin.c
+++ b/src/libstrongswan/plugins/x509/x509_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: x509_plugin.c 3640 2008-03-21 10:52:11Z andreas $
*/
#include "x509_plugin.h"
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index 48c6ef954..82ef55bd5 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -88,6 +88,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -110,6 +111,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -121,6 +125,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -134,6 +139,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -194,6 +201,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -205,6 +213,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -224,8 +233,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -322,7 +331,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
index ab37eca40..dd63af005 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General xcbc License
* for more details.
- *
- * $Id: xcbc.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
index f1501476f..25f59c650 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "xcbc_plugin.h"
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_prf.c b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
index 03056594d..a90f2d44f 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc_prf.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc_prf.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "xcbc_prf.h"
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_signer.c b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
index 29eb2d25b..b394bb251 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc_signer.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc_signer.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <string.h>
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c
index ceace27da..692ad9cf8 100644
--- a/src/libstrongswan/printf_hook.c
+++ b/src/libstrongswan/printf_hook.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: printf_hook.c 4975 2009-03-19 08:54:39Z martin $
*/
#include "printf_hook.h"
@@ -62,7 +60,7 @@ struct printf_hook_handler_t {
*/
int argtypes[ARGS_MAX];
-#ifndef HAVE_PRINTF_HOOKS
+#ifdef USE_VSTR
/**
* name required for Vstr
*/
@@ -77,7 +75,7 @@ static printf_hook_handler_t *printf_hooks[NUM_HANDLERS];
#define SPEC_TO_INDEX(spec) ((int)(spec) - (int)'A')
#define IS_VALID_SPEC(spec) (SPEC_TO_INDEX(spec) > -1 && SPEC_TO_INDEX(spec) < NUM_HANDLERS)
-#ifdef HAVE_PRINTF_HOOKS
+#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR)
/**
* Printf hook print function. This is actually of type "printf_function",
@@ -165,7 +163,7 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
}
/**
- * Add a custom format handler to the given Vstr_conf object
+ * Add a custom format handler to the given Vstr_conf object
*/
static void vstr_fmt_add_handler(Vstr_conf *conf, printf_hook_handler_t *handler)
{
@@ -340,7 +338,7 @@ static void add_handler(private_printf_hook_t *this, char spec,
return;
}
- handler = malloc_thing(printf_hook_handler_t);
+ handler = malloc_thing(printf_hook_handler_t);
handler->hook = hook;
va_start(args, hook);
@@ -361,7 +359,7 @@ static void add_handler(private_printf_hook_t *this, char spec,
if (handler->numargs > 0)
{
-#ifdef HAVE_PRINTF_HOOKS
+#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR)
register_printf_function(spec, custom_print, custom_arginfo);
#else
Vstr_conf *conf = get_vstr_conf();
@@ -384,7 +382,7 @@ static void add_handler(private_printf_hook_t *this, char spec,
static void destroy(private_printf_hook_t *this)
{
int i;
-#ifndef HAVE_PRINTF_HOOKS
+#ifdef USE_VSTR
Vstr_conf *conf = get_vstr_conf();
#endif
@@ -393,7 +391,7 @@ static void destroy(private_printf_hook_t *this)
printf_hook_handler_t *handler = printf_hooks[i];
if (handler)
{
-#ifndef HAVE_PRINTF_HOOKS
+#ifdef USE_VSTR
vstr_fmt_del(conf, handler->name);
free(handler->name);
#endif
@@ -401,7 +399,7 @@ static void destroy(private_printf_hook_t *this)
}
}
-#ifndef HAVE_PRINTF_HOOKS
+#ifdef USE_VSTR
/* freeing the Vstr_conf of the main thread */
pthread_key_delete(vstr_conf_key);
vstr_free_conf(conf);
@@ -422,7 +420,7 @@ printf_hook_t *printf_hook_create()
memset(printf_hooks, 0, sizeof(printf_hooks));
-#ifndef HAVE_PRINTF_HOOKS
+#ifdef USE_VSTR
if (!vstr_init())
{
DBG1("failed to initialize Vstr library!");
diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h
index a82c1583c..02c973580 100644
--- a/src/libstrongswan/printf_hook.h
+++ b/src/libstrongswan/printf_hook.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: printf_hook.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -28,12 +26,13 @@ typedef struct printf_hook_t printf_hook_t;
typedef struct printf_hook_spec_t printf_hook_spec_t;
typedef enum printf_hook_argtype_t printf_hook_argtype_t;
-#ifdef HAVE_PRINTF_HOOKS
+#if defined(HAVE_PRINTF_HOOKS) && !defined(USE_VSTR)
+#include <stdio.h>
#include <printf.h>
enum printf_hook_argtype_t {
- PRINTF_HOOK_ARGTYPE_END = PA_LAST,
+ PRINTF_HOOK_ARGTYPE_END = -1,
PRINTF_HOOK_ARGTYPE_INT = PA_INT,
PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
};
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
index a02823ba0..64ac09299 100644
--- a/src/libstrongswan/settings.c
+++ b/src/libstrongswan/settings.c
@@ -11,12 +11,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
#include <string.h>
+#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
@@ -213,17 +212,17 @@ static bool get_bool(private_settings_t *this, char *key, bool def, ...)
va_end(args);
if (value)
{
- if (strcasecmp(value, "true") == 0 ||
- strcasecmp(value, "enabled") == 0 ||
- strcasecmp(value, "yes") == 0 ||
- strcasecmp(value, "1") == 0)
+ if (strcaseeq(value, "true") ||
+ strcaseeq(value, "enabled") ||
+ strcaseeq(value, "yes") ||
+ strcaseeq(value, "1"))
{
return TRUE;
}
- else if (strcasecmp(value, "false") == 0 ||
- strcasecmp(value, "disabled") == 0 ||
- strcasecmp(value, "no") == 0 ||
- strcasecmp(value, "0") == 0)
+ else if (strcaseeq(value, "false") ||
+ strcaseeq(value, "disabled") ||
+ strcaseeq(value, "no") ||
+ strcaseeq(value, "0"))
{
return FALSE;
}
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
index c487f7775..1816787ae 100644
--- a/src/libstrongswan/settings.h
+++ b/src/libstrongswan/settings.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
@@ -25,7 +23,7 @@
typedef struct settings_t settings_t;
-#include <library.h>
+#include <utils.h>
#include <utils/enumerator.h>
/**
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index be0e8e9e5..4a0eff45f 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: utils.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include "utils.h"
@@ -22,6 +20,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+#include <limits.h>
#include <dirent.h>
#include <time.h>
@@ -148,6 +147,22 @@ void *return_null()
}
/**
+ * returns TRUE
+ */
+bool return_true()
+{
+ return TRUE;
+}
+
+/**
+ * returns FALSE
+ */
+bool return_false()
+{
+ return FALSE;
+}
+
+/**
* nop operation
*/
void nop()
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
index b740e7473..debd0145b 100644
--- a/src/libstrongswan/utils.h
+++ b/src/libstrongswan/utils.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: utils.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -51,6 +49,11 @@
#define strneq(x,y,len) (strncmp(x, y, len) == 0)
/**
+ * Macro compares two strings for equality ignoring case
+ */
+#define strcaseeq(x,y) (strcasecmp(x, y) == 0)
+
+/**
* Macro compares two binary blobs for equality
*/
#define memeq(x,y,len) (memcmp(x, y, len) == 0)
@@ -113,12 +116,22 @@
/**
* General purpose boolean type.
*/
-typedef int bool;
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# ifndef HAVE__BOOL
+# define _Bool signed char
+# endif /* HAVE__BOOL */
+# define bool _Bool
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif /* HAVE_STDBOOL_H */
#ifndef FALSE
-# define FALSE 0
+# define FALSE false
#endif /* FALSE */
#ifndef TRUE
-# define TRUE 1
+# define TRUE true
#endif /* TRUE */
typedef enum status_t status_t;
@@ -250,6 +263,16 @@ void *return_null();
void nop();
/**
+ * returns TRUE
+ */
+bool return_true();
+
+/**
+ * returns FALSE
+ */
+bool return_false();
+
+/**
* Special type to count references
*/
typedef volatile u_int refcount_t;
diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c
index 3caafdc38..f110521af 100644
--- a/src/libstrongswan/utils/backtrace.c
+++ b/src/libstrongswan/utils/backtrace.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -25,6 +23,8 @@
# include <execinfo.h>
#endif /* HAVE_BACKTRACE */
+#include <string.h>
+
#include "backtrace.h"
typedef struct private_backtrace_t private_backtrace_t;
diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c
index e7653a9b2..24bafe66a 100644
--- a/src/libstrongswan/utils/enumerator.c
+++ b/src/libstrongswan/utils/enumerator.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: enumerator.c 4744 2008-12-03 10:03:59Z tobias $
*/
#include "enumerator.h"
@@ -21,9 +19,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <limits.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
+#include <string.h>
#include <debug.h>
diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h
index 98f300609..4367d0836 100644
--- a/src/libstrongswan/utils/enumerator.h
+++ b/src/libstrongswan/utils/enumerator.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: enumerator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -25,7 +23,7 @@
typedef struct enumerator_t enumerator_t;
-#include <library.h>
+#include <utils.h>
/**
* Enumerate is simpler, but more flexible than iterator.
diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c
index 27a7a66c1..6d33d023b 100644
--- a/src/libstrongswan/utils/hashtable.c
+++ b/src/libstrongswan/utils/hashtable.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hashtable.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <utils/linked_list.h>
diff --git a/src/libstrongswan/utils/hashtable.h b/src/libstrongswan/utils/hashtable.h
index 28804caf8..cbe51f557 100644
--- a/src/libstrongswan/utils/hashtable.h
+++ b/src/libstrongswan/utils/hashtable.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: hashtable.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index a40c42c49..484de5e54 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -14,8 +14,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: host.c 4977 2009-03-19 09:16:03Z martin $
*/
#define _GNU_SOURCE
@@ -34,7 +32,7 @@ typedef struct private_host_t private_host_t;
/**
* Private Data of a host object.
*/
-struct private_host_t {
+struct private_host_t {
/**
* Public data
*/
@@ -81,7 +79,7 @@ static socklen_t *get_sockaddr_len(private_host_t *this)
*/
static bool is_anyaddr(private_host_t *this)
{
- switch (this->address.sa_family)
+ switch (this->address.sa_family)
{
case AF_INET:
{
@@ -100,7 +98,7 @@ static bool is_anyaddr(private_host_t *this)
default:
{
return FALSE;
- }
+ }
}
}
@@ -171,7 +169,7 @@ static chunk_t get_address(private_host_t *this)
{
chunk_t address = chunk_empty;
- switch (this->address.sa_family)
+ switch (this->address.sa_family)
{
case AF_INET:
{
@@ -206,7 +204,7 @@ static int get_family(private_host_t *this)
*/
static u_int16_t get_port(private_host_t *this)
{
- switch (this->address.sa_family)
+ switch (this->address.sa_family)
{
case AF_INET:
{
@@ -342,7 +340,7 @@ static void destroy(private_host_t *this)
}
/**
- * Creates an empty host_t object
+ * Creates an empty host_t object
*/
static private_host_t *host_create_empty(void)
{
@@ -438,9 +436,12 @@ host_t *host_create_from_string(char *string, u_int16_t port)
host_t *host_create_from_dns(char *string, int af, u_int16_t port)
{
private_host_t *this;
- struct hostent host, *ptr;
+ struct hostent *ptr;
+ int ret = 0, err;
+#ifdef HAVE_GETHOSTBYNAME_R
+ struct hostent host;
char buf[512];
- int err, ret;
+#endif
if (streq(string, "%any"))
{
@@ -455,37 +456,49 @@ host_t *host_create_from_dns(char *string, int af, u_int16_t port)
/* gethostbyname does not like IPv6 addresses - fallback */
return host_create_from_string(string, port);
}
-
+
+#ifdef HAVE_GETHOSTBYNAME_R
if (af)
- {
+ {
ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err);
}
else
{
ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err);
}
- if (ret != 0)
+#else
+ /* Some systems (e.g. Mac OS X) do not support gethostbyname_r */
+ if (af)
+ {
+ ptr = gethostbyname2(string, af);
+ }
+ else
{
- DBG1("resolving '%s' failed: %s", string, hstrerror(err));
- return NULL;
+ ptr = gethostbyname(string);
}
if (ptr == NULL)
{
- DBG1("resolving '%s' failed", string);
+ err = h_errno;
+ }
+#endif
+ if (ret != 0 || ptr == NULL)
+ {
+ DBG1("resolving '%s' failed: %s", string, hstrerror(err));
+ return NULL;
}
this = host_create_empty();
- this->address.sa_family = host.h_addrtype;
+ this->address.sa_family = ptr->h_addrtype;
switch (this->address.sa_family)
{
case AF_INET:
memcpy(&this->address4.sin_addr.s_addr,
- host.h_addr_list[0], host.h_length);
+ ptr->h_addr_list[0], ptr->h_length);
this->address4.sin_port = htons(port);
this->socklen = sizeof(struct sockaddr_in);
break;
case AF_INET6:
memcpy(&this->address6.sin6_addr.s6_addr,
- host.h_addr_list[0], host.h_length);
+ ptr->h_addr_list[0], ptr->h_length);
this->address6.sin6_port = htons(port);
this->socklen = sizeof(struct sockaddr_in6);
break;
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index bce6b1cc2..1c04c97ef 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: identification.c 5036 2009-03-26 13:25:46Z martin $
*/
#define _GNU_SOURCE
@@ -59,110 +57,42 @@ ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_CERT_DER_SHA1, ID_KEY_ID,
ENUM_END(id_type_names, ID_CERT_DER_SHA1);
/**
- * X.501 acronyms for well known object identifiers (OIDs)
- */
-static u_char oid_ND[] = {
- 0x02, 0x82, 0x06, 0x01, 0x0A, 0x07, 0x14
-};
-static u_char oid_UID[] = {
- 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x01
-};
-static u_char oid_DC[] = {
- 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19
-};
-static u_char oid_CN[] = {
- 0x55, 0x04, 0x03
-};
-static u_char oid_S[] = {
- 0x55, 0x04, 0x04
-};
-static u_char oid_SN[] = {
- 0x55, 0x04, 0x05
-};
-static u_char oid_C[] = {
- 0x55, 0x04, 0x06
-};
-static u_char oid_L[] = {
- 0x55, 0x04, 0x07
-};
-static u_char oid_ST[] = {
- 0x55, 0x04, 0x08
-};
-static u_char oid_O[] = {
- 0x55, 0x04, 0x0A
-};
-static u_char oid_OU[] = {
- 0x55, 0x04, 0x0B
-};
-static u_char oid_T[] = {
- 0x55, 0x04, 0x0C
-};
-static u_char oid_D[] = {
- 0x55, 0x04, 0x0D
-};
-static u_char oid_N[] = {
- 0x55, 0x04, 0x29
-};
-static u_char oid_G[] = {
- 0x55, 0x04, 0x2A
-};
-static u_char oid_I[] = {
- 0x55, 0x04, 0x2B
-};
-static u_char oid_ID[] = {
- 0x55, 0x04, 0x2D
-};
-static u_char oid_EN[] = {
- 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x42, 0x03, 0x01, 0x03
-};
-static u_char oid_E[] = {
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01
-};
-static u_char oid_UN[] = {
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x02
-};
-static u_char oid_TCGID[] = {
- 0x2B, 0x06, 0x01, 0x04, 0x01, 0x89, 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B
-};
-
-/**
* coding of X.501 distinguished name
*/
typedef struct {
const u_char *name;
- chunk_t oid;
+ int oid;
u_char type;
} x501rdn_t;
static const x501rdn_t x501rdns[] = {
- {"ND", {oid_ND, 7}, ASN1_PRINTABLESTRING},
- {"UID", {oid_UID, 10}, ASN1_PRINTABLESTRING},
- {"DC", {oid_DC, 10}, ASN1_PRINTABLESTRING},
- {"CN", {oid_CN, 3}, ASN1_PRINTABLESTRING},
- {"S", {oid_S, 3}, ASN1_PRINTABLESTRING},
- {"SN", {oid_SN, 3}, ASN1_PRINTABLESTRING},
- {"serialNumber", {oid_SN, 3}, ASN1_PRINTABLESTRING},
- {"C", {oid_C, 3}, ASN1_PRINTABLESTRING},
- {"L", {oid_L, 3}, ASN1_PRINTABLESTRING},
- {"ST", {oid_ST, 3}, ASN1_PRINTABLESTRING},
- {"O", {oid_O, 3}, ASN1_PRINTABLESTRING},
- {"OU", {oid_OU, 3}, ASN1_PRINTABLESTRING},
- {"T", {oid_T, 3}, ASN1_PRINTABLESTRING},
- {"D", {oid_D, 3}, ASN1_PRINTABLESTRING},
- {"N", {oid_N, 3}, ASN1_PRINTABLESTRING},
- {"G", {oid_G, 3}, ASN1_PRINTABLESTRING},
- {"I", {oid_I, 3}, ASN1_PRINTABLESTRING},
- {"ID", {oid_ID, 3}, ASN1_PRINTABLESTRING},
- {"EN", {oid_EN, 10}, ASN1_PRINTABLESTRING},
- {"employeeNumber", {oid_EN, 10}, ASN1_PRINTABLESTRING},
- {"E", {oid_E, 9}, ASN1_IA5STRING},
- {"Email", {oid_E, 9}, ASN1_IA5STRING},
- {"emailAddress", {oid_E, 9}, ASN1_IA5STRING},
- {"UN", {oid_UN, 9}, ASN1_IA5STRING},
- {"unstructuredName",{oid_UN, 9}, ASN1_IA5STRING},
- {"TCGID", {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
+ {"ND", OID_NAME_DISTINGUISHER, ASN1_PRINTABLESTRING},
+ {"UID", OID_PILOT_USERID, ASN1_PRINTABLESTRING},
+ {"DC", OID_PILOT_DOMAIN_COMPONENT, ASN1_PRINTABLESTRING},
+ {"CN", OID_COMMON_NAME, ASN1_PRINTABLESTRING},
+ {"S", OID_SURNAME, ASN1_PRINTABLESTRING},
+ {"SN", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
+ {"serialNumber", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
+ {"C", OID_COUNTRY, ASN1_PRINTABLESTRING},
+ {"L", OID_LOCALITY, ASN1_PRINTABLESTRING},
+ {"ST", OID_STATE_OR_PROVINCE, ASN1_PRINTABLESTRING},
+ {"O", OID_ORGANIZATION, ASN1_PRINTABLESTRING},
+ {"OU", OID_ORGANIZATION_UNIT, ASN1_PRINTABLESTRING},
+ {"T", OID_TITLE, ASN1_PRINTABLESTRING},
+ {"D", OID_DESCRIPTION, ASN1_PRINTABLESTRING},
+ {"N", OID_NAME, ASN1_PRINTABLESTRING},
+ {"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
+ {"I", OID_INITIALS, ASN1_PRINTABLESTRING},
+ {"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
+ {"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
+ {"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
+ {"E", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
+ {"Email", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
+ {"emailAddress", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
+ {"UN", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
+ {"unstructuredName",OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
+ {"TCGID", OID_TCGID, ASN1_PRINTABLESTRING}
};
-#define X501_RDN_ROOF 26
/**
* maximum number of RDNs in atodn()
@@ -208,34 +138,22 @@ static void update_chunk(chunk_t *ch, int n)
* Remove any malicious characters from a chunk. We are very restrictive, but
* whe use these strings only to present it to the user.
*/
-static chunk_t sanitize_chunk(chunk_t chunk)
+static bool sanitize_chunk(chunk_t chunk, chunk_t *clone)
{
char *pos;
- chunk_t clone = chunk_clone(chunk);
+ bool all_printable = TRUE;
+
+ *clone = chunk_clone(chunk);
- for (pos = clone.ptr; pos < (char*)(clone.ptr + clone.len); pos++)
+ for (pos = clone->ptr; pos < (char*)(clone->ptr + clone->len); pos++)
{
- switch (*pos)
+ if (!isprint(*pos))
{
- case '\0':
- case ' ':
- case '*':
- case '-':
- case '.':
- case '/':
- case '0' ... '9':
- case ':':
- case '=':
- case '@':
- case 'A' ... 'Z':
- case '_':
- case 'a' ... 'z':
- break;
- default:
- *pos = '?';
+ *pos = '?';
+ all_printable = FALSE;
}
}
- return clone;
+ return all_printable;
}
/**
@@ -272,14 +190,15 @@ static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
/**
* Fetches the next RDN in a DN
*/
-static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
+static bool get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
+ chunk_t *value, asn1_t *type, bool *next)
{
chunk_t body;
-
+
/* initialize return values */
*oid = chunk_empty;
*value = chunk_empty;
-
+
/* if all attributes have been parsed, get next rdn */
if (attribute->len <= 0)
{
@@ -371,19 +290,19 @@ static bool dntoa(chunk_t dn, chunk_t *str)
int oid_code;
bool next;
bool first = TRUE;
-
+
if (!init_rdn(dn, &rdn, &attribute, &next))
{
return FALSE;
}
-
+
while (next)
{
if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
{
return FALSE;
}
-
+
if (first)
{ /* first OID/value pair */
first = FALSE;
@@ -392,7 +311,7 @@ static bool dntoa(chunk_t dn, chunk_t *str)
{ /* separate OID/value pair by a comma */
update_chunk(str, snprintf(str->ptr,str->len,", "));
}
-
+
/* print OID */
oid_code = asn1_known_oid(oid);
if (oid_code == OID_UNKNOWN)
@@ -404,7 +323,7 @@ static bool dntoa(chunk_t dn, chunk_t *str)
update_chunk(str, snprintf(str->ptr,str->len,"%s", oid_names[oid_code].name));
}
/* print value */
- proper = sanitize_chunk(value);
+ sanitize_chunk(value, &proper);
update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
chunk_free(&proper);
}
@@ -421,7 +340,7 @@ static bool same_dn(chunk_t a, chunk_t b)
chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b;
bool next_a, next_b;
-
+
/* same lengths for the DNs */
if (a.len != b.len)
{
@@ -438,7 +357,7 @@ static bool same_dn(chunk_t a, chunk_t b)
{
return FALSE;
}
-
+
/* fetch next RDN pair */
while (next_a && next_b)
{
@@ -448,19 +367,19 @@ static bool same_dn(chunk_t a, chunk_t b)
{
return FALSE;
}
-
+
/* OIDs must agree */
if (oid_a.len != oid_b.len || !memeq(oid_a.ptr, oid_b.ptr, oid_b.len))
{
return FALSE;
}
-
+
/* same lengths for values */
if (value_a.len != value_b.len)
{
return FALSE;
}
-
+
/* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
@@ -499,17 +418,17 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
chunk_t oid_a, oid_b, value_a, value_b;
asn1_t type_a, type_b;
bool next_a, next_b;
-
+
/* initialize wildcard counter */
*wildcards = 0;
-
+
/* initialize DN parsing */
if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
!init_rdn(b, &rdn_b, &attribute_b, &next_b))
{
return FALSE;
}
-
+
/* fetch next RDN pair */
while (next_a && next_b)
{
@@ -524,7 +443,7 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
-
+
/* does rdn_b contain a wildcard? */
if (value_b.len == 1 && *value_b.ptr == '*')
{
@@ -536,7 +455,7 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
return FALSE;
}
-
+
/* printableStrings and email RDNs require uppercase comparison */
if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
(type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
@@ -609,15 +528,18 @@ static status_t atodn(char *src, chunk_t *dn)
}
else
{
- for (i = 0; i < X501_RDN_ROOF; i++)
+ bool found = FALSE;
+
+ for (i = 0; i < countof(x501rdns); i++)
{
- if (strlen(x501rdns[i].name) == oid.len
- && strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0)
+ if (strlen(x501rdns[i].name) == oid.len &&
+ strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0)
{
- break; /* found a valid OID */
+ found = TRUE;
+ break;
}
}
- if (i == X501_RDN_ROOF)
+ if (!found)
{
status = NOT_SUPPORTED;
state = UNKNOWN_OID;
@@ -655,14 +577,24 @@ static status_t atodn(char *src, chunk_t *dn)
if (rdn_count < RDN_MAX)
{
- rdns[rdn_count] =
- asn1_wrap(ASN1_SET, "m",
- asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_OID, "c", x501rdns[i].oid),
- asn1_wrap(rdn_type, "c", name)
- )
- );
- dn_len += rdns[rdn_count++].len;
+ chunk_t rdn_oid;
+
+ rdn_oid = asn1_build_known_oid(x501rdns[i].oid);
+ if (rdn_oid.len)
+ {
+ rdns[rdn_count] =
+ asn1_wrap(ASN1_SET, "m",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ rdn_oid,
+ asn1_wrap(rdn_type, "c", name)
+ )
+ );
+ dn_len += rdns[rdn_count++].len;
+ }
+ else
+ {
+ status = INVALID_ARG;
+ }
}
else
{
@@ -677,12 +609,12 @@ static status_t atodn(char *src, chunk_t *dn)
break;
}
} while (*src++ != '\0');
-
+
/* build the distinguished name sequence */
- {
+ {
int i;
u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
-
+
for (i = 0; i < rdn_count; i++)
{
memcpy(pos, rdns[i].ptr, rdns[i].len);
@@ -690,7 +622,7 @@ static status_t atodn(char *src, chunk_t *dn)
free(rdns[i].ptr);
}
}
-
+
if (status != SUCCESS)
{
free(dn->ptr);
@@ -945,9 +877,8 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
case ID_FQDN:
case ID_RFC822_ADDR:
case ID_DER_ASN1_GN_URI:
- case ID_EAP:
case ID_IETF_ATTR_STRING:
- proper = sanitize_chunk(this->encoded);
+ sanitize_chunk(this->encoded, &proper);
snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
chunk_free(&proper);
break;
@@ -961,6 +892,16 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
snprintf(buf, sizeof(buf), "(ASN.1 general Name");
break;
case ID_KEY_ID:
+ if (sanitize_chunk(this->encoded, &proper))
+ { /* fully printable, use ascii version */
+ snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
+ }
+ else
+ { /* not printable, hex dump */
+ snprintf(buf, sizeof(buf), "%#B", &this->encoded);
+ }
+ chunk_free(&proper);
+ break;
case ID_PUBKEY_INFO_SHA1:
case ID_PUBKEY_SHA1:
case ID_CERT_DER_SHA1:
@@ -978,6 +919,124 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
}
/**
+ * Enumerator over RDNs
+ */
+typedef struct {
+ /* implements enumerator interface */
+ enumerator_t public;
+ /* current RDN */
+ chunk_t rdn;
+ /* current attribute */
+ chunk_t attr;
+ /** have another RDN? */
+ bool next;
+} rdn_enumerator_t;
+
+/**
+ * Implementation of rdn_enumerator_t.enumerate
+ */
+static bool rdn_enumerate(rdn_enumerator_t *this,
+ id_part_t *type, chunk_t *data)
+{
+ chunk_t oid, value;
+ asn1_t asn1_type;
+
+ while (this->next)
+ {
+ if (!get_next_rdn(&this->rdn, &this->attr, &oid,
+ &value, &asn1_type, &this->next))
+ {
+ return FALSE;
+ }
+ switch (asn1_known_oid(oid))
+ {
+ case OID_COMMON_NAME:
+ *type = ID_PART_RDN_CN;
+ break;
+ case OID_SURNAME:
+ *type = ID_PART_RDN_S;
+ break;
+ case OID_SERIAL_NUMBER:
+ *type = ID_PART_RDN_SN;
+ break;
+ case OID_COUNTRY:
+ *type = ID_PART_RDN_C;
+ break;
+ case OID_LOCALITY:
+ *type = ID_PART_RDN_L;
+ break;
+ case OID_STATE_OR_PROVINCE:
+ *type = ID_PART_RDN_ST;
+ break;
+ case OID_ORGANIZATION:
+ *type = ID_PART_RDN_O;
+ break;
+ case OID_ORGANIZATION_UNIT:
+ *type = ID_PART_RDN_OU;
+ break;
+ case OID_TITLE:
+ *type = ID_PART_RDN_T;
+ break;
+ case OID_DESCRIPTION:
+ *type = ID_PART_RDN_D;
+ break;
+ case OID_NAME:
+ *type = ID_PART_RDN_N;
+ break;
+ case OID_GIVEN_NAME:
+ *type = ID_PART_RDN_G;
+ break;
+ case OID_INITIALS:
+ *type = ID_PART_RDN_I;
+ break;
+ case OID_UNIQUE_IDENTIFIER:
+ *type = ID_PART_RDN_ID;
+ break;
+ case OID_EMAIL_ADDRESS:
+ *type = ID_PART_RDN_E;
+ break;
+ case OID_EMPLOYEE_NUMBER:
+ *type = ID_PART_RDN_EN;
+ break;
+ default:
+ continue;
+ }
+ *data = value;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of identification_t.create_part_enumerator
+ */
+static enumerator_t* create_part_enumerator(private_identification_t *this)
+{
+ switch (this->type)
+ {
+ case ID_DER_ASN1_DN:
+ {
+ rdn_enumerator_t *e = malloc_thing(rdn_enumerator_t);
+
+ e->public.enumerate = (void*)rdn_enumerate;
+ e->public.destroy = (void*)free;
+ if (init_rdn(this->encoded, &e->rdn, &e->attr, &e->next))
+ {
+ return &e->public;
+ }
+ free(e);
+ /* FALL */
+ }
+ case ID_RFC822_ADDR:
+ /* TODO */
+ case ID_FQDN:
+ /* TODO */
+ default:
+ return enumerator_create_empty();
+ }
+}
+
+/**
* Implementation of identification_t.clone.
*/
static identification_t *clone_(private_identification_t *this)
@@ -1014,6 +1073,7 @@ static private_identification_t *identification_create(void)
this->public.get_encoding = (chunk_t (*) (identification_t*))get_encoding;
this->public.get_type = (id_type_t (*) (identification_t*))get_type;
this->public.contains_wildcards = (bool (*) (identification_t *this))contains_wildcards;
+ this->public.create_part_enumerator = (enumerator_t*(*)(identification_t*))create_part_enumerator;
this->public.clone = (identification_t* (*) (identification_t*))clone_;
this->public.destroy = (void (*) (identification_t*))destroy;
/* we use these as defaults, the may be overloaded for special ID types */
@@ -1043,8 +1103,9 @@ identification_t *identification_create_from_string(char *string)
*/
if (atodn(string, &this->encoded) != SUCCESS)
{
- free(this);
- return NULL;
+ this->type = ID_KEY_ID;
+ this->encoded = chunk_clone(chunk_create(string, strlen(string)));
+ return &this->public;
}
this->type = ID_DER_ASN1_DN;
this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn;
@@ -1084,11 +1145,11 @@ identification_t *identification_create_from_string(char *string)
(identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
- return &(this->public);
+ return &this->public;
}
this->encoded = chunk_clone(chunk);
this->type = ID_IPV4_ADDR;
- return &(this->public);
+ return &this->public;
}
else
{
@@ -1098,12 +1159,14 @@ identification_t *identification_create_from_string(char *string)
if (inet_pton(AF_INET6, string, &address) <= 0)
{
- free(this);
- return NULL;
+ this->type = ID_KEY_ID;
+ this->encoded = chunk_clone(chunk_create(string,
+ strlen(string)));
+ return &this->public;
}
this->encoded = chunk_clone(chunk);
this->type = ID_IPV6_ADDR;
- return &(this->public);
+ return &this->public;
}
}
}
@@ -1117,7 +1180,7 @@ identification_t *identification_create_from_string(char *string)
this->type = ID_KEY_ID;
this->encoded = chunk_from_hex(
chunk_create(string, strlen(string)), NULL);
- return &(this->public);
+ return &this->public;
}
else
{
@@ -1128,7 +1191,7 @@ identification_t *identification_create_from_string(char *string)
(identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
- return &(this->public);
+ return &this->public;
}
}
else
@@ -1140,7 +1203,7 @@ identification_t *identification_create_from_string(char *string)
(identification_t*,identification_t*))matches_string;
this->public.equals = (bool (*)
(identification_t*,identification_t*))equals_strcasecmp;
- return &(this->public);
+ return &this->public;
}
}
}
@@ -1180,7 +1243,6 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
case ID_PUBKEY_INFO_SHA1:
case ID_PUBKEY_SHA1:
case ID_CERT_DER_SHA1:
- case ID_EAP:
case ID_IETF_ATTR_STRING:
default:
break;
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index 2284b7b46..dc0aec18e 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: identification.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -29,6 +27,7 @@
typedef enum id_type_t id_type_t;
typedef struct identification_t identification_t;
typedef enum id_match_t id_match_t;
+typedef enum id_part_t id_part_t;
#include <library.h>
@@ -80,7 +79,8 @@ enum id_type_t {
* An example of an ID_RFC822_ADDR is "jsmith@example.com".
* The string MUST NOT contain any terminators.
*/
- ID_RFC822_ADDR = 3,
+ ID_USER_FQDN = 3, /* IKEv1 only */
+ ID_RFC822_ADDR = 3, /* IKEv2 only */
/**
* ID data is an IPv4 subnet (IKEv1 only)
@@ -143,16 +143,16 @@ enum id_type_t {
* SHA1 hash of the binary DER encoding of a certificate
*/
ID_CERT_DER_SHA1 = 204,
-
+
/**
- * Generic EAP identity
+ * IETF Attribute Syntax String (RFC 3281)
*/
- ID_EAP = 205,
+ ID_IETF_ATTR_STRING = 205,
/**
- * IETF Attribute Syntax String (RFC 3281)
+ * Private ID used by the pluto daemon for opportunistic encryption
*/
- ID_IETF_ATTR_STRING = 206,
+ ID_MYID = 206,
};
/**
@@ -161,6 +161,56 @@ enum id_type_t {
extern enum_name_t *id_type_names;
/**
+ * Type of an ID sub part.
+ */
+enum id_part_t {
+ /** Username part of an RFC822_ADDR */
+ ID_PART_USERNAME,
+ /** Domain part of an RFC822_ADDR */
+ ID_PART_DOMAIN,
+
+ /** Top-Level domain of a FQDN */
+ ID_PART_TLD,
+ /** Second-Level domain of a FQDN */
+ ID_PART_SLD,
+ /** Another Level domain of a FQDN */
+ ID_PART_ALD,
+
+ /** Country RDN of a DN */
+ ID_PART_RDN_C,
+ /** CommonName RDN of a DN */
+ ID_PART_RDN_CN,
+ /** Description RDN of a DN */
+ ID_PART_RDN_D,
+ /** Email RDN of a DN */
+ ID_PART_RDN_E,
+ /** EmployeeNumber RDN of a DN */
+ ID_PART_RDN_EN,
+ /** GivenName RDN of a DN */
+ ID_PART_RDN_G,
+ /** Initials RDN of a DN */
+ ID_PART_RDN_I,
+ /** UniqueIdentifier RDN of a DN */
+ ID_PART_RDN_ID,
+ /** Locality RDN of a DN */
+ ID_PART_RDN_L,
+ /** Name RDN of a DN */
+ ID_PART_RDN_N,
+ /** Organization RDN of a DN */
+ ID_PART_RDN_O,
+ /** OrganizationUnit RDN of a DN */
+ ID_PART_RDN_OU,
+ /** Surname RDN of a DN */
+ ID_PART_RDN_S,
+ /** SerialNumber RDN of a DN */
+ ID_PART_RDN_SN,
+ /** StateOrProvince RDN of a DN */
+ ID_PART_RDN_ST,
+ /** Title RDN of a DN */
+ ID_PART_RDN_T,
+};
+
+/**
* Generic identification, such as used in ID payload.
*
* @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison
@@ -225,6 +275,19 @@ struct identification_t {
bool (*contains_wildcards) (identification_t *this);
/**
+ * Create an enumerator over subparts of an identity.
+ *
+ * Some identities are built from several parts, e.g. an E-Mail consists
+ * of a username and a domain part, or a DistinguishedName contains several
+ * RDNs.
+ * For identity without subtypes (support), an empty enumerator is
+ * returned.
+ *
+ * @return an enumerator over (id_part_t type, chunk_t data)
+ */
+ enumerator_t* (*create_part_enumerator)(identification_t *this);
+
+ /**
* Clone a identification_t instance.
*
* @return clone of this
@@ -257,16 +320,16 @@ struct identification_t {
* N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
* unstructuredName, TCGID.
*
+ * This constructor never returns NULL. If it does not find a suitable
+ * conversion function, it will copy the string to an ID_KEY_ID.
+ *
* @param string input string, which will be converted
- * @return created identification_t, NULL if not supported.
+ * @return identification_t
*/
identification_t * identification_create_from_string(char *string);
/**
* Creates an identification_t object from an encoded chunk.
- *
- * In contrast to identification_create_from_string(), this constructor never
- * returns NULL, even when the conversion to a string representation fails.
*
* @param type type of this id, such as ID_IPV4_ADDR
* @param encoded encoded bytes, such as from identification_t.get_encoding
diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h
index 02eb1b9c0..1dbf01539 100644
--- a/src/libstrongswan/utils/iterator.h
+++ b/src/libstrongswan/utils/iterator.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: iterator.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index 0e0866fec..2cac3b458 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: leak_detective.c 4936 2009-03-12 18:07:32Z tobias $
*/
#define _GNU_SOURCE
@@ -202,6 +200,11 @@ char *whitelist[] = {
"DH_new_method",
"ENGINE_load_builtin_engines",
"OPENSSL_config",
+ /* libgcrypt */
+ "gcry_control",
+ "gcry_check_version",
+ "gcry_randomize",
+ "gcry_create_nonce",
};
/**
diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c
index 5725df1ea..2472f6751 100644
--- a/src/libstrongswan/utils/lexparser.c
+++ b/src/libstrongswan/utils/lexparser.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: lexparser.c 4877 2009-02-18 09:45:54Z martin $
*/
#include "lexparser.h"
diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h
index 6ae970e1e..7e2edb278 100644
--- a/src/libstrongswan/utils/lexparser.h
+++ b/src/libstrongswan/utils/lexparser.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: lexparser.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index bfe30b0df..a45468cca 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: linked_list.c 4936 2009-03-12 18:07:32Z tobias $
*/
#include <stdlib.h>
diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h
index aa603fefa..8b2de9083 100644
--- a/src/libstrongswan/utils/linked_list.h
+++ b/src/libstrongswan/utils/linked_list.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: linked_list.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
@@ -27,7 +25,6 @@
typedef struct linked_list_t linked_list_t;
-#include <library.h>
#include <utils/iterator.h>
#include <utils/enumerator.h>
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
index ba4b72b0c..8b3a25201 100644
--- a/src/libstrongswan/utils/mutex.c
+++ b/src/libstrongswan/utils/mutex.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mutex.c 4803 2008-12-15 09:13:43Z martin $
*/
#define _GNU_SOURCE
@@ -315,7 +313,7 @@ mutex_t *mutex_create(mutex_type_t type)
/**
* Implementation of condvar_t.wait.
*/
-static void wait(private_condvar_t *this, private_mutex_t *mutex)
+static void _wait(private_condvar_t *this, private_mutex_t *mutex)
{
if (mutex->recursive)
{
@@ -389,7 +387,7 @@ static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
/**
* Implementation of condvar_t.signal.
*/
-static void signal(private_condvar_t *this)
+static void _signal(private_condvar_t *this)
{
pthread_cond_signal(&this->condvar);
}
@@ -423,10 +421,10 @@ condvar_t *condvar_create(condvar_type_t type)
{
private_condvar_t *this = malloc_thing(private_condvar_t);
- this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))wait;
+ this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))_wait;
this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
this->public.timed_wait_abs = (bool(*)(condvar_t*, mutex_t *mutex, timeval_t time))timed_wait_abs;
- this->public.signal = (void(*)(condvar_t*))signal;
+ this->public.signal = (void(*)(condvar_t*))_signal;
this->public.broadcast = (void(*)(condvar_t*))broadcast;
this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
index 46c939fb8..c5c667992 100644
--- a/src/libstrongswan/utils/mutex.h
+++ b/src/libstrongswan/utils/mutex.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: mutex.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c
index 18427e197..bf47e6b98 100644
--- a/src/libstrongswan/utils/optionsfrom.c
+++ b/src/libstrongswan/utils/optionsfrom.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
* License for more details.
- *
- * $Id: optionsfrom.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <stdio.h>
diff --git a/src/libstrongswan/utils/optionsfrom.h b/src/libstrongswan/utils/optionsfrom.h
index 9372971ca..05269f4f5 100644
--- a/src/libstrongswan/utils/optionsfrom.h
+++ b/src/libstrongswan/utils/optionsfrom.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: optionsfrom.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index bce0ead39..49376379e 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -112,6 +112,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -134,6 +135,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -145,6 +149,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -158,6 +163,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -218,6 +225,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -229,6 +237,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -293,8 +302,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -588,7 +597,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/manager/controller/auth_controller.c b/src/manager/controller/auth_controller.c
index 13031198a..5f9c3b623 100644
--- a/src/manager/controller/auth_controller.c
+++ b/src/manager/controller/auth_controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: auth_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "auth_controller.h"
diff --git a/src/manager/controller/auth_controller.h b/src/manager/controller/auth_controller.h
index e2cd48cc4..41e669fd0 100644
--- a/src/manager/controller/auth_controller.h
+++ b/src/manager/controller/auth_controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: auth_controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/controller/config_controller.c b/src/manager/controller/config_controller.c
index 1f8289c71..dda2938a1 100644
--- a/src/manager/controller/config_controller.c
+++ b/src/manager/controller/config_controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: config_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "config_controller.h"
diff --git a/src/manager/controller/config_controller.h b/src/manager/controller/config_controller.h
index 88d37424f..07cafd4ff 100644
--- a/src/manager/controller/config_controller.h
+++ b/src/manager/controller/config_controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: config_controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/controller/control_controller.c b/src/manager/controller/control_controller.c
index b3149797f..c22591182 100644
--- a/src/manager/controller/control_controller.c
+++ b/src/manager/controller/control_controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: control_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "control_controller.h"
diff --git a/src/manager/controller/control_controller.h b/src/manager/controller/control_controller.h
index 8992e5b48..c9bc1e4b3 100644
--- a/src/manager/controller/control_controller.h
+++ b/src/manager/controller/control_controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: control_controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/controller/gateway_controller.c b/src/manager/controller/gateway_controller.c
index 68fdb7021..164bf5921 100644
--- a/src/manager/controller/gateway_controller.c
+++ b/src/manager/controller/gateway_controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gateway_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "gateway_controller.h"
diff --git a/src/manager/controller/gateway_controller.h b/src/manager/controller/gateway_controller.h
index 864c7a4bd..7d77bdccb 100644
--- a/src/manager/controller/gateway_controller.h
+++ b/src/manager/controller/gateway_controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gateway_controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/controller/ikesa_controller.c b/src/manager/controller/ikesa_controller.c
index ab3a089f0..c35ff42e6 100644
--- a/src/manager/controller/ikesa_controller.c
+++ b/src/manager/controller/ikesa_controller.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ikesa_controller.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "ikesa_controller.h"
diff --git a/src/manager/controller/ikesa_controller.h b/src/manager/controller/ikesa_controller.h
index 240e8db4f..3f6779629 100644
--- a/src/manager/controller/ikesa_controller.h
+++ b/src/manager/controller/ikesa_controller.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: ikesa_controller.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/gateway.c b/src/manager/gateway.c
index e6c944873..f0d557c71 100644
--- a/src/manager/gateway.c
+++ b/src/manager/gateway.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gateway.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "gateway.h"
diff --git a/src/manager/gateway.h b/src/manager/gateway.h
index 4ba301a0f..7c76fa474 100644
--- a/src/manager/gateway.h
+++ b/src/manager/gateway.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: gateway.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/main.c b/src/manager/main.c
index e556a7415..6fef0bf3e 100644
--- a/src/manager/main.c
+++ b/src/manager/main.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: main.c 4333 2008-09-04 16:19:46Z andreas $
*/
#include <dispatcher.h>
diff --git a/src/manager/manager.c b/src/manager/manager.c
index 7d1b2adba..72f402a48 100644
--- a/src/manager/manager.c
+++ b/src/manager/manager.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: manager.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "manager.h"
diff --git a/src/manager/manager.h b/src/manager/manager.h
index ecd29550b..dc5fc1831 100644
--- a/src/manager/manager.h
+++ b/src/manager/manager.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: manager.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/storage.c b/src/manager/storage.c
index fee4c216e..00e688e08 100644
--- a/src/manager/storage.c
+++ b/src/manager/storage.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: storage.c 3917 2008-05-08 13:12:43Z martin $
*/
#include "storage.h"
diff --git a/src/manager/storage.h b/src/manager/storage.h
index 6c5bea650..2495b3a26 100644
--- a/src/manager/storage.h
+++ b/src/manager/storage.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: storage.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/manager/xml.c b/src/manager/xml.c
index 1e9731cc2..5aa2e3e1e 100644
--- a/src/manager/xml.c
+++ b/src/manager/xml.c
@@ -11,10 +11,10 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: xml.c 3589 2008-03-13 14:14:44Z martin $
*/
+#include <string.h>
+
#include "xml.h"
#include <libxml/parser.h>
diff --git a/src/manager/xml.h b/src/manager/xml.h
index febe5c25d..230e0f925 100644
--- a/src/manager/xml.h
+++ b/src/manager/xml.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id: xml.h 5003 2009-03-24 17:43:01Z martin $
*/
/**
diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in
index 89843860d..a9ef57922 100644
--- a/src/medsrv/Makefile.in
+++ b/src/medsrv/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -98,6 +98,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -120,6 +121,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -131,6 +135,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -144,6 +149,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -204,6 +211,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -215,6 +223,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -266,8 +275,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -477,7 +486,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/medsrv/controller/peer_controller.c b/src/medsrv/controller/peer_controller.c
index 22fc6df2f..0dec27698 100755
--- a/src/medsrv/controller/peer_controller.c
+++ b/src/medsrv/controller/peer_controller.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
@@ -72,7 +70,7 @@ static void list(private_peer_controller_t *this, request_t *request)
{
request->setf(request, "peers.%d.alias=%s", id, alias);
identifier = identification_create_from_encoding(ID_KEY_ID, keyid);
- request->setf(request, "peers.%d.identifier=%D", id, identifier);
+ request->setf(request, "peers.%d.identifier=%Y", id, identifier);
identifier->destroy(identifier);
}
query->destroy(query);
diff --git a/src/medsrv/controller/peer_controller.h b/src/medsrv/controller/peer_controller.h
index 511265487..f25c30281 100755
--- a/src/medsrv/controller/peer_controller.h
+++ b/src/medsrv/controller/peer_controller.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/medsrv/controller/user_controller.c b/src/medsrv/controller/user_controller.c
index 9e6d12340..bc4717e32 100755
--- a/src/medsrv/controller/user_controller.c
+++ b/src/medsrv/controller/user_controller.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#define _GNU_SOURCE
diff --git a/src/medsrv/controller/user_controller.h b/src/medsrv/controller/user_controller.h
index 897e28362..9d23795d7 100755
--- a/src/medsrv/controller/user_controller.h
+++ b/src/medsrv/controller/user_controller.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/medsrv/filter/auth_filter.c b/src/medsrv/filter/auth_filter.c
index 5036d26f1..76114a347 100755
--- a/src/medsrv/filter/auth_filter.c
+++ b/src/medsrv/filter/auth_filter.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "auth_filter.h"
diff --git a/src/medsrv/filter/auth_filter.h b/src/medsrv/filter/auth_filter.h
index 5ba270e72..f1fc565eb 100755
--- a/src/medsrv/filter/auth_filter.h
+++ b/src/medsrv/filter/auth_filter.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
/**
diff --git a/src/medsrv/main.c b/src/medsrv/main.c
index 1f7b675bb..20dec9d37 100644
--- a/src/medsrv/main.c
+++ b/src/medsrv/main.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include <stdio.h>
diff --git a/src/medsrv/user.c b/src/medsrv/user.c
index 032859e2e..d204dd057 100644
--- a/src/medsrv/user.c
+++ b/src/medsrv/user.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#include "user.h"
diff --git a/src/medsrv/user.h b/src/medsrv/user.h
index b411f7c6f..2d1c738ca 100644
--- a/src/medsrv/user.h
+++ b/src/medsrv/user.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * $Id$
*/
#ifndef USER_H_
diff --git a/src/openac/Makefile.in b/src/openac/Makefile.in
index ae05b722f..7bf71b08f 100644
--- a/src/openac/Makefile.in
+++ b/src/openac/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -84,6 +84,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -106,6 +107,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -117,6 +121,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -130,6 +135,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -190,6 +197,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -201,6 +209,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -223,8 +232,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -325,8 +334,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -365,7 +374,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/openac/openac.c b/src/openac/openac.c
index 99464a236..3686c07ac 100755
--- a/src/openac/openac.c
+++ b/src/openac/openac.c
@@ -19,8 +19,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: openac.c 4749 2008-12-04 04:34:49Z andreas $
*/
#include <stdio.h>
@@ -39,6 +37,7 @@
#include <asn1/pem.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/ac.h>
+#include <credentials/keys/private_key.h>
#include <utils/optionsfrom.h>
#ifdef INTEGRITY_TEST
@@ -218,18 +217,35 @@ static bool stderr_quiet = FALSE;
static void openac_dbg(int level, char *fmt, ...)
{
int priority = LOG_INFO;
+ char buffer[8192];
+ char *current = buffer, *next;
va_list args;
if (level <= debug_level)
{
va_start(args, fmt);
+
if (!stderr_quiet)
{
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
- vsyslog(priority, fmt, args);
+
+ /* write in memory buffer first */
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
+
+ /* do a syslog with every line */
+ while (current)
+ {
+ next = strchr(current, '\n');
+ if (next)
+ {
+ *(next++) = '\0';
+ }
+ syslog(priority, "%s\n", current);
+ current = next;
+ }
}
}
@@ -547,9 +563,8 @@ int main(int argc, char **argv)
/* write the attribute certificate to file */
attr_chunk = attr_cert->get_encoding(attr_cert);
- if (chunk_write(attr_chunk, outfile, 0022, TRUE))
+ if (chunk_write(attr_chunk, outfile, "attribute cert", 0022, TRUE))
{
- DBG1(" wrote attribute cert file '%s' (%u bytes)", outfile, attr_chunk.len);
write_serial(serial);
status = 0;
}
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index f788bc3d1..01237305b 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -7,7 +7,6 @@ ipsec_PROGRAMS = pluto _pluto_adns
pluto_SOURCES = \
ac.c ac.h \
alg_info.c alg_info.h \
-asn1.c asn1.h \
ca.c ca.h \
certs.c certs.h \
connections.c connections.h \
@@ -19,11 +18,8 @@ db_ops.c db_ops.h \
defs.c defs.h \
demux.c demux.h \
dnskey.c dnskey.h \
-dsa.c dsa.h \
-elgamal.c elgamal.h \
fetch.c fetch.h \
foodgroups.c foodgroups.h \
-gcryptfix.c gcryptfix.h \
id.c id.h \
ike_alg.c ike_alg.h \
ipsec_doi.c ipsec_doi.h \
@@ -36,23 +32,16 @@ kernel_pfkey.c kernel_pfkey.h \
keys.c keys.h \
lex.c lex.h \
log.c log.h \
-md2.c md2.h \
-md5.c md5.h \
modecfg.c modecfg.h \
-mp_defs.c mp_defs.h \
nat_traversal.c nat_traversal.h \
ocsp.c ocsp.h \
packet.c packet.h \
pem.c pem.h \
-pgp.c pgp.h \
-pkcs1.c pkcs1.h \
+pgpcert.c pgpcert.h \
pkcs7.c pkcs7.h \
plutomain.c \
-primegen.c smallprime.c \
rcv_whack.c rcv_whack.h \
-rnd.c rnd.h \
server.c server.h \
-sha1.c sha1.h \
smartcard.c smartcard.h \
spdb.c spdb.h \
state.c state.h \
@@ -61,22 +50,17 @@ vendor.c vendor.h \
virtual.c virtual.h \
xauth.c xauth.h \
x509.c x509.h \
-alg/ike_alg_aes.c alg/ike_alg_blowfish.c alg/ike_alg_twofish.c \
-alg/ike_alg_serpent.c alg/ike_alg_sha2.c alg/ike_alginit.c \
rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
_pluto_adns_SOURCES = adns.c adns.h
-LIBSTRONGSWANDIR=$(top_srcdir)/src/libstrongswan
+LIBSTRONGSWANDIR=$(top_builddir)/src/libstrongswan
LIBFREESWANDIR=$(top_builddir)/src/libfreeswan
-LIBCRYPTODIR=$(top_builddir)/src/libcrypto
-
INCLUDES = \
-I${linuxdir} \
--I$(LIBSTRONGSWANDIR)\
+-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libfreeswan \
--I$(top_srcdir)/src/libcrypto \
-I$(top_srcdir)/src/whack
AM_CFLAGS = \
@@ -84,24 +68,23 @@ AM_CFLAGS = \
-DIPSEC_CONFDIR=\"${confdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
-DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
+-DIPSEC_PLUGINDIR=\"${plugindir}\" \
+-DPLUGINS=\""${pluto_plugins}\"" \
+-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
-DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
-DPLUTO -DKLIPS -DDEBUG
pluto_LDADD = \
-oid.o \
+$(LIBSTRONGSWANDIR)/libstrongswan.la \
$(LIBFREESWANDIR)/libfreeswan.a \
-$(LIBCRYPTODIR)/libcrypto.a \
--lgmp -lresolv -lpthread -ldl
+-lresolv -lpthread $(DLLIB)
_pluto_adns_LDADD = \
$(LIBFREESWANDIR)/libfreeswan.a \
--lresolv -ldl
+-lresolv $(DLLIB)
dist_man_MANS = pluto.8 ipsec.secrets.5
-oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
- $(COMPILE) -c -o $@ $<
-
# This compile option activates the sending of a strongSwan VID
if USE_VENDORID
AM_CFLAGS += -DVENDORID
@@ -122,23 +105,16 @@ if USE_NAT_TRANSPORT
AM_CFLAGS += -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
endif
-# This compile option activates dynamic URL fetching using libcurl
-if USE_CURL
- pluto_LDADD += -lcurl
- AM_CFLAGS += -DLIBCURL
-endif
-
-# This compile option activates dynamic LDAP CRL fetching
-if USE_LDAP
- pluto_LDADD += -lldap -llber
- AM_CFLAGS += -DLIBLDAP
-endif
-
# This compile option activates smartcard support
if USE_SMARTCARD
AM_CFLAGS += -DSMARTCARD
endif
+# This compile option activates the integrity test of libstrongswan
+if USE_INTEGRITY_TEST
+ AM_CFLAGS += -DINTEGRITY_TEST
+endif
+
if USE_CAPABILITIES
pluto_LDADD += -lcap
endif
diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in
index 457f93d9f..01bda8540 100644
--- a/src/pluto/Makefile.in
+++ b/src/pluto/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -50,21 +50,16 @@ ipsec_PROGRAMS = pluto$(EXEEXT) _pluto_adns$(EXEEXT)
# This compile option activates NAT traversal with IPSec transport mode
@USE_NAT_TRANSPORT_TRUE@am__append_4 = -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
-# This compile option activates dynamic URL fetching using libcurl
-@USE_CURL_TRUE@am__append_5 = -lcurl
-@USE_CURL_TRUE@am__append_6 = -DLIBCURL
-
-# This compile option activates dynamic LDAP CRL fetching
-@USE_LDAP_TRUE@am__append_7 = -lldap -llber
-@USE_LDAP_TRUE@am__append_8 = -DLIBLDAP
-
# This compile option activates smartcard support
-@USE_SMARTCARD_TRUE@am__append_9 = -DSMARTCARD
-@USE_CAPABILITIES_TRUE@am__append_10 = -lcap
-@USE_THREADS_TRUE@am__append_11 = -DTHREADS
+@USE_SMARTCARD_TRUE@am__append_5 = -DSMARTCARD
+
+# This compile option activates the integrity test of libstrongswan
+@USE_INTEGRITY_TEST_TRUE@am__append_6 = -DINTEGRITY_TEST
+@USE_CAPABILITIES_TRUE@am__append_7 = -lcap
+@USE_THREADS_TRUE@am__append_8 = -DTHREADS
subdir = src/pluto
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in TODO
+ $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -77,34 +72,28 @@ ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am__pluto_adns_OBJECTS = adns.$(OBJEXT)
_pluto_adns_OBJECTS = $(am__pluto_adns_OBJECTS)
-_pluto_adns_DEPENDENCIES = $(LIBFREESWANDIR)/libfreeswan.a
-am_pluto_OBJECTS = ac.$(OBJEXT) alg_info.$(OBJEXT) asn1.$(OBJEXT) \
- ca.$(OBJEXT) certs.$(OBJEXT) connections.$(OBJEXT) \
- constants.$(OBJEXT) cookie.$(OBJEXT) crl.$(OBJEXT) \
- crypto.$(OBJEXT) db_ops.$(OBJEXT) defs.$(OBJEXT) \
- demux.$(OBJEXT) dnskey.$(OBJEXT) dsa.$(OBJEXT) \
- elgamal.$(OBJEXT) fetch.$(OBJEXT) foodgroups.$(OBJEXT) \
- gcryptfix.$(OBJEXT) id.$(OBJEXT) ike_alg.$(OBJEXT) \
- ipsec_doi.$(OBJEXT) kernel.$(OBJEXT) kernel_alg.$(OBJEXT) \
- kernel_netlink.$(OBJEXT) kernel_noklips.$(OBJEXT) \
- kernel_pfkey.$(OBJEXT) keys.$(OBJEXT) lex.$(OBJEXT) \
- log.$(OBJEXT) md2.$(OBJEXT) md5.$(OBJEXT) modecfg.$(OBJEXT) \
- mp_defs.$(OBJEXT) nat_traversal.$(OBJEXT) ocsp.$(OBJEXT) \
- packet.$(OBJEXT) pem.$(OBJEXT) pgp.$(OBJEXT) pkcs1.$(OBJEXT) \
- pkcs7.$(OBJEXT) plutomain.$(OBJEXT) primegen.$(OBJEXT) \
- smallprime.$(OBJEXT) rcv_whack.$(OBJEXT) rnd.$(OBJEXT) \
- server.$(OBJEXT) sha1.$(OBJEXT) smartcard.$(OBJEXT) \
- spdb.$(OBJEXT) state.$(OBJEXT) timer.$(OBJEXT) \
- vendor.$(OBJEXT) virtual.$(OBJEXT) xauth.$(OBJEXT) \
- x509.$(OBJEXT) ike_alg_aes.$(OBJEXT) \
- ike_alg_blowfish.$(OBJEXT) ike_alg_twofish.$(OBJEXT) \
- ike_alg_serpent.$(OBJEXT) ike_alg_sha2.$(OBJEXT) \
- ike_alginit.$(OBJEXT)
-pluto_OBJECTS = $(am_pluto_OBJECTS)
am__DEPENDENCIES_1 =
-pluto_DEPENDENCIES = oid.o $(LIBFREESWANDIR)/libfreeswan.a \
- $(LIBCRYPTODIR)/libcrypto.a $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+_pluto_adns_DEPENDENCIES = $(LIBFREESWANDIR)/libfreeswan.a \
+ $(am__DEPENDENCIES_1)
+am_pluto_OBJECTS = ac.$(OBJEXT) alg_info.$(OBJEXT) ca.$(OBJEXT) \
+ certs.$(OBJEXT) connections.$(OBJEXT) constants.$(OBJEXT) \
+ cookie.$(OBJEXT) crl.$(OBJEXT) crypto.$(OBJEXT) \
+ db_ops.$(OBJEXT) defs.$(OBJEXT) demux.$(OBJEXT) \
+ dnskey.$(OBJEXT) fetch.$(OBJEXT) foodgroups.$(OBJEXT) \
+ id.$(OBJEXT) ike_alg.$(OBJEXT) ipsec_doi.$(OBJEXT) \
+ kernel.$(OBJEXT) kernel_alg.$(OBJEXT) kernel_netlink.$(OBJEXT) \
+ kernel_noklips.$(OBJEXT) kernel_pfkey.$(OBJEXT) keys.$(OBJEXT) \
+ lex.$(OBJEXT) log.$(OBJEXT) modecfg.$(OBJEXT) \
+ nat_traversal.$(OBJEXT) ocsp.$(OBJEXT) packet.$(OBJEXT) \
+ pem.$(OBJEXT) pgpcert.$(OBJEXT) pkcs7.$(OBJEXT) \
+ plutomain.$(OBJEXT) rcv_whack.$(OBJEXT) server.$(OBJEXT) \
+ smartcard.$(OBJEXT) spdb.$(OBJEXT) state.$(OBJEXT) \
+ timer.$(OBJEXT) vendor.$(OBJEXT) virtual.$(OBJEXT) \
+ xauth.$(OBJEXT) x509.$(OBJEXT)
+pluto_OBJECTS = $(am_pluto_OBJECTS)
+pluto_DEPENDENCIES = $(LIBSTRONGSWANDIR)/libstrongswan.la \
+ $(LIBFREESWANDIR)/libfreeswan.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -141,6 +130,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -163,6 +153,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -174,6 +167,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -187,6 +181,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -247,6 +243,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -258,6 +255,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -265,7 +263,6 @@ xml_LIBS = @xml_LIBS@
pluto_SOURCES = \
ac.c ac.h \
alg_info.c alg_info.h \
-asn1.c asn1.h \
ca.c ca.h \
certs.c certs.h \
connections.c connections.h \
@@ -277,11 +274,8 @@ db_ops.c db_ops.h \
defs.c defs.h \
demux.c demux.h \
dnskey.c dnskey.h \
-dsa.c dsa.h \
-elgamal.c elgamal.h \
fetch.c fetch.h \
foodgroups.c foodgroups.h \
-gcryptfix.c gcryptfix.h \
id.c id.h \
ike_alg.c ike_alg.h \
ipsec_doi.c ipsec_doi.h \
@@ -294,23 +288,16 @@ kernel_pfkey.c kernel_pfkey.h \
keys.c keys.h \
lex.c lex.h \
log.c log.h \
-md2.c md2.h \
-md5.c md5.h \
modecfg.c modecfg.h \
-mp_defs.c mp_defs.h \
nat_traversal.c nat_traversal.h \
ocsp.c ocsp.h \
packet.c packet.h \
pem.c pem.h \
-pgp.c pgp.h \
-pkcs1.c pkcs1.h \
+pgpcert.c pgpcert.h \
pkcs7.c pkcs7.h \
plutomain.c \
-primegen.c smallprime.c \
rcv_whack.c rcv_whack.h \
-rnd.c rnd.h \
server.c server.h \
-sha1.c sha1.h \
smartcard.c smartcard.h \
spdb.c spdb.h \
state.c state.h \
@@ -319,34 +306,33 @@ vendor.c vendor.h \
virtual.c virtual.h \
xauth.c xauth.h \
x509.c x509.h \
-alg/ike_alg_aes.c alg/ike_alg_blowfish.c alg/ike_alg_twofish.c \
-alg/ike_alg_serpent.c alg/ike_alg_sha2.c alg/ike_alginit.c \
rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
_pluto_adns_SOURCES = adns.c adns.h
-LIBSTRONGSWANDIR = $(top_srcdir)/src/libstrongswan
+LIBSTRONGSWANDIR = $(top_builddir)/src/libstrongswan
LIBFREESWANDIR = $(top_builddir)/src/libfreeswan
-LIBCRYPTODIR = $(top_builddir)/src/libcrypto
INCLUDES = \
-I${linuxdir} \
--I$(LIBSTRONGSWANDIR)\
+-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libfreeswan \
--I$(top_srcdir)/src/libcrypto \
-I$(top_srcdir)/src/whack
AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_CONFDIR=\"${confdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
-DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
- -DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES -DPLUTO \
- -DKLIPS -DDEBUG $(am__append_1) $(am__append_2) \
- $(am__append_3) $(am__append_4) $(am__append_6) \
- $(am__append_8) $(am__append_9) $(am__append_11)
-pluto_LDADD = oid.o $(LIBFREESWANDIR)/libfreeswan.a \
- $(LIBCRYPTODIR)/libcrypto.a -lgmp -lresolv -lpthread -ldl \
- $(am__append_5) $(am__append_7) $(am__append_10)
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${pluto_plugins}\"" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" -DKERNEL26_SUPPORT \
+ -DKERNEL26_HAS_KAME_DUPLICATES -DPLUTO -DKLIPS -DDEBUG \
+ $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4) $(am__append_5) $(am__append_6) \
+ $(am__append_8)
+pluto_LDADD = $(LIBSTRONGSWANDIR)/libstrongswan.la \
+ $(LIBFREESWANDIR)/libfreeswan.a -lresolv -lpthread $(DLLIB) \
+ $(am__append_7)
_pluto_adns_LDADD = \
$(LIBFREESWANDIR)/libfreeswan.a \
--lresolv -ldl
+-lresolv $(DLLIB)
dist_man_MANS = pluto.8 ipsec.secrets.5
all: all-am
@@ -357,8 +343,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -426,7 +412,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adns.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg_info.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ca.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connections.Po@am__quote@
@@ -438,19 +423,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dnskey.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elgamal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foodgroups.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcryptfix.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg_aes.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg_blowfish.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg_serpent.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg_sha2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alg_twofish.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_alginit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipsec_doi.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_alg.Po@am__quote@
@@ -460,24 +436,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keys.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modecfg.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp_defs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nat_traversal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgpcert.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plutomain.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primegen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcv_whack.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rnd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smallprime.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smartcard.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@
@@ -508,90 +476,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-ike_alg_aes.o: alg/ike_alg_aes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_aes.o -MD -MP -MF $(DEPDIR)/ike_alg_aes.Tpo -c -o ike_alg_aes.o `test -f 'alg/ike_alg_aes.c' || echo '$(srcdir)/'`alg/ike_alg_aes.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_aes.Tpo $(DEPDIR)/ike_alg_aes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_aes.c' object='ike_alg_aes.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_aes.o `test -f 'alg/ike_alg_aes.c' || echo '$(srcdir)/'`alg/ike_alg_aes.c
-
-ike_alg_aes.obj: alg/ike_alg_aes.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_aes.obj -MD -MP -MF $(DEPDIR)/ike_alg_aes.Tpo -c -o ike_alg_aes.obj `if test -f 'alg/ike_alg_aes.c'; then $(CYGPATH_W) 'alg/ike_alg_aes.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_aes.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_aes.Tpo $(DEPDIR)/ike_alg_aes.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_aes.c' object='ike_alg_aes.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_aes.obj `if test -f 'alg/ike_alg_aes.c'; then $(CYGPATH_W) 'alg/ike_alg_aes.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_aes.c'; fi`
-
-ike_alg_blowfish.o: alg/ike_alg_blowfish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_blowfish.o -MD -MP -MF $(DEPDIR)/ike_alg_blowfish.Tpo -c -o ike_alg_blowfish.o `test -f 'alg/ike_alg_blowfish.c' || echo '$(srcdir)/'`alg/ike_alg_blowfish.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_blowfish.Tpo $(DEPDIR)/ike_alg_blowfish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_blowfish.c' object='ike_alg_blowfish.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_blowfish.o `test -f 'alg/ike_alg_blowfish.c' || echo '$(srcdir)/'`alg/ike_alg_blowfish.c
-
-ike_alg_blowfish.obj: alg/ike_alg_blowfish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_blowfish.obj -MD -MP -MF $(DEPDIR)/ike_alg_blowfish.Tpo -c -o ike_alg_blowfish.obj `if test -f 'alg/ike_alg_blowfish.c'; then $(CYGPATH_W) 'alg/ike_alg_blowfish.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_blowfish.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_blowfish.Tpo $(DEPDIR)/ike_alg_blowfish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_blowfish.c' object='ike_alg_blowfish.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_blowfish.obj `if test -f 'alg/ike_alg_blowfish.c'; then $(CYGPATH_W) 'alg/ike_alg_blowfish.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_blowfish.c'; fi`
-
-ike_alg_twofish.o: alg/ike_alg_twofish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_twofish.o -MD -MP -MF $(DEPDIR)/ike_alg_twofish.Tpo -c -o ike_alg_twofish.o `test -f 'alg/ike_alg_twofish.c' || echo '$(srcdir)/'`alg/ike_alg_twofish.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_twofish.Tpo $(DEPDIR)/ike_alg_twofish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_twofish.c' object='ike_alg_twofish.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_twofish.o `test -f 'alg/ike_alg_twofish.c' || echo '$(srcdir)/'`alg/ike_alg_twofish.c
-
-ike_alg_twofish.obj: alg/ike_alg_twofish.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_twofish.obj -MD -MP -MF $(DEPDIR)/ike_alg_twofish.Tpo -c -o ike_alg_twofish.obj `if test -f 'alg/ike_alg_twofish.c'; then $(CYGPATH_W) 'alg/ike_alg_twofish.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_twofish.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_twofish.Tpo $(DEPDIR)/ike_alg_twofish.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_twofish.c' object='ike_alg_twofish.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_twofish.obj `if test -f 'alg/ike_alg_twofish.c'; then $(CYGPATH_W) 'alg/ike_alg_twofish.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_twofish.c'; fi`
-
-ike_alg_serpent.o: alg/ike_alg_serpent.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_serpent.o -MD -MP -MF $(DEPDIR)/ike_alg_serpent.Tpo -c -o ike_alg_serpent.o `test -f 'alg/ike_alg_serpent.c' || echo '$(srcdir)/'`alg/ike_alg_serpent.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_serpent.Tpo $(DEPDIR)/ike_alg_serpent.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_serpent.c' object='ike_alg_serpent.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_serpent.o `test -f 'alg/ike_alg_serpent.c' || echo '$(srcdir)/'`alg/ike_alg_serpent.c
-
-ike_alg_serpent.obj: alg/ike_alg_serpent.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_serpent.obj -MD -MP -MF $(DEPDIR)/ike_alg_serpent.Tpo -c -o ike_alg_serpent.obj `if test -f 'alg/ike_alg_serpent.c'; then $(CYGPATH_W) 'alg/ike_alg_serpent.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_serpent.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_serpent.Tpo $(DEPDIR)/ike_alg_serpent.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_serpent.c' object='ike_alg_serpent.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_serpent.obj `if test -f 'alg/ike_alg_serpent.c'; then $(CYGPATH_W) 'alg/ike_alg_serpent.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_serpent.c'; fi`
-
-ike_alg_sha2.o: alg/ike_alg_sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_sha2.o -MD -MP -MF $(DEPDIR)/ike_alg_sha2.Tpo -c -o ike_alg_sha2.o `test -f 'alg/ike_alg_sha2.c' || echo '$(srcdir)/'`alg/ike_alg_sha2.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_sha2.Tpo $(DEPDIR)/ike_alg_sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_sha2.c' object='ike_alg_sha2.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_sha2.o `test -f 'alg/ike_alg_sha2.c' || echo '$(srcdir)/'`alg/ike_alg_sha2.c
-
-ike_alg_sha2.obj: alg/ike_alg_sha2.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alg_sha2.obj -MD -MP -MF $(DEPDIR)/ike_alg_sha2.Tpo -c -o ike_alg_sha2.obj `if test -f 'alg/ike_alg_sha2.c'; then $(CYGPATH_W) 'alg/ike_alg_sha2.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_sha2.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alg_sha2.Tpo $(DEPDIR)/ike_alg_sha2.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alg_sha2.c' object='ike_alg_sha2.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alg_sha2.obj `if test -f 'alg/ike_alg_sha2.c'; then $(CYGPATH_W) 'alg/ike_alg_sha2.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alg_sha2.c'; fi`
-
-ike_alginit.o: alg/ike_alginit.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alginit.o -MD -MP -MF $(DEPDIR)/ike_alginit.Tpo -c -o ike_alginit.o `test -f 'alg/ike_alginit.c' || echo '$(srcdir)/'`alg/ike_alginit.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alginit.Tpo $(DEPDIR)/ike_alginit.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alginit.c' object='ike_alginit.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alginit.o `test -f 'alg/ike_alginit.c' || echo '$(srcdir)/'`alg/ike_alginit.c
-
-ike_alginit.obj: alg/ike_alginit.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_alginit.obj -MD -MP -MF $(DEPDIR)/ike_alginit.Tpo -c -o ike_alginit.obj `if test -f 'alg/ike_alginit.c'; then $(CYGPATH_W) 'alg/ike_alginit.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alginit.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_alginit.Tpo $(DEPDIR)/ike_alginit.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='alg/ike_alginit.c' object='ike_alginit.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_alginit.obj `if test -f 'alg/ike_alginit.c'; then $(CYGPATH_W) 'alg/ike_alginit.c'; else $(CYGPATH_W) '$(srcdir)/alg/ike_alginit.c'; fi`
-
mostlyclean-libtool:
-rm -f *.lo
@@ -608,8 +492,8 @@ install-man5: $(man5_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
5*) ;; \
@@ -653,8 +537,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -693,7 +577,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -871,9 +755,6 @@ uninstall-man: uninstall-man5 uninstall-man8
uninstall-ipsecPROGRAMS uninstall-man uninstall-man5 \
uninstall-man8
-
-oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
- $(COMPILE) -c -o $@ $<
# 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/pluto/TODO b/src/pluto/TODO
deleted file mode 100644
index 1c22b2f5c..000000000
--- a/src/pluto/TODO
+++ /dev/null
@@ -1,129 +0,0 @@
-Pluto TODO list
-===============
-RCSID $Id: TODO 3269 2007-10-08 20:03:02Z andreas $
-
-- should all log entries that are for errors say ERROR?
-
-- Add a "plug-in" facility so that others can add features without
- changing the mainline code. This is how X509/LDAP/biometric stuff
- might be added.
-
-- (internal change only) routines for outputting payloads should plug
- "np" into the previous payload so that a payload generating routine
- need not know what the next payload will be. This may be more bother
- than it is worth.
-
-- notifications, in and out
- + delete
- + first contact
- + last contact? (not part of drafts, but would be nice)
-
-- Make DNS usage for asynchronous (non-blocking)
- + looking up KEY and TXT records during negotiation
- + perhaps not for whack command arguments and ipsec.secrets since the
- library code uses gethostbyname
-
-- check that ipsec auto and whack to agree on what is worth reporting
-
-- Should Pluto (rather than ipsec manual) install %passthrough conns?
- That way Pluto would know of them.
-
-- For responding to Road Warriors, how can we decide if the RW has
- gone away? The rekeying event is perhaps too imprecise. Even if
- rekeying event is good enough, how do we know if the route should be
- torn down? Perhaps limiting a Phase 1 ID to one IP address would
- help (limiting a client subnet to one peer already helps). Perhaps
- (in some rate-limited way) we can take an ICMP host unreachable
- as a hint to do some authenticated and reliable probe.
-
-- it is annoying that Pluto and auto have different models for public keys.
- + auto specifies one per connection
- + Pluto allows one to be specified per id
- Two connections with the same id are going to use the same key:
- the one of the last conn to be added!
-
- I think auto ought to be fixed. It is hard for Pluto to warn when
- there is a conflict since the deletion of a connection doesn't
- prompt auto to tell pluto to delete the public key.
-
-- different connections with the same host IP addresses are randomly
- interchangeable until the ID payload is received. At least for the
- Responder case (and eventually for the opportunistic Initiator).
- Worse, all Road Warriors must be considered to have the
- indistinguishable IP addresses. This affects ISAKMP SA negotiation.
- Currently, there is little flexibility in this negotiation, so the
- problem is limited to the specification of acceptable authentication
- method(s). Correct, but more work than seems worthwhile, would be
- to select the conn based on what is proposed.
-
- Warning about such confusion at connection definition time isn't great
- because there is no confusion when explicitly initiated (a particular
- conn is specified). Warning for a Road Warrior conn is possible
- since it cannot be initiated (and has been implemented).
-
-- characterize and ameliorate DOS attacks. Lots of rate limiting.
-
-- look at John Denker's wish list: http://www.quintillion.com/moat/wish.list
-
-- use of random numbers needs to be audited.
-
-- unknown (not just unimplemented) transforms cause a negotiation to
- fail. Only the transform should be rejected.
-
-- we need better policy control. Our present flags need to be
- modulated (forbid, allow, offer, require)
-
-- HS will specify how --copyright and --version should behave
-
-- HS will initiate project-wide terminology replacing ISAKMP SA, IPSEC
- SA, Protection Suite, Phase 1, Main Mode, Phase 2, Quick Mode, ...
- Simplicity and clarity will be a goal.
-
-- interface discovery ought to match what is specified in ipsec.conf.
- This probably means grokking /proc/net/ipsec_tncfg. Documented in
- ipsec_tncfg(5). This won't do for Hugh's debugging setup.
-
-
-Protocol Issues
-===============
-
-Notification and delete payloads seem to be "escape hatches" for the
-protocols. As such, anything implemented using them seems to be
-kludged without being well designed or well situated or well
-constrained in the protocols. Often the precise meaning (if any) or
-usage is under specified. An implementation is allowed to ignore
-them, so they cannot really matter (but they too often do). Their
-specification ought to be scrutinized by a protocol guru.
-
-Any extra payload in last main mode message is not protected (not
-authenticated by hash).
-
-Should notification payloads be interpreted before or after the normal
-payloads (i.e. understood in the context of, executed in the context of).
-
-What is the precise result of an INITIAL_CONNECTION? What is a
-"system" (eg. does Phase 1 Identity count)? What is "earlier" or
-"before" (simultaneous negotiation is possible, with time being only a
-partial order)? Could it be used for FINAL_CONTACT (needed too)?
-
-Blasting out a pile of UDP messages, especially to a particular
-destination, is likely to provoke message loss. The exchanges are
-just that, so they individually are self-throttling. But what about
-multiple exchanges simultaneously? What about notifications (example:
-when shutting down, a flurry of delete notifications are likely).
-Should the RFCs be designed to protect against this problem?
-
-draft-jenkins-ipsec-rekeying-03.txt rekeying is way too complicated.
-Our solution looks sound and simple (we have the Responder install the
-incoming IPSEC SA before sending its first reply). In "2.2.1.4
-Responder Pre-Set-up Security Hole", the draft claims that setting up
-the IPSEC SA early leaves the Responder open to replay attacks. I
-think that this is wrong: the Message Id, since it must not be reused,
-serves to prove that this isn't a replay.
-
-The details for notification messages suggested by
-draft-ietf-ipsec-notifymsg-02.txt are over-complicated, just to make
-them machine-comprehensible. I think this is over-engineering,
-justified only if another level of negotiation is contemplated (ugh!).
-Plain text is probably sufficient for informing humans (I admit that
-there is a problem with I18N).
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index 6745ff484..3b5df9738 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ac.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <stdlib.h>
@@ -25,10 +23,11 @@
#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "asn1.h"
+#include <utils.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <asn1/oid.h>
+
#include "ac.h"
#include "x509.h"
#include "crl.h"
@@ -38,971 +37,947 @@
#include "whack.h"
#include "fetch.h"
-/* chained list of X.509 attribute certificates */
-
+/**
+ * Chained list of X.509 attribute certificates
+ */
static x509acert_t *x509acerts = NULL;
-/* chained list of ietfAttributes */
-
+/**
+ * Chained list of ietfAttributes
+ */
static ietfAttrList_t *ietfAttributes = NULL;
-/* ASN.1 definition of ietfAttrSyntax */
-
+/**
+ * ASN.1 definition of ietfAttrSyntax
+ */
static const asn1Object_t ietfAttrSyntaxObjects[] =
{
- { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
- { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
- ASN1_BODY }, /* 4 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 2, "oid", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 6 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "string", ASN1_UTF8STRING, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 10 */
+ { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_BODY }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
+ { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 4 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
+ { 2, "oid", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 6 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 2, "string", ASN1_UTF8STRING, ASN1_OPT |
+ ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-#define IETF_ATTR_OCTETS 4
-#define IETF_ATTR_OID 6
-#define IETF_ATTR_STRING 8
-#define IETF_ATTR_ROOF 11
-
-/* ASN.1 definition of roleSyntax */
+#define IETF_ATTR_OCTETS 4
+#define IETF_ATTR_OID 6
+#define IETF_ATTR_STRING 8
+/**
+ * ASN.1 definition of roleSyntax
+ */
static const asn1Object_t roleSyntaxObjects[] =
{
- { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
+ { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_OBJ }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-#define ROLE_ROOF 4
-
-/* ASN.1 definition of an X509 attribute certificate */
-
+/**
+ * ASN.1 definition of an X509 attribute certificate
+ */
static const asn1Object_t acObjects[] =
{
- { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_DEF |
- ASN1_BODY }, /* 2 */
- { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 7 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 10 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
- { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
- { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
- { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
- { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
- { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
- { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
- { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 25 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
- { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
- { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
- { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 31 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
- { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
- { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
- { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
- { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
- { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
- { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
- { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
- { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
- { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
- { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 50 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
+ { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_DEF |
+ ASN1_BODY }, /* 2 */
+ { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
+ { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
+ { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 7 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
+ ASN1_OBJ }, /* 10 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
+ { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13 */
+ { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 14 */
+ { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
+ { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_OBJ }, /* 19 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
+ { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
+ { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
+ { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
+ { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
+ ASN1_BODY }, /* 25 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
+ { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
+ { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
+ { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
+ ASN1_BODY }, /* 31 */
+ { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
+ { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
+ { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
+ { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
+ { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
+ { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
+ { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
+ { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
+ { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
+ { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
+ { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 50 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 54 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-#define AC_OBJ_CERTIFICATE 0
-#define AC_OBJ_CERTIFICATE_INFO 1
-#define AC_OBJ_VERSION 2
-#define AC_OBJ_HOLDER_ISSUER 5
-#define AC_OBJ_HOLDER_SERIAL 6
-#define AC_OBJ_ENTITY_NAME 10
-#define AC_OBJ_ISSUER_NAME 19
-#define AC_OBJ_ISSUER 23
-#define AC_OBJ_SIG_ALG 35
-#define AC_OBJ_SERIAL_NUMBER 36
-#define AC_OBJ_NOT_BEFORE 38
-#define AC_OBJ_NOT_AFTER 39
-#define AC_OBJ_ATTRIBUTE_TYPE 42
-#define AC_OBJ_ATTRIBUTE_VALUE 44
-#define AC_OBJ_EXTN_ID 49
-#define AC_OBJ_CRITICAL 50
-#define AC_OBJ_EXTN_VALUE 51
-#define AC_OBJ_ALGORITHM 53
-#define AC_OBJ_SIGNATURE 54
-#define AC_OBJ_ROOF 55
+#define AC_OBJ_CERTIFICATE 0
+#define AC_OBJ_CERTIFICATE_INFO 1
+#define AC_OBJ_VERSION 2
+#define AC_OBJ_HOLDER_ISSUER 5
+#define AC_OBJ_HOLDER_SERIAL 6
+#define AC_OBJ_ENTITY_NAME 10
+#define AC_OBJ_ISSUER_NAME 19
+#define AC_OBJ_ISSUER 23
+#define AC_OBJ_SIG_ALG 35
+#define AC_OBJ_SERIAL_NUMBER 36
+#define AC_OBJ_NOT_BEFORE 38
+#define AC_OBJ_NOT_AFTER 39
+#define AC_OBJ_ATTRIBUTE_TYPE 42
+#define AC_OBJ_ATTRIBUTE_VALUE 44
+#define AC_OBJ_EXTN_ID 49
+#define AC_OBJ_CRITICAL 50
+#define AC_OBJ_EXTN_VALUE 51
+#define AC_OBJ_ALGORITHM 53
+#define AC_OBJ_SIGNATURE 54
const x509acert_t empty_ac = {
- NULL , /* *next */
- 0 , /* installed */
- { NULL, 0 }, /* certificate */
- { NULL, 0 }, /* certificateInfo */
- 1 , /* version */
- /* holder */
- /* baseCertificateID */
- { NULL, 0 }, /* holderIssuer */
- { NULL, 0 }, /* holderSerial */
- /* entityName */
- { NULL, 0 }, /* generalNames */
- /* v2Form */
- { NULL, 0 }, /* issuerName */
- /* signature */
- OID_UNKNOWN, /* sigAlg */
- { NULL, 0 }, /* serialNumber */
- /* attrCertValidityPeriod */
- 0 , /* notBefore */
- 0 , /* notAfter */
- /* attributes */
- NULL , /* charging */
- NULL , /* groups */
- /* extensions */
- { NULL, 0 }, /* authKeyID */
- { NULL, 0 }, /* authKeySerialNumber */
- FALSE , /* noRevAvail */
- /* signatureAlgorithm */
- OID_UNKNOWN, /* algorithm */
- { NULL, 0 }, /* signature */
+ NULL , /* *next */
+ 0 , /* installed */
+ { NULL, 0 }, /* certificate */
+ { NULL, 0 }, /* certificateInfo */
+ 1 , /* version */
+ /* holder */
+ /* baseCertificateID */
+ { NULL, 0 }, /* holderIssuer */
+ { NULL, 0 }, /* holderSerial */
+ /* entityName */
+ { NULL, 0 }, /* generalNames */
+ /* v2Form */
+ { NULL, 0 }, /* issuerName */
+ /* signature */
+ OID_UNKNOWN, /* sigAlg */
+ { NULL, 0 }, /* serialNumber */
+ /* attrCertValidityPeriod */
+ 0 , /* notBefore */
+ 0 , /* notAfter */
+ /* attributes */
+ NULL , /* charging */
+ NULL , /* groups */
+ /* extensions */
+ { NULL, 0 }, /* authKeyID */
+ { NULL, 0 }, /* authKeySerialNumber */
+ FALSE , /* noRevAvail */
+ /* signatureAlgorithm */
+ OID_UNKNOWN, /* algorithm */
+ { NULL, 0 }, /* signature */
};
-/* compare two ietfAttributes, returns zero if a equals b
+/**
+ * compare two ietfAttributes, returns zero if a equals b
* negative/positive if a is earlier/later in the alphabet than b
*/
-static int
-cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
+static int cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
{
- int cmp_len, len, cmp_value;
+ int cmp_len, len, cmp_value;
- /* cannot compare OID with STRING or OCTETS attributes */
- if (a->kind == IETF_ATTRIBUTE_OID && b->kind != IETF_ATTRIBUTE_OID)
- return 1;
-
- cmp_len = a->value.len - b->value.len;
- len = (cmp_len < 0)? a->value.len : b->value.len;
- cmp_value = memcmp(a->value.ptr, b->value.ptr, len);
+ /* cannot compare OID with STRING or OCTETS attributes */
+ if (a->kind == IETF_ATTRIBUTE_OID && b->kind != IETF_ATTRIBUTE_OID)
+ return 1;
+
+ cmp_len = a->value.len - b->value.len;
+ len = (cmp_len < 0)? a->value.len : b->value.len;
+ cmp_value = memcmp(a->value.ptr, b->value.ptr, len);
- return (cmp_value == 0)? cmp_len : cmp_value;
+ return (cmp_value == 0)? cmp_len : cmp_value;
}
-/*
+/**
* add an ietfAttribute to the chained list
*/
-static ietfAttr_t*
-add_ietfAttr(ietfAttr_t *attr)
+static ietfAttr_t* add_ietfAttr(ietfAttr_t *attr)
{
- ietfAttrList_t **listp = &ietfAttributes;
- ietfAttrList_t *list = *listp;
- int cmp = -1;
-
- while (list != NULL)
- {
- cmp = cmp_ietfAttr(attr, list->attr);
- if (cmp <= 0)
- break;
- listp = &list->next;
- list = *listp;
- }
-
- if (cmp == 0)
- {
- /* attribute already exists, increase count */
- pfree(attr);
- list->attr->count++;
- return list->attr;
- }
- else
- {
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- /* new attribute, unshare value */
- attr->value.ptr = clone_bytes(attr->value.ptr, attr->value.len
- , "attr value");
- attr->count = 1;
- time(&attr->installed);
-
- el->attr = attr;
- el->next = list;
- *listp = el;
-
- return attr;
- }
+ ietfAttrList_t **listp = &ietfAttributes;
+ ietfAttrList_t *list = *listp;
+ int cmp = -1;
+
+ while (list != NULL)
+ {
+ cmp = cmp_ietfAttr(attr, list->attr);
+ if (cmp <= 0)
+ break;
+ listp = &list->next;
+ list = *listp;
+ }
+
+ if (cmp == 0)
+ {
+ /* attribute already exists, increase count */
+ free(attr);
+ list->attr->count++;
+ return list->attr;
+ }
+ else
+ {
+ ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
+
+ /* new attribute, unshare value */
+ attr->value = chunk_clone(attr->value);
+ attr->count = 1;
+ time(&attr->installed);
+
+ el->attr = attr;
+ el->next = list;
+ *listp = el;
+
+ return attr;
+ }
}
-/*
+/**
* decodes a comma separated list of group attributes
*/
-void
-decode_groups(char *groups, ietfAttrList_t **listp)
+void decode_groups(char *groups, ietfAttrList_t **listp)
{
- if (groups == NULL)
- return;
+ if (groups == NULL)
+ return;
- while (strlen(groups) > 0)
- {
- char *end;
- char *next = strchr(groups, ',');
+ while (strlen(groups) > 0)
+ {
+ char *end;
+ char *next = strchr(groups, ',');
- if (next == NULL)
- end = next = groups + strlen(groups);
- else
- end = next++;
+ if (next == NULL)
+ end = next = groups + strlen(groups);
+ else
+ end = next++;
- /* eat preceeding whitespace */
- while (groups < end && *groups == ' ')
- groups++;
+ /* eat preceeding whitespace */
+ while (groups < end && *groups == ' ')
+ groups++;
- /* eat trailing whitespace */
- while (end > groups && *(end-1) == ' ')
- end--;
+ /* eat trailing whitespace */
+ while (end > groups && *(end-1) == ' ')
+ end--;
- if (groups < end)
- {
- ietfAttr_t *attr = alloc_thing(ietfAttr_t, "ietfAttr");
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
+ if (groups < end)
+ {
+ ietfAttr_t *attr = malloc_thing(ietfAttr_t);
+ ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
- attr->kind = IETF_ATTRIBUTE_STRING;
- attr->value.ptr = groups;
- attr->value.len = end - groups;
- attr->count = 0;
+ attr->kind = IETF_ATTRIBUTE_STRING;
+ attr->value.ptr = groups;
+ attr->value.len = end - groups;
+ attr->count = 0;
- el->attr = add_ietfAttr(attr);
- el->next = *listp;
- *listp = el;
- }
+ el->attr = add_ietfAttr(attr);
+ el->next = *listp;
+ *listp = el;
+ }
- groups = next;
- }
+ groups = next;
+ }
}
-static bool
-same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
+static bool same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
{
- return (a->kind == b->kind && a->value.len == b->value.len
- && memcmp(a->value.ptr, b->value.ptr, b->value.len) == 0);
+ return (a->kind == b->kind && a->value.len == b->value.len
+ && memeq(a->value.ptr, b->value.ptr, b->value.len));
}
-bool
-group_membership(const ietfAttrList_t *peer_list
- , const char *conn
- , const ietfAttrList_t *conn_list)
+bool group_membership(const ietfAttrList_t *peer_list
+ , const char *conn
+ , const ietfAttrList_t *conn_list)
{
- if (conn_list == NULL)
- return TRUE;
-
- while (peer_list != NULL)
- {
- const ietfAttr_t *peer_attr = peer_list->attr;
- const ietfAttrList_t *list = conn_list;
+ if (conn_list == NULL)
+ return TRUE;
- while (list != NULL)
+ while (peer_list != NULL)
{
- ietfAttr_t *conn_attr = list->attr;
+ const ietfAttr_t *peer_attr = peer_list->attr;
+ const ietfAttrList_t *list = conn_list;
- if (same_attribute(conn_attr, peer_attr))
- {
+ while (list != NULL)
+ {
+ ietfAttr_t *conn_attr = list->attr;
+
+ if (same_attribute(conn_attr, peer_attr))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("%s: peer matches group '%.*s'"
+ , conn
+ , (int)peer_attr->value.len, peer_attr->value.ptr)
+ )
+ return TRUE;
+ }
+ list = list->next;
+ }
+ peer_list = peer_list->next;
+ }
DBG(DBG_CONTROL,
- DBG_log("%s: peer matches group '%.*s'"
- , conn
- , (int)peer_attr->value.len, peer_attr->value.ptr)
+ DBG_log("%s: peer doesn't match any group", conn)
)
- return TRUE;
- }
- list = list->next;
- }
- peer_list = peer_list->next;
- }
- DBG(DBG_CONTROL,
- DBG_log("%s: peer doesn't match any group", conn)
- )
- return FALSE;
+ return FALSE;
}
-
-void
-unshare_ietfAttrList(ietfAttrList_t **listp)
+void unshare_ietfAttrList(ietfAttrList_t **listp)
{
- ietfAttrList_t *list = *listp;
-
- while (list != NULL)
- {
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- el->attr = list->attr;
- el->attr->count++;
- el->next = NULL;
- *listp = el;
- listp = &el->next;
- list = list->next;
- }
+ ietfAttrList_t *list = *listp;
+
+ while (list != NULL)
+ {
+ ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
+
+ el->attr = list->attr;
+ el->attr->count++;
+ el->next = NULL;
+ *listp = el;
+ listp = &el->next;
+ list = list->next;
+ }
}
-/*
- * parses ietfAttrSyntax
+/**
+ * Parses ietfAttrSyntax
*/
-static ietfAttrList_t*
-parse_ietfAttrSyntax(chunk_t blob, int level0)
+static ietfAttrList_t* parse_ietfAttrSyntax(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- ietfAttrList_t *list = NULL;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ ietfAttrList_t *list = NULL;
- while (objectID < IETF_ATTR_ROOF)
- {
- if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
- return NULL;
+ parser = asn1_parser_create(ietfAttrSyntaxObjects, blob);
+ parser->set_top_level(parser, level0);
- switch (objectID)
+ while (parser->iterate(parser, &objectID, &object))
{
- case IETF_ATTR_OCTETS:
- case IETF_ATTR_OID:
- case IETF_ATTR_STRING:
- {
- ietfAttr_t *attr = alloc_thing(ietfAttr_t, "ietfAttr");
- ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
-
- attr->kind = (objectID - IETF_ATTR_OCTETS) / 2;
- attr->value = object;
- attr->count = 0;
-
- el->attr = add_ietfAttr(attr);
- el->next = list;
- list = el;
- }
- break;
- default:
- break;
+ switch (objectID)
+ {
+ case IETF_ATTR_OCTETS:
+ case IETF_ATTR_OID:
+ case IETF_ATTR_STRING:
+ {
+ ietfAttr_t *attr = malloc_thing(ietfAttr_t);
+ ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
+
+ attr->kind = (objectID - IETF_ATTR_OCTETS) / 2;
+ attr->value = object;
+ attr->count = 0;
+
+ el->attr = add_ietfAttr(attr);
+ el->next = list;
+ list = el;
+ }
+ break;
+ default:
+ break;
+ }
}
- objectID++;
- }
- return list;
+ parser->destroy(parser);
+ return list;
}
-/*
- * parses roleSyntax
+
+/**
+ * Parses roleSyntax
*/
-static void
-parse_roleSyntax(chunk_t blob, int level0)
+static void parse_roleSyntax(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(roleSyntaxObjects, blob);
+ parser->set_top_level(parser, level0);
- while (objectID < ROLE_ROOF)
- {
- if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- default:
- break;
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ default:
+ break;
+ }
}
- objectID++;
- }
+ parser->destroy(parser);
}
-/*
+/**
* Parses an X.509 attribute certificate
*/
-bool
-parse_ac(chunk_t blob, x509acert_t *ac)
+bool parse_ac(chunk_t blob, x509acert_t *ac)
{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int type = OID_UNKNOWN;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int type = OID_UNKNOWN;
+ int extn_oid = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
- while (objectID < AC_OBJ_ROOF) {
+ parser = asn1_parser_create(acObjects, blob);
- if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
- return FALSE;
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
- /* those objects which will parsed further need the next higher level */
- level++;
+ switch (objectID)
+ {
+ case AC_OBJ_CERTIFICATE:
+ ac->certificate = object;
+ break;
+ case AC_OBJ_CERTIFICATE_INFO:
+ ac->certificateInfo = object;
+ break;
+ case AC_OBJ_VERSION:
+ ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
+ DBG(DBG_PARSING,
+ DBG_log(" v%d", ac->version);
+ )
+ if (ac->version != 2)
+ {
+ plog("v%d attribute certificates are not supported"
+ , ac->version);
+ goto end;
+ }
+ break;
+ case AC_OBJ_HOLDER_ISSUER:
+ ac->holderIssuer = get_directoryName(object, level, FALSE);
+ break;
+ case AC_OBJ_HOLDER_SERIAL:
+ ac->holderSerial = object;
+ break;
+ case AC_OBJ_ENTITY_NAME:
+ ac->entityName = get_directoryName(object, level, TRUE);
+ break;
+ case AC_OBJ_ISSUER_NAME:
+ ac->issuerName = get_directoryName(object, level, FALSE);
+ break;
+ case AC_OBJ_SIG_ALG:
+ ac->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SERIAL_NUMBER:
+ ac->serialNumber = object;
+ break;
+ case AC_OBJ_NOT_BEFORE:
+ ac->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_NOT_AFTER:
+ ac->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case AC_OBJ_ATTRIBUTE_TYPE:
+ type = asn1_known_oid(object);
+ break;
+ case AC_OBJ_ATTRIBUTE_VALUE:
+ {
+ switch (type) {
+ case OID_AUTHENTICATION_INFO:
+ DBG(DBG_PARSING,
+ DBG_log(" need to parse authenticationInfo")
+ )
+ break;
+ case OID_ACCESS_IDENTITY:
+ DBG(DBG_PARSING,
+ DBG_log(" need to parse accessIdentity")
+ )
+ break;
+ case OID_CHARGING_IDENTITY:
+ ac->charging = parse_ietfAttrSyntax(object, level);
+ break;
+ case OID_GROUP:
+ ac->groups = parse_ietfAttrSyntax(object, level);
+ break;
+ case OID_ROLE:
+ parse_roleSyntax(object, level);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case AC_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case AC_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(critical)?"TRUE":"FALSE");
+ )
+ break;
+ case AC_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid) {
+ case OID_CRL_DISTRIBUTION_POINTS:
+ DBG(DBG_PARSING,
+ DBG_log(" need to parse crlDistributionPoints")
+ )
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ parse_authorityKeyIdentifier(object, level
+ , &ac->authKeyID, &ac->authKeySerialNumber);
+ break;
+ case OID_TARGET_INFORMATION:
+ DBG(DBG_PARSING,
+ DBG_log(" need to parse targetInformation")
+ )
+ break;
+ case OID_NO_REV_AVAIL:
+ ac->noRevAvail = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case AC_OBJ_ALGORITHM:
+ ac->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case AC_OBJ_SIGNATURE:
+ ac->signature = object;
+ break;
- switch (objectID)
- {
- case AC_OBJ_CERTIFICATE:
- ac->certificate = object;
- break;
- case AC_OBJ_CERTIFICATE_INFO:
- ac->certificateInfo = object;
- break;
- case AC_OBJ_VERSION:
- ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", ac->version);
- )
- if (ac->version != 2)
- {
- plog("v%d attribute certificates are not supported"
- , ac->version);
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_ISSUER:
- ac->holderIssuer = get_directoryName(object, level, FALSE);
- break;
- case AC_OBJ_HOLDER_SERIAL:
- ac->holderSerial = object;
- break;
- case AC_OBJ_ENTITY_NAME:
- ac->entityName = get_directoryName(object, level, TRUE);
- break;
- case AC_OBJ_ISSUER_NAME:
- ac->issuerName = get_directoryName(object, level, FALSE);
- break;
- case AC_OBJ_SIG_ALG:
- ac->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SERIAL_NUMBER:
- ac->serialNumber = object;
- break;
- case AC_OBJ_NOT_BEFORE:
- ac->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_NOT_AFTER:
- ac->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_ATTRIBUTE_TYPE:
- type = known_oid(object);
- break;
- case AC_OBJ_ATTRIBUTE_VALUE:
- {
- switch (type) {
- case OID_AUTHENTICATION_INFO:
- DBG(DBG_PARSING,
- DBG_log(" need to parse authenticationInfo")
- )
- break;
- case OID_ACCESS_IDENTITY:
- DBG(DBG_PARSING,
- DBG_log(" need to parse accessIdentity")
- )
- break;
- case OID_CHARGING_IDENTITY:
- ac->charging = parse_ietfAttrSyntax(object, level);
- break;
- case OID_GROUP:
- ac->groups = parse_ietfAttrSyntax(object, level);
- break;
- case OID_ROLE:
- parse_roleSyntax(object, level);
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case AC_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case AC_OBJ_EXTN_VALUE:
- {
- switch (extn_oid) {
- case OID_CRL_DISTRIBUTION_POINTS:
- DBG(DBG_PARSING,
- DBG_log(" need to parse crlDistributionPoints")
- )
- break;
- case OID_AUTHORITY_KEY_ID:
- parse_authorityKeyIdentifier(object, level
- , &ac->authKeyID, &ac->authKeySerialNumber);
- break;
- case OID_TARGET_INFORMATION:
- DBG(DBG_PARSING,
- DBG_log(" need to parse targetInformation")
- )
- break;
- case OID_NO_REV_AVAIL:
- ac->noRevAvail = TRUE;
- break;
default:
- break;
+ break;
}
- }
- break;
- case AC_OBJ_ALGORITHM:
- ac->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SIGNATURE:
- ac->signature = object;
- break;
-
- default:
- break;
}
- objectID++;
- }
- time(&ac->installed);
- return TRUE;
+ success = parser->success(parser);
+ time(&ac->installed);
+
+end:
+ parser->destroy(parser);
+ return success;
}
-/*
- * release an ietfAttribute, free it if count reaches zero
+/**
+ * Release an ietfAttribute, free it if count reaches zero
*/
-static void
-release_ietfAttr(ietfAttr_t* attr)
+static void release_ietfAttr(ietfAttr_t* attr)
{
- if (--attr->count == 0)
- {
- ietfAttrList_t **plist = &ietfAttributes;
- ietfAttrList_t *list = *plist;
-
- while (list->attr != attr)
+ if (--attr->count == 0)
{
- plist = &list->next;
- list = *plist;
+ ietfAttrList_t **plist = &ietfAttributes;
+ ietfAttrList_t *list = *plist;
+
+ while (list->attr != attr)
+ {
+ plist = &list->next;
+ list = *plist;
+ }
+ *plist = list->next;
+
+ free(attr->value.ptr);
+ free(attr);
+ free(list);
}
- *plist = list->next;
-
- pfree(attr->value.ptr);
- pfree(attr);
- pfree(list);
- }
}
-/*
- * free an ietfAttrList
+/**
+ * Free an ietfAttrList
*/
-void
-free_ietfAttrList(ietfAttrList_t* list)
+void free_ietfAttrList(ietfAttrList_t* list)
{
- while (list != NULL)
- {
- ietfAttrList_t *el = list;
-
- release_ietfAttr(el->attr);
- list = list->next;
- pfree(el);
- }
+ while (list != NULL)
+ {
+ ietfAttrList_t *el = list;
+
+ release_ietfAttr(el->attr);
+ list = list->next;
+ free(el);
+ }
}
-/*
- * free a X.509 attribute certificate
+/**
+ * Free a X.509 attribute certificate
*/
-void
-free_acert(x509acert_t *ac)
+void free_acert(x509acert_t *ac)
{
- if (ac != NULL)
- {
- free_ietfAttrList(ac->charging);
- free_ietfAttrList(ac->groups);
- pfreeany(ac->certificate.ptr);
- pfree(ac);
- }
+ if (ac != NULL)
+ {
+ free_ietfAttrList(ac->charging);
+ free_ietfAttrList(ac->groups);
+ free(ac->certificate.ptr);
+ free(ac);
+ }
}
-/*
- * free first X.509 attribute certificate in the chained list
+/**
+ * Free first X.509 attribute certificate in the chained list
*/
-static void
-free_first_acert(void)
+static void free_first_acert(void)
{
- x509acert_t *first = x509acerts;
- x509acerts = first->next;
- free_acert(first);
+ x509acert_t *first = x509acerts;
+ x509acerts = first->next;
+ free_acert(first);
}
-/*
+/**
* Free all attribute certificates in the chained list
*/
-void
-free_acerts(void)
-{
- while (x509acerts != NULL)
- free_first_acert();
+void free_acerts(void)
+{
+ while (x509acerts != NULL)
+ free_first_acert();
}
-/*
- * get a X.509 attribute certificate for a given holder
+/**
+ * Get a X.509 attribute certificate for a given holder
*/
-x509acert_t*
-get_x509acert(chunk_t issuer, chunk_t serial)
+x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial)
{
- x509acert_t *ac = x509acerts;
- x509acert_t *prev_ac = NULL;
+ x509acert_t *ac = x509acerts;
+ x509acert_t *prev_ac = NULL;
- while (ac != NULL)
- {
- if (same_dn(issuer, ac->holderIssuer)
- && same_serial(serial, ac->holderSerial))
+ while (ac != NULL)
{
- if (ac!= x509acerts)
- {
- /* bring the certificate up front */
- prev_ac->next = ac->next;
- ac->next = x509acerts;
- x509acerts = ac;
- }
- return ac;
+ if (same_dn(issuer, ac->holderIssuer)
+ && same_serial(serial, ac->holderSerial))
+ {
+ if (ac!= x509acerts)
+ {
+ /* bring the certificate up front */
+ prev_ac->next = ac->next;
+ ac->next = x509acerts;
+ x509acerts = ac;
+ }
+ return ac;
+ }
+ prev_ac = ac;
+ ac = ac->next;
}
- prev_ac = ac;
- ac = ac->next;
- }
- return NULL;
+ return NULL;
}
-/*
- * add a X.509 attribute certificate to the chained list
+/**
+ * Add a X.509 attribute certificate to the chained list
*/
-static void
-add_acert(x509acert_t *ac)
+static void add_acert(x509acert_t *ac)
{
- x509acert_t *old_ac = get_x509acert(ac->holderIssuer, ac->holderSerial);
+ x509acert_t *old_ac = get_x509acert(ac->holderIssuer, ac->holderSerial);
- if (old_ac != NULL)
- {
- if (ac->notBefore >old_ac->notBefore)
- {
- /* delete the old attribute cert */
- free_first_acert();
- DBG(DBG_CONTROL,
- DBG_log("attribute cert is newer - existing cert deleted")
- )
- }
- else
+ if (old_ac != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("attribute cert is not newer - existing cert kept");
- )
- free_acert(ac);
- return;
+ if (ac->notBefore >old_ac->notBefore)
+ {
+ /* delete the old attribute cert */
+ free_first_acert();
+ DBG(DBG_CONTROL,
+ DBG_log("attribute cert is newer - existing cert deleted")
+ )
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("attribute cert is not newer - existing cert kept");
+ )
+ free_acert(ac);
+ return;
+ }
}
- }
- plog("attribute cert added");
+ plog("attribute cert added");
- /* insert new attribute cert at the root of the chain */
- ac->next = x509acerts;
- x509acerts = ac;
+ /* insert new attribute cert at the root of the chain */
+ ac->next = x509acerts;
+ x509acerts = ac;
}
-/* verify the validity of an attribute certificate by
+/**
+ * Verify the validity of an attribute certificate by
* checking the notBefore and notAfter dates
*/
-static err_t
-check_ac_validity(const x509acert_t *ac)
+static err_t check_ac_validity(const x509acert_t *ac)
{
- time_t current_time;
-
- time(&current_time);
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" not before : %s", timetoa(&ac->notBefore, TRUE));
- DBG_log(" current time: %s", timetoa(&current_time, TRUE));
- DBG_log(" not after : %s", timetoa(&ac->notAfter, TRUE));
- )
-
- if (current_time < ac->notBefore)
- return "attribute certificate is not valid yet";
- if (current_time > ac->notAfter)
- return "attribute certificate has expired";
- else
- return NULL;
+ time_t current_time;
+
+ time(&current_time);
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" not before : %T", &ac->notBefore, TRUE);
+ DBG_log(" current time: %T", &current_time, TRUE);
+ DBG_log(" not after : %T", &ac->notAfter, TRUE);
+ )
+
+ if (current_time < ac->notBefore)
+ return "attribute certificate is not valid yet";
+ if (current_time > ac->notAfter)
+ return "attribute certificate has expired";
+ else
+ return NULL;
}
-/*
+/**
* verifies a X.509 attribute certificate
*/
-bool
-verify_x509acert(x509acert_t *ac, bool strict)
+bool verify_x509acert(x509acert_t *ac, bool strict)
{
- u_char buf[BUF_LEN];
- x509cert_t *aacert;
- err_t ugh = NULL;
- time_t valid_until = ac->notAfter;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, ac->entityName);
- DBG_log("holder: '%s'",buf);
- dntoa(buf, BUF_LEN, ac->issuerName);
- DBG_log("issuer: '%s'",buf);
- )
-
- ugh = check_ac_validity(ac);
-
- if (ugh != NULL)
- {
- plog("%s", ugh);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("attribute certificate is valid")
- )
-
- lock_authcert_list("verify_x509acert");
- aacert = get_authcert(ac->issuerName, ac->authKeySerialNumber
- , ac->authKeyID, AUTH_AA);
- unlock_authcert_list("verify_x509acert");
-
- if (aacert == NULL)
- {
- plog("issuer aacert not found");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("issuer aacert found")
- )
-
- if (!check_signature(ac->certificateInfo, ac->signature
- , ac->algorithm, ac->algorithm, aacert))
- {
- plog("attribute certificate signature is invalid");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("attribute certificate signature is valid");
- )
+ u_char buf[BUF_LEN];
+ x509cert_t *aacert;
+ err_t ugh = NULL;
+ time_t valid_until = ac->notAfter;
- return verify_x509cert(aacert, strict, &valid_until);
+ DBG(DBG_CONTROL,
+ dntoa(buf, BUF_LEN, ac->entityName);
+ DBG_log("holder: '%s'",buf);
+ dntoa(buf, BUF_LEN, ac->issuerName);
+ DBG_log("issuer: '%s'",buf);
+ )
+
+ ugh = check_ac_validity(ac);
+
+ if (ugh != NULL)
+ {
+ plog("%s", ugh);
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("attribute certificate is valid")
+ )
+
+ lock_authcert_list("verify_x509acert");
+ aacert = get_authcert(ac->issuerName, ac->authKeySerialNumber
+ , ac->authKeyID, AUTH_AA);
+ unlock_authcert_list("verify_x509acert");
+
+ if (aacert == NULL)
+ {
+ plog("issuer aacert not found");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("issuer aacert found")
+ )
+
+ if (!x509_check_signature(ac->certificateInfo, ac->signature, ac->algorithm,
+ aacert))
+ {
+ plog("attribute certificate signature is invalid");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("attribute certificate signature is valid");
+ )
+
+ return verify_x509cert(aacert, strict, &valid_until);
}
-/*
+/**
* Loads X.509 attribute certificates
*/
-void
-load_acerts(void)
+void load_acerts(void)
{
- u_char buf[BUF_LEN];
-
- /* change directory to specified path */
- u_char *save_dir = getcwd(buf, BUF_LEN);
-
- if (!chdir(A_CERT_PATH))
- {
- struct dirent **filelist;
- int n;
+ u_char buf[BUF_LEN];
- plog("Changing to directory '%s'",A_CERT_PATH);
- n = scandir(A_CERT_PATH, &filelist, file_select, alphasort);
+ /* change directory to specified path */
+ u_char *save_dir = getcwd(buf, BUF_LEN);
- if (n > 0)
+ if (!chdir(A_CERT_PATH))
{
- while (n--)
- {
- chunk_t blob = empty_chunk;
- bool pgp = FALSE;
+ struct dirent **filelist;
+ int n;
+
+ plog("Changing to directory '%s'",A_CERT_PATH);
+ n = scandir(A_CERT_PATH, &filelist, file_select, alphasort);
- if (load_coded_file(filelist[n]->d_name, NULL, "acert", &blob, &pgp))
+ if (n > 0)
{
- x509acert_t *ac = alloc_thing(x509acert_t, "x509acert");
-
- *ac = empty_ac;
-
- if (parse_ac(blob, ac)
- && verify_x509acert(ac, FALSE))
- add_acert(ac);
- else
- free_acert(ac);
+ while (n--)
+ {
+ chunk_t blob = chunk_empty;
+ bool pgp = FALSE;
+
+ if (load_coded_file(filelist[n]->d_name, NULL, "acert", &blob, &pgp))
+ {
+ x509acert_t *ac = malloc_thing(x509acert_t);
+
+ *ac = empty_ac;
+
+ if (parse_ac(blob, ac)
+ && verify_x509acert(ac, FALSE))
+ add_acert(ac);
+ else
+ free_acert(ac);
+ }
+ free(filelist[n]);
+ }
+ free(filelist);
}
- free(filelist[n]);
- }
- free(filelist);
}
- }
- /* restore directory path */
- ignore_result(chdir(save_dir));
+ /* restore directory path */
+ ignore_result(chdir(save_dir));
}
-/*
+/**
* lists group attributes separated by commas on a single line
*/
-void
-format_groups(const ietfAttrList_t *list, char *buf, int len)
+void format_groups(const ietfAttrList_t *list, char *buf, int len)
{
- bool first_group = TRUE;
-
- while (list != NULL && len > 0)
- {
- ietfAttr_t *attr = list->attr;
+ bool first_group = TRUE;
- if (attr->kind == IETF_ATTRIBUTE_OCTETS
- || attr->kind == IETF_ATTRIBUTE_STRING)
+ while (list != NULL && len > 0)
{
- int written = snprintf(buf, len, "%s%.*s"
- , (first_group)? "" : ", "
- , (int)attr->value.len, attr->value.ptr);
-
- first_group = FALSE;
-
- /* return value of snprintf() up to glibc 2.0.6 */
- if (written < 0)
- break;
-
- buf += written;
- len -= written;
+ ietfAttr_t *attr = list->attr;
+
+ if (attr->kind == IETF_ATTRIBUTE_OCTETS
+ || attr->kind == IETF_ATTRIBUTE_STRING)
+ {
+ int written = snprintf(buf, len, "%s%.*s"
+ , (first_group)? "" : ", "
+ , (int)attr->value.len, attr->value.ptr);
+
+ first_group = FALSE;
+
+ /* return value of snprintf() up to glibc 2.0.6 */
+ if (written < 0)
+ break;
+
+ buf += written;
+ len -= written;
+ }
+ list = list->next;
}
- list = list->next;
- }
}
-/*
+/**
* list all X.509 attribute certificates in the chained list
*/
-void
-list_acerts(bool utc)
+void list_acerts(bool utc)
{
- x509acert_t *ac = x509acerts;
- time_t now;
-
- /* determine the current time */
- time(&now);
+ x509acert_t *ac = x509acerts;
+ time_t now;
- if (ac != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 Attribute Certificates:");
- whack_log(RC_COMMENT, " ");
- }
+ /* determine the current time */
+ time(&now);
- while (ac != NULL)
- {
- u_char buf[BUF_LEN];
-
- whack_log(RC_COMMENT, "%s",timetoa(&ac->installed, utc));
- if (ac->entityName.ptr != NULL)
+ if (ac != NULL)
{
- dntoa(buf, BUF_LEN, ac->entityName);
- whack_log(RC_COMMENT, " holder: '%s'", buf);
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of X.509 Attribute Certificates:");
+ whack_log(RC_COMMENT, " ");
}
- if (ac->holderIssuer.ptr != NULL)
- {
- dntoa(buf, BUF_LEN, ac->holderIssuer);
- whack_log(RC_COMMENT, " hissuer: '%s'", buf);
- }
- if (ac->holderSerial.ptr != NULL)
- {
- datatot(ac->holderSerial.ptr, ac->holderSerial.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " hserial: %s", buf);
- }
- if (ac->groups != NULL)
- {
- format_groups(ac->groups, buf, BUF_LEN);
- whack_log(RC_COMMENT, " groups: %s", buf);
- }
- dntoa(buf, BUF_LEN, ac->issuerName);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- datatot(ac->serialNumber.ptr, ac->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s", buf);
- whack_log(RC_COMMENT, " validity: not before %s %s",
- timetoa(&ac->notBefore, utc),
- (ac->notBefore < now)?"ok":"fatal (not valid yet)");
- whack_log(RC_COMMENT, " not after %s %s",
- timetoa(&ac->notAfter, utc),
- check_expiry(ac->notAfter, ACERT_WARNING_INTERVAL, TRUE));
- if (ac->authKeyID.ptr != NULL)
- {
- datatot(ac->authKeyID.ptr, ac->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (ac->authKeySerialNumber.ptr != NULL)
+
+ while (ac != NULL)
{
- datatot(ac->authKeySerialNumber.ptr, ac->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
+ u_char buf[BUF_LEN];
+
+ whack_log(RC_COMMENT, "%T", &ac->installed, utc);
+ if (ac->entityName.ptr != NULL)
+ {
+ dntoa(buf, BUF_LEN, ac->entityName);
+ whack_log(RC_COMMENT, " holder: '%s'", buf);
+ }
+ if (ac->holderIssuer.ptr != NULL)
+ {
+ dntoa(buf, BUF_LEN, ac->holderIssuer);
+ whack_log(RC_COMMENT, " hissuer: '%s'", buf);
+ }
+ if (ac->holderSerial.ptr != NULL)
+ {
+ datatot(ac->holderSerial.ptr, ac->holderSerial.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " hserial: %s", buf);
+ }
+ if (ac->groups != NULL)
+ {
+ format_groups(ac->groups, buf, BUF_LEN);
+ whack_log(RC_COMMENT, " groups: %s", buf);
+ }
+ dntoa(buf, BUF_LEN, ac->issuerName);
+ whack_log(RC_COMMENT, " issuer: '%s'", buf);
+ datatot(ac->serialNumber.ptr, ac->serialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " serial: %s", buf);
+ whack_log(RC_COMMENT, " validity: not before %T %s",
+ &ac->notBefore, utc,
+ (ac->notBefore < now)?"ok":"fatal (not valid yet)");
+ whack_log(RC_COMMENT, " not after %T %s",
+ &ac->notAfter, utc,
+ check_expiry(ac->notAfter, ACERT_WARNING_INTERVAL, TRUE));
+ if (ac->authKeyID.ptr != NULL)
+ {
+ datatot(ac->authKeyID.ptr, ac->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (ac->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(ac->authKeySerialNumber.ptr, ac->authKeySerialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
- ac = ac->next;
- }
+ ac = ac->next;
+ }
}
-/*
+/**
* list all group attributes in alphabetical order
*/
-void
-list_groups(bool utc)
+void list_groups(bool utc)
{
- ietfAttrList_t *list = ietfAttributes;
-
- if (list != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Group Attributes:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (list != NULL)
- {
- ietfAttr_t *attr = list->attr;
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&attr->installed, utc),
- attr->count);
+ ietfAttrList_t *list = ietfAttributes;
- switch (attr->kind)
+ if (list != NULL)
{
- case IETF_ATTRIBUTE_OCTETS:
- case IETF_ATTRIBUTE_STRING:
- whack_log(RC_COMMENT, " %.*s", (int)attr->value.len, attr->value.ptr);
- break;
- case IETF_ATTRIBUTE_OID:
- whack_log(RC_COMMENT, " OID");
- break;
- default:
- break;
- }
-
- list = list->next;
- }
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of Group Attributes:");
+ whack_log(RC_COMMENT, " ");
+ }
+
+ while (list != NULL)
+ {
+ ietfAttr_t *attr = list->attr;
+
+ whack_log(RC_COMMENT, "%T, count: %d", &attr->installed, utc, attr->count);
+
+ switch (attr->kind)
+ {
+ case IETF_ATTRIBUTE_OCTETS:
+ case IETF_ATTRIBUTE_STRING:
+ whack_log(RC_COMMENT, " %.*s", (int)attr->value.len, attr->value.ptr);
+ break;
+ case IETF_ATTRIBUTE_OID:
+ whack_log(RC_COMMENT, " OID");
+ break;
+ default:
+ break;
+ }
+
+ list = list->next;
+ }
}
diff --git a/src/pluto/ac.h b/src/pluto/ac.h
index d60ad25af..bee016143 100644
--- a/src/pluto/ac.h
+++ b/src/pluto/ac.h
@@ -1,7 +1,7 @@
/* Support of X.509 attribute certificates
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter
-
+
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ac.h 3253 2007-10-06 21:39:00Z andreas $
*/
#ifndef _AC_H
@@ -22,9 +20,9 @@
/* definition of ietfAttribute kinds */
typedef enum {
- IETF_ATTRIBUTE_OCTETS = 0,
- IETF_ATTRIBUTE_OID = 1,
- IETF_ATTRIBUTE_STRING = 2
+ IETF_ATTRIBUTE_OCTETS = 0,
+ IETF_ATTRIBUTE_OID = 1,
+ IETF_ATTRIBUTE_STRING = 2
} ietfAttribute_t;
/* access structure for an ietfAttribute */
@@ -32,17 +30,17 @@ typedef enum {
typedef struct ietfAttr ietfAttr_t;
struct ietfAttr {
- time_t installed;
- int count;
+ time_t installed;
+ int count;
ietfAttribute_t kind;
- chunk_t value;
+ chunk_t value;
};
typedef struct ietfAttrList ietfAttrList_t;
struct ietfAttrList {
ietfAttrList_t *next;
- ietfAttr_t *attr;
+ ietfAttr_t *attr;
};
@@ -52,31 +50,31 @@ typedef struct x509acert x509acert_t;
struct x509acert {
x509acert_t *next;
- time_t installed;
- chunk_t certificate;
- chunk_t certificateInfo;
- u_int version;
- /* holder */
- /* baseCertificateID */
- chunk_t holderIssuer;
- chunk_t holderSerial;
- chunk_t entityName;
- /* v2Form */
- chunk_t issuerName;
- /* signature */
+ time_t installed;
+ chunk_t certificate;
+ chunk_t certificateInfo;
+ u_int version;
+ /* holder */
+ /* baseCertificateID */
+ chunk_t holderIssuer;
+ chunk_t holderSerial;
+ chunk_t entityName;
+ /* v2Form */
+ chunk_t issuerName;
+ /* signature */
int sigAlg;
- chunk_t serialNumber;
- /* attrCertValidityPeriod */
+ chunk_t serialNumber;
+ /* attrCertValidityPeriod */
time_t notBefore;
time_t notAfter;
- /* attributes */
+ /* attributes */
ietfAttrList_t *charging;
ietfAttrList_t *groups;
- /* extensions */
+ /* extensions */
chunk_t authKeyID;
chunk_t authKeySerialNumber;
- bool noRevAvail;
- /* signatureAlgorithm */
+ bool noRevAvail;
+ /* signatureAlgorithm */
int algorithm;
chunk_t signature;
};
@@ -88,7 +86,7 @@ extern void unshare_ietfAttrList(ietfAttrList_t **listp);
extern void free_ietfAttrList(ietfAttrList_t *list);
extern void decode_groups(char *groups, ietfAttrList_t **listp);
extern bool group_membership(const ietfAttrList_t *my_list
- , const char *conn, const ietfAttrList_t *conn_list);
+ , const char *conn, const ietfAttrList_t *conn_list);
extern bool parse_ac(chunk_t blob, x509acert_t *ac);
extern bool verify_x509acert(x509acert_t *ac, bool strict);
extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial);
diff --git a/src/pluto/adns.c b/src/pluto/adns.c
index a721d8837..95e22b96f 100644
--- a/src/pluto/adns.c
+++ b/src/pluto/adns.c
@@ -10,11 +10,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: adns.c 3252 2007-10-06 21:24:50Z andreas $
*/
-#ifndef USE_LWRES /* whole file! */
+#ifndef USE_LWRES /* whole file! */
/* This program executes as multiple processes. The Master process
* receives queries (struct adns_query messages) from Pluto and distributes
@@ -58,7 +56,7 @@
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
-#include <netdb.h> /* ??? for h_errno */
+#include <netdb.h> /* ??? for h_errno */
#include <freeswan.h>
@@ -70,11 +68,11 @@
#endif
#include "constants.h"
-#include "adns.h" /* needs <resolv.h> */
+#include "adns.h" /* needs <resolv.h> */
/* shared by all processes */
-static const char *name; /* program name, for messages */
+static const char *name; /* program name, for messages */
static bool debug = FALSE;
@@ -88,43 +86,43 @@ static bool debug = FALSE;
static enum helper_exit_status
read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
{
- size_t n = 0;
- size_t goal = minlen;
+ size_t n = 0;
+ size_t goal = minlen;
- do {
- ssize_t m = read(fd, stuff + n, goal - n);
+ do {
+ ssize_t m = read(fd, stuff + n, goal - n);
- if (m == -1)
- {
- if (errno != EINTR)
- {
- syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
- return HES_IO_ERROR_IN;
- }
- }
- else if (m == 0)
- {
- return HES_OK; /* treat empty message as EOF */
- }
- else
- {
- n += m;
- if (n >= sizeof(size_t))
- {
- goal = *(size_t *)(void *)stuff;
- if (goal < minlen || maxlen < goal)
+ if (m == -1)
{
- if (debug)
- fprintf(stderr, "%lu : [%lu, %lu]\n"
- , (unsigned long)goal
- , (unsigned long)minlen, (unsigned long)maxlen);
- return HES_BAD_LEN;
+ if (errno != EINTR)
+ {
+ syslog(LOG_ERR, "Input error on pipe: %s", strerror(errno));
+ return HES_IO_ERROR_IN;
+ }
}
- }
- }
- } while (n < goal);
+ else if (m == 0)
+ {
+ return HES_OK; /* treat empty message as EOF */
+ }
+ else
+ {
+ n += m;
+ if (n >= sizeof(size_t))
+ {
+ goal = *(size_t *)(void *)stuff;
+ if (goal < minlen || maxlen < goal)
+ {
+ if (debug)
+ fprintf(stderr, "%lu : [%lu, %lu]\n"
+ , (unsigned long)goal
+ , (unsigned long)minlen, (unsigned long)maxlen);
+ return HES_BAD_LEN;
+ }
+ }
+ }
+ } while (n < goal);
- return HES_CONTINUE;
+ return HES_CONTINUE;
}
/* Write a variable-length record to a pipe.
@@ -135,27 +133,27 @@ read_pipe(int fd, unsigned char *stuff, size_t minlen, size_t maxlen)
static enum helper_exit_status
write_pipe(int fd, const unsigned char *stuff)
{
- size_t len = *(const size_t *)(const void *)stuff;
- size_t n = 0;
+ size_t len = *(const size_t *)(const void *)stuff;
+ size_t n = 0;
- do {
- ssize_t m = write(fd, stuff + n, len - n);
+ do {
+ ssize_t m = write(fd, stuff + n, len - n);
- if (m == -1)
- {
- /* error, but ignore and retry if EINTR */
- if (errno != EINTR)
- {
- syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
- return HES_IO_ERROR_OUT;
- }
- }
- else
- {
- n += m;
- }
- } while (n != len);
- return HES_CONTINUE;
+ if (m == -1)
+ {
+ /* error, but ignore and retry if EINTR */
+ if (errno != EINTR)
+ {
+ syslog(LOG_ERR, "Output error from master: %s", strerror(errno));
+ return HES_IO_ERROR_OUT;
+ }
+ }
+ else
+ {
+ n += m;
+ }
+ } while (n != len);
+ return HES_CONTINUE;
}
/**************** worker process ****************/
@@ -171,14 +169,14 @@ write_pipe(int fd, const unsigned char *stuff)
*/
#if (__RES) <= 19960801
-# define OLD_RESOLVER 1
+# define OLD_RESOLVER 1
#endif
#ifdef OLD_RESOLVER
# define res_ninit(statp) res_init()
# define res_nquery(statp, dname, class, type, answer, anslen) \
- res_query(dname, class, type, answer, anslen)
+ res_query(dname, class, type, answer, anslen)
# define res_nclose(statp) res_close()
static struct __res_state *statp = &_res;
@@ -193,75 +191,75 @@ static res_state statp = &my_res_state;
static int
worker(int qfd, int afd)
{
- {
- int r = res_ninit(statp);
-
- if (r != 0)
{
- syslog(LOG_ERR, "cannot initialize resolver");
- return HES_RES_INIT;
- }
+ int r = res_ninit(statp);
+
+ if (r != 0)
+ {
+ syslog(LOG_ERR, "cannot initialize resolver");
+ return HES_RES_INIT;
+ }
#ifndef OLD_RESOLVER
- statp->options |= RES_ROTATE;
+ statp->options |= RES_ROTATE;
#endif
- statp->options |= RES_DEBUG;
- }
+ statp->options |= RES_DEBUG;
+ }
- for (;;)
- {
- struct adns_query q;
- struct adns_answer a;
+ for (;;)
+ {
+ struct adns_query q;
+ struct adns_answer a;
- enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
- , sizeof(q), sizeof(q));
+ enum helper_exit_status r = read_pipe(qfd, (unsigned char *)&q
+ , sizeof(q), sizeof(q));
- if (r != HES_CONTINUE)
- return r; /* some kind of exit */
+ if (r != HES_CONTINUE)
+ return r; /* some kind of exit */
- if (q.qmagic != ADNS_Q_MAGIC)
- {
- syslog(LOG_ERR, "error in input from master: bad magic");
- return HES_BAD_MAGIC;
- }
+ if (q.qmagic != ADNS_Q_MAGIC)
+ {
+ syslog(LOG_ERR, "error in input from master: bad magic");
+ return HES_BAD_MAGIC;
+ }
- a.amagic = ADNS_A_MAGIC;
- a.serial = q.serial;
+ a.amagic = ADNS_A_MAGIC;
+ a.serial = q.serial;
- a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans));
- a.h_errno_val = h_errno;
+ a.result = res_nquery(statp, q.name_buf, C_IN, q.type, a.ans, sizeof(a.ans));
+ a.h_errno_val = h_errno;
- a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result);
+ a.len = offsetof(struct adns_answer, ans) + (a.result < 0? 0 : a.result);
#ifdef DEBUG
- if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
- || ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
- sleep(30); /* delay the answer */
+ if (((q.debugging & IMPAIR_DELAY_ADNS_KEY_ANSWER) && q.type == T_KEY)
+ || ((q.debugging & IMPAIR_DELAY_ADNS_TXT_ANSWER) && q.type == T_TXT))
+ sleep(30); /* delay the answer */
#endif
- /* write answer, possibly a bit at a time */
- r = write_pipe(afd, (const unsigned char *)&a);
+ /* write answer, possibly a bit at a time */
+ r = write_pipe(afd, (const unsigned char *)&a);
- if (r != HES_CONTINUE)
- return r; /* some kind of exit */
- }
+ if (r != HES_CONTINUE)
+ return r; /* some kind of exit */
+ }
}
/**************** master process ****************/
bool eof_from_pluto = FALSE;
-#define PLUTO_QFD 0 /* queries come on stdin */
-#define PLUTO_AFD 1 /* answers go out on stdout */
+#define PLUTO_QFD 0 /* queries come on stdin */
+#define PLUTO_AFD 1 /* answers go out on stdout */
#ifndef MAX_WORKERS
-# define MAX_WORKERS 10 /* number of in-flight queries */
+# define MAX_WORKERS 10 /* number of in-flight queries */
#endif
struct worker_info {
- int qfd; /* query pipe's file descriptor */
- int afd; /* answer pipe's file descriptor */
- pid_t pid;
- bool busy;
- void *continuation; /* of outstanding request */
+ int qfd; /* query pipe's file descriptor */
+ int afd; /* answer pipe's file descriptor */
+ pid_t pid;
+ bool busy;
+ void *continuation; /* of outstanding request */
};
static struct worker_info wi[MAX_WORKERS];
@@ -270,300 +268,300 @@ static struct worker_info *wi_roof = wi;
/* request FIFO */
struct query_list {
- struct query_list *next;
- struct adns_query aq;
+ struct query_list *next;
+ struct adns_query aq;
};
static struct query_list *oldest_query = NULL;
-static struct query_list *newest_query; /* undefined when oldest == NULL */
+static struct query_list *newest_query; /* undefined when oldest == NULL */
static struct query_list *free_queries = NULL;
static bool
spawn_worker(void)
{
- int qfds[2];
- int afds[2];
- pid_t p;
-
- if (pipe(qfds) != 0 || pipe(afds) != 0)
- {
- syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
- exit(HES_PIPE);
- }
-
- wi_roof->qfd = qfds[1]; /* write end of query pipe */
- wi_roof->afd = afds[0]; /* read end of answer pipe */
-
- p = fork();
- if (p == -1)
- {
- /* fork failed: ignore if at least one worker exists */
- if (wi_roof == wi)
+ int qfds[2];
+ int afds[2];
+ pid_t p;
+
+ if (pipe(qfds) != 0 || pipe(afds) != 0)
+ {
+ syslog(LOG_ERR, "pipe(2) failed: %s", strerror(errno));
+ exit(HES_PIPE);
+ }
+
+ wi_roof->qfd = qfds[1]; /* write end of query pipe */
+ wi_roof->afd = afds[0]; /* read end of answer pipe */
+
+ p = fork();
+ if (p == -1)
+ {
+ /* fork failed: ignore if at least one worker exists */
+ if (wi_roof == wi)
+ {
+ syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
+ exit(HES_FORK);
+ }
+ close(qfds[0]);
+ close(qfds[1]);
+ close(afds[0]);
+ close(afds[1]);
+ return FALSE;
+ }
+ else if (p == 0)
{
- syslog(LOG_ERR, "fork(2) error creating first worker: %s", strerror(errno));
- exit(HES_FORK);
+ /* child */
+ struct worker_info *w;
+
+ close(PLUTO_QFD);
+ close(PLUTO_AFD);
+ /* close all master pipes, including ours */
+ for (w = wi; w <= wi_roof; w++)
+ {
+ close(w->qfd);
+ close(w->afd);
+ }
+ exit(worker(qfds[0], afds[1]));
}
- close(qfds[0]);
- close(qfds[1]);
- close(afds[0]);
- close(afds[1]);
- return FALSE;
- }
- else if (p == 0)
- {
- /* child */
- struct worker_info *w;
-
- close(PLUTO_QFD);
- close(PLUTO_AFD);
- /* close all master pipes, including ours */
- for (w = wi; w <= wi_roof; w++)
+ else
{
- close(w->qfd);
- close(w->afd);
+ /* parent */
+ struct worker_info *w = wi_roof++;
+
+ w->pid = p;
+ w->busy = FALSE;
+ close(qfds[0]);
+ close(afds[1]);
+ return TRUE;
}
- exit(worker(qfds[0], afds[1]));
- }
- else
- {
- /* parent */
- struct worker_info *w = wi_roof++;
-
- w->pid = p;
- w->busy = FALSE;
- close(qfds[0]);
- close(afds[1]);
- return TRUE;
- }
}
static void
send_eof(struct worker_info *w)
{
- pid_t p;
- int status;
+ pid_t p;
+ int status;
- close(w->qfd);
- w->qfd = NULL_FD;
+ close(w->qfd);
+ w->qfd = NULL_FD;
- close(w->afd);
- w->afd = NULL_FD;
+ close(w->afd);
+ w->afd = NULL_FD;
- /* reap child */
- p = waitpid(w->pid, &status, 0);
- /* ignore result -- what could we do with it? */
+ /* reap child */
+ p = waitpid(w->pid, &status, 0);
+ /* ignore result -- what could we do with it? */
}
static void
forward_query(struct worker_info *w)
{
- struct query_list *q = oldest_query;
-
- if (q == NULL)
- {
- if (eof_from_pluto)
- send_eof(w);
- }
- else
- {
- enum helper_exit_status r
- = write_pipe(w->qfd, (const unsigned char *) &q->aq);
-
- if (r != HES_CONTINUE)
- exit(r);
-
- w->busy = TRUE;
-
- oldest_query = q->next;
- q->next = free_queries;
- free_queries = q;
- }
+ struct query_list *q = oldest_query;
+
+ if (q == NULL)
+ {
+ if (eof_from_pluto)
+ send_eof(w);
+ }
+ else
+ {
+ enum helper_exit_status r
+ = write_pipe(w->qfd, (const unsigned char *) &q->aq);
+
+ if (r != HES_CONTINUE)
+ exit(r);
+
+ w->busy = TRUE;
+
+ oldest_query = q->next;
+ q->next = free_queries;
+ free_queries = q;
+ }
}
static void
query(void)
{
- struct query_list *q = free_queries;
- enum helper_exit_status r;
+ struct query_list *q = free_queries;
+ enum helper_exit_status r;
- /* find an unused queue entry */
- if (q == NULL)
- {
- q = malloc(sizeof(*q));
+ /* find an unused queue entry */
if (q == NULL)
{
- syslog(LOG_ERR, "malloc(3) failed");
- exit(HES_MALLOC);
+ q = malloc(sizeof(*q));
+ if (q == NULL)
+ {
+ syslog(LOG_ERR, "malloc(3) failed");
+ exit(HES_MALLOC);
+ }
}
- }
- else
- {
- free_queries = q->next;
- }
-
- r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
- , sizeof(q->aq), sizeof(q->aq));
-
- if (r == HES_OK)
- {
- /* EOF: we're done, except for unanswered queries */
- struct worker_info *w;
-
- eof_from_pluto = TRUE;
- q->next = free_queries;
- free_queries = q;
-
- /* Send bye-bye to unbusy processes.
- * Note that if there are queued queries, there won't be
- * any non-busy workers.
- */
- for (w = wi; w != wi_roof; w++)
- if (!w->busy)
- send_eof(w);
- }
- else if (r != HES_CONTINUE)
- {
- exit(r);
- }
- else if (q->aq.qmagic != ADNS_Q_MAGIC)
- {
- syslog(LOG_ERR, "error in query from Pluto: bad magic");
- exit(HES_BAD_MAGIC);
- }
- else
- {
- struct worker_info *w;
-
- /* got a query */
-
- /* add it to FIFO */
- q->next = NULL;
- if (oldest_query == NULL)
- oldest_query = q;
else
- newest_query->next = q;
- newest_query = q;
+ {
+ free_queries = q->next;
+ }
+
+ r = read_pipe(PLUTO_QFD, (unsigned char *)&q->aq
+ , sizeof(q->aq), sizeof(q->aq));
- /* See if any worker available */
- for (w = wi; ; w++)
+ if (r == HES_OK)
{
- if (w == wi_roof)
- {
- /* no free worker */
- if (w == wi + MAX_WORKERS)
- break; /* no more to be created */
- /* make a new one */
- if (!spawn_worker())
- break; /* cannot create one at this time */
- }
- if (!w->busy)
- {
- /* assign first to free worker */
- forward_query(w);
- break;
- }
+ /* EOF: we're done, except for unanswered queries */
+ struct worker_info *w;
+
+ eof_from_pluto = TRUE;
+ q->next = free_queries;
+ free_queries = q;
+
+ /* Send bye-bye to unbusy processes.
+ * Note that if there are queued queries, there won't be
+ * any non-busy workers.
+ */
+ for (w = wi; w != wi_roof; w++)
+ if (!w->busy)
+ send_eof(w);
+ }
+ else if (r != HES_CONTINUE)
+ {
+ exit(r);
+ }
+ else if (q->aq.qmagic != ADNS_Q_MAGIC)
+ {
+ syslog(LOG_ERR, "error in query from Pluto: bad magic");
+ exit(HES_BAD_MAGIC);
+ }
+ else
+ {
+ struct worker_info *w;
+
+ /* got a query */
+
+ /* add it to FIFO */
+ q->next = NULL;
+ if (oldest_query == NULL)
+ oldest_query = q;
+ else
+ newest_query->next = q;
+ newest_query = q;
+
+ /* See if any worker available */
+ for (w = wi; ; w++)
+ {
+ if (w == wi_roof)
+ {
+ /* no free worker */
+ if (w == wi + MAX_WORKERS)
+ break; /* no more to be created */
+ /* make a new one */
+ if (!spawn_worker())
+ break; /* cannot create one at this time */
+ }
+ if (!w->busy)
+ {
+ /* assign first to free worker */
+ forward_query(w);
+ break;
+ }
+ }
}
- }
- return;
+ return;
}
static void
answer(struct worker_info *w)
{
- struct adns_answer a;
- enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
- , offsetof(struct adns_answer, ans), sizeof(a));
-
- if (r == HES_OK)
- {
- /* unexpected EOF */
- syslog(LOG_ERR, "unexpected EOF from worker");
- exit(HES_IO_ERROR_IN);
- }
- else if (r != HES_CONTINUE)
- {
- exit(r);
- }
- else if (a.amagic != ADNS_A_MAGIC)
- {
- syslog(LOG_ERR, "Input from worker error: bad magic");
- exit(HES_BAD_MAGIC);
- }
- else if (a.continuation != w->continuation)
- {
- /* answer doesn't match query */
- syslog(LOG_ERR, "Input from worker error: continuation mismatch");
- exit(HES_SYNC);
- }
- else
- {
- /* pass the answer on to Pluto */
- enum helper_exit_status r
- = write_pipe(PLUTO_AFD, (const unsigned char *) &a);
-
- if (r != HES_CONTINUE)
- exit(r);
- w->busy = FALSE;
- forward_query(w);
- }
+ struct adns_answer a;
+ enum helper_exit_status r = read_pipe(w->afd, (unsigned char *)&a
+ , offsetof(struct adns_answer, ans), sizeof(a));
+
+ if (r == HES_OK)
+ {
+ /* unexpected EOF */
+ syslog(LOG_ERR, "unexpected EOF from worker");
+ exit(HES_IO_ERROR_IN);
+ }
+ else if (r != HES_CONTINUE)
+ {
+ exit(r);
+ }
+ else if (a.amagic != ADNS_A_MAGIC)
+ {
+ syslog(LOG_ERR, "Input from worker error: bad magic");
+ exit(HES_BAD_MAGIC);
+ }
+ else if (a.continuation != w->continuation)
+ {
+ /* answer doesn't match query */
+ syslog(LOG_ERR, "Input from worker error: continuation mismatch");
+ exit(HES_SYNC);
+ }
+ else
+ {
+ /* pass the answer on to Pluto */
+ enum helper_exit_status r
+ = write_pipe(PLUTO_AFD, (const unsigned char *) &a);
+
+ if (r != HES_CONTINUE)
+ exit(r);
+ w->busy = FALSE;
+ forward_query(w);
+ }
}
/* assumption: input limited; accept blocking on output */
static int
master(void)
{
- for (;;)
- {
- fd_set readfds;
- int maxfd = PLUTO_QFD; /* approximate lower bound */
- int ndes = 0;
- struct worker_info *w;
-
- FD_ZERO(&readfds);
- if (!eof_from_pluto)
+ for (;;)
{
- FD_SET(PLUTO_QFD, &readfds);
- ndes++;
- }
- for (w = wi; w != wi_roof; w++)
- {
- if (w->busy)
- {
- FD_SET(w->afd, &readfds);
- ndes++;
- if (maxfd < w->afd)
- maxfd = w->afd;
- }
- }
+ fd_set readfds;
+ int maxfd = PLUTO_QFD; /* approximate lower bound */
+ int ndes = 0;
+ struct worker_info *w;
+
+ FD_ZERO(&readfds);
+ if (!eof_from_pluto)
+ {
+ FD_SET(PLUTO_QFD, &readfds);
+ ndes++;
+ }
+ for (w = wi; w != wi_roof; w++)
+ {
+ if (w->busy)
+ {
+ FD_SET(w->afd, &readfds);
+ ndes++;
+ if (maxfd < w->afd)
+ maxfd = w->afd;
+ }
+ }
- if (ndes == 0)
- return HES_OK; /* done! */
+ if (ndes == 0)
+ return HES_OK; /* done! */
- do {
- ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
- } while (ndes == -1 && errno == EINTR);
- if (ndes == -1)
- {
- syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
- exit(HES_IO_ERROR_SELECT);
- }
- else if (ndes > 0)
- {
- if (FD_ISSET(PLUTO_QFD, &readfds))
- {
- query();
- ndes--;
- }
- for (w = wi; ndes > 0 && w != wi_roof; w++)
- {
- if (w->busy && FD_ISSET(w->afd, &readfds))
+ do {
+ ndes = select(maxfd + 1, &readfds, NULL, NULL, NULL);
+ } while (ndes == -1 && errno == EINTR);
+ if (ndes == -1)
+ {
+ syslog(LOG_ERR, "select(2) error: %s", strerror(errno));
+ exit(HES_IO_ERROR_SELECT);
+ }
+ else if (ndes > 0)
{
- answer(w);
- ndes--;
+ if (FD_ISSET(PLUTO_QFD, &readfds))
+ {
+ query();
+ ndes--;
+ }
+ for (w = wi; ndes > 0 && w != wi_roof; w++)
+ {
+ if (w->busy && FD_ISSET(w->afd, &readfds))
+ {
+ answer(w);
+ ndes--;
+ }
+ }
}
- }
}
- }
}
/* Not to be invoked by strangers -- user hostile.
@@ -574,42 +572,42 @@ master(void)
static void
adns_usage(const char *fmt, const char *arg)
{
- const char **sp = ipsec_copyright_notice();
+ const char **sp = ipsec_copyright_notice();
- fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n");
+ fprintf(stderr, "INTERNAL TO PLUTO: DO NOT EXECUTE\n");
- fprintf(stderr, fmt, arg);
- fprintf(stderr, "\n%s\n", ipsec_version_string());
+ fprintf(stderr, fmt, arg);
+ fprintf(stderr, "\nstrongSwan "VERSION"\n");
- for (; *sp != NULL; sp++)
- fprintf(stderr, "%s\n", *sp);
+ for (; *sp != NULL; sp++)
+ fprintf(stderr, "%s\n", *sp);
- syslog(LOG_ERR, fmt, arg);
- exit(HES_INVOCATION);
+ syslog(LOG_ERR, fmt, arg);
+ exit(HES_INVOCATION);
}
int
main(int argc UNUSED, char **argv)
{
- int i = 1;
+ int i = 1;
- name = argv[0];
+ name = argv[0];
- while (i < argc)
- {
- if (streq(argv[i], "-d"))
+ while (i < argc)
{
- i++;
- debug = TRUE;
- }
- else
- {
- adns_usage("unexpected argument \"%s\"", argv[i]);
- /*NOTREACHED*/
+ if (streq(argv[i], "-d"))
+ {
+ i++;
+ debug = TRUE;
+ }
+ else
+ {
+ adns_usage("unexpected argument \"%s\"", argv[i]);
+ /*NOTREACHED*/
+ }
}
- }
- return master();
+ return master();
}
#endif /* !USE_LWRES */
diff --git a/src/pluto/adns.h b/src/pluto/adns.h
index f2d0b28bd..f564be232 100644
--- a/src/pluto/adns.h
+++ b/src/pluto/adns.h
@@ -10,11 +10,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: adns.h 3252 2007-10-06 21:24:50Z andreas $
*/
-#ifndef USE_LWRES /* whole file! */
+#ifndef USE_LWRES /* whole file! */
/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
* so we build some of our own :-(
@@ -38,38 +36,38 @@
*/
struct adns_query {
- size_t len;
- unsigned int qmagic;
- unsigned long serial;
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
- u_char name_buf[NS_MAXDNAME + 2];
- int type; /* T_KEY or T_TXT */
+ size_t len;
+ unsigned int qmagic;
+ unsigned long serial;
+ lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
+ u_char name_buf[NS_MAXDNAME + 2];
+ int type; /* T_KEY or T_TXT */
};
struct adns_answer {
- size_t len;
- unsigned int amagic;
- unsigned long serial;
- struct adns_continuation *continuation;
- int result;
- int h_errno_val;
- u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
+ size_t len;
+ unsigned int amagic;
+ unsigned long serial;
+ struct adns_continuation *continuation;
+ int result;
+ int h_errno_val;
+ u_char ans[NS_PACKETSZ * 10]; /* very probably bigger than necessary */
};
enum helper_exit_status {
- HES_CONTINUE = -1, /* not an exit */
- HES_OK = 0, /* all's well that ends well (perhaps EOF) */
- HES_INVOCATION, /* improper invocation */
- HES_IO_ERROR_SELECT, /* IO error in select() */
- HES_MALLOC, /* malloc failed */
- HES_IO_ERROR_IN, /* error reading pipe */
- HES_IO_ERROR_OUT, /* error reading pipe */
- HES_PIPE, /* pipe(2) failed */
- HES_SYNC, /* answer from worker doesn't match query */
- HES_FORK, /* fork(2) failed */
- HES_RES_INIT, /* resolver initialization failed */
- HES_BAD_LEN, /* implausible .len field */
- HES_BAD_MAGIC, /* .magic field wrong */
+ HES_CONTINUE = -1, /* not an exit */
+ HES_OK = 0, /* all's well that ends well (perhaps EOF) */
+ HES_INVOCATION, /* improper invocation */
+ HES_IO_ERROR_SELECT, /* IO error in select() */
+ HES_MALLOC, /* malloc failed */
+ HES_IO_ERROR_IN, /* error reading pipe */
+ HES_IO_ERROR_OUT, /* error reading pipe */
+ HES_PIPE, /* pipe(2) failed */
+ HES_SYNC, /* answer from worker doesn't match query */
+ HES_FORK, /* fork(2) failed */
+ HES_RES_INIT, /* resolver initialization failed */
+ HES_BAD_LEN, /* implausible .len field */
+ HES_BAD_MAGIC, /* .magic field wrong */
};
#endif /* !USE_LWRES */
diff --git a/src/pluto/alg/ike_alg_aes.c b/src/pluto/alg/ike_alg_aes.c
deleted file mode 100644
index c635af723..000000000
--- a/src/pluto/alg/ike_alg_aes.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libaes/aes_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define AES_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define AES_KEY_MIN_LEN 128
-#define AES_KEY_DEF_LEN 128
-#define AES_KEY_MAX_LEN 256
-
-static void
-do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- aes_context aes_ctx;
- char iv_bak[AES_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
- aes_set_key(&aes_ctx, key, key_size, 0);
-
- /*
- * my AES cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak, (char*) buf + buf_len - AES_CBC_BLOCK_SIZE
- , AES_CBC_BLOCK_SIZE);
-
- SS_AES_cbc_encrypt(&aes_ctx, buf, buf, buf_len, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_len-AES_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, AES_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc algo_aes =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_AES_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(aes_context),
- enc_blocksize: AES_CBC_BLOCK_SIZE,
- keyminlen: AES_KEY_MIN_LEN,
- keydeflen: AES_KEY_DEF_LEN,
- keymaxlen: AES_KEY_MAX_LEN,
- do_crypt: do_aes,
-};
-
-int ike_alg_aes_init(void);
-
-int
-ike_alg_aes_init(void)
-{
- int ret = ike_alg_register_enc(&algo_aes);
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_aes_init
-*/
diff --git a/src/pluto/alg/ike_alg_blowfish.c b/src/pluto/alg/ike_alg_blowfish.c
deleted file mode 100644
index 2bbef051b..000000000
--- a/src/pluto/alg/ike_alg_blowfish.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libblowfish/blowfish.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define BLOWFISH_CBC_BLOCK_SIZE 8 /* block size */
-#define BLOWFISH_KEY_MIN_LEN 128
-#define BLOWFISH_KEY_MAX_LEN 448
-
-
-static void
-do_blowfish(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- BF_KEY bf_ctx;
-
- BF_set_key(&bf_ctx, key_size , key);
- BF_cbc_encrypt(buf, buf, buf_len, &bf_ctx, iv, enc);
-}
-
-struct encrypt_desc algo_blowfish =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_BLOWFISH_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(BF_KEY),
- enc_blocksize: BLOWFISH_CBC_BLOCK_SIZE,
- keyminlen: BLOWFISH_KEY_MIN_LEN,
- keydeflen: BLOWFISH_KEY_MIN_LEN,
- keymaxlen: BLOWFISH_KEY_MAX_LEN,
- do_crypt: do_blowfish,
-};
-
-int ike_alg_blowfish_init(void);
-
-int
-ike_alg_blowfish_init(void)
-{
- int ret = ike_alg_register_enc(&algo_blowfish);
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_blowfish_init
-*/
diff --git a/src/pluto/alg/ike_alg_serpent.c b/src/pluto/alg/ike_alg_serpent.c
deleted file mode 100644
index fb01caa41..000000000
--- a/src/pluto/alg/ike_alg_serpent.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libserpent/serpent_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define SERPENT_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define SERPENT_KEY_MIN_LEN 128
-#define SERPENT_KEY_DEF_LEN 128
-#define SERPENT_KEY_MAX_LEN 256
-
-static void
-do_serpent(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- serpent_context serpent_ctx;
- char iv_bak[SERPENT_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
-
- serpent_set_key(&serpent_ctx, key, key_size);
- /*
- * my SERPENT cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak,
- (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE,
- SERPENT_CBC_BLOCK_SIZE);
-
- serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc encrypt_desc_serpent =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_SERPENT_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(struct serpent_context),
- enc_blocksize: SERPENT_CBC_BLOCK_SIZE,
- keyminlen: SERPENT_KEY_MIN_LEN,
- keydeflen: SERPENT_KEY_DEF_LEN,
- keymaxlen: SERPENT_KEY_MAX_LEN,
- do_crypt: do_serpent,
-};
-
-int ike_alg_serpent_init(void);
-
-int
-ike_alg_serpent_init(void)
-{
- int ret = ike_alg_register_enc(&encrypt_desc_serpent);
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_serpent_init
-*/
diff --git a/src/pluto/alg/ike_alg_sha2.c b/src/pluto/alg/ike_alg_sha2.c
deleted file mode 100644
index 6b7c8438c..000000000
--- a/src/pluto/alg/ike_alg_sha2.c
+++ /dev/null
@@ -1,634 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libsha2/sha2.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-static void
-sha256_hash_final(u_char *hash, sha256_context *ctx)
-{
- sha256_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_256_DIGEST_SIZE);
-}
-
-static void
-sha384_hash_final(u_char *hash, sha512_context *ctx)
-{
- sha512_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_384_DIGEST_SIZE);
-}
-
-static void
-sha512_hash_final(u_char *hash, sha512_context *ctx)
-{
- sha512_final(ctx);
- memcpy(hash, ctx->sha_out, SHA2_512_DIGEST_SIZE);
-}
-
-/* SHA-256 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha256_short2_msg[] = {
- 0x19
-};
-
-static const u_char sha256_short2_msg_digest[] = {
- 0x68, 0xaa, 0x2e, 0x2e, 0xe5, 0xdf, 0xf9, 0x6e,
- 0x33, 0x55, 0xe6, 0xc7, 0xee, 0x37, 0x3e, 0x3d,
- 0x6a, 0x4e, 0x17, 0xf7, 0x5f, 0x95, 0x18, 0xd8,
- 0x43, 0x70, 0x9c, 0x0c, 0x9b, 0xc3, 0xe3, 0xd4
-};
-
-static const u_char sha256_short4_msg[] = {
- 0xe3, 0xd7, 0x25, 0x70, 0xdc, 0xdd, 0x78, 0x7c,
- 0xe3, 0x88, 0x7a, 0xb2, 0xcd, 0x68, 0x46, 0x52
-};
-
-static const u_char sha256_short4_msg_digest[] = {
- 0x17, 0x5e, 0xe6, 0x9b, 0x02, 0xba, 0x9b, 0x58,
- 0xe2, 0xb0, 0xa5, 0xfd, 0x13, 0x81, 0x9c, 0xea,
- 0x57, 0x3f, 0x39, 0x40, 0xa9, 0x4f, 0x82, 0x51,
- 0x28, 0xcf, 0x42, 0x09, 0xbe, 0xab, 0xb4, 0xe8
-};
-
-static const u_char sha256_long2_msg[] = {
- 0x83, 0x26, 0x75, 0x4e, 0x22, 0x77, 0x37, 0x2f,
- 0x4f, 0xc1, 0x2b, 0x20, 0x52, 0x7a, 0xfe, 0xf0,
- 0x4d, 0x8a, 0x05, 0x69, 0x71, 0xb1, 0x1a, 0xd5,
- 0x71, 0x23, 0xa7, 0xc1, 0x37, 0x76, 0x00, 0x00,
- 0xd7, 0xbe, 0xf6, 0xf3, 0xc1, 0xf7, 0xa9, 0x08,
- 0x3a, 0xa3, 0x9d, 0x81, 0x0d, 0xb3, 0x10, 0x77,
- 0x7d, 0xab, 0x8b, 0x1e, 0x7f, 0x02, 0xb8, 0x4a,
- 0x26, 0xc7, 0x73, 0x32, 0x5f, 0x8b, 0x23, 0x74,
- 0xde, 0x7a, 0x4b, 0x5a, 0x58, 0xcb, 0x5c, 0x5c,
- 0xf3, 0x5b, 0xce, 0xe6, 0xfb, 0x94, 0x6e, 0x5b,
- 0xd6, 0x94, 0xfa, 0x59, 0x3a, 0x8b, 0xeb, 0x3f,
- 0x9d, 0x65, 0x92, 0xec, 0xed, 0xaa, 0x66, 0xca,
- 0x82, 0xa2, 0x9d, 0x0c, 0x51, 0xbc, 0xf9, 0x33,
- 0x62, 0x30, 0xe5, 0xd7, 0x84, 0xe4, 0xc0, 0xa4,
- 0x3f, 0x8d, 0x79, 0xa3, 0x0a, 0x16, 0x5c, 0xba,
- 0xbe, 0x45, 0x2b, 0x77, 0x4b, 0x9c, 0x71, 0x09,
- 0xa9, 0x7d, 0x13, 0x8f, 0x12, 0x92, 0x28, 0x96,
- 0x6f, 0x6c, 0x0a, 0xdc, 0x10, 0x6a, 0xad, 0x5a,
- 0x9f, 0xdd, 0x30, 0x82, 0x57, 0x69, 0xb2, 0xc6,
- 0x71, 0xaf, 0x67, 0x59, 0xdf, 0x28, 0xeb, 0x39,
- 0x3d, 0x54, 0xd6
-};
-
-static const u_char sha256_long2_msg_digest[] = {
- 0x97, 0xdb, 0xca, 0x7d, 0xf4, 0x6d, 0x62, 0xc8,
- 0xa4, 0x22, 0xc9, 0x41, 0xdd, 0x7e, 0x83, 0x5b,
- 0x8a, 0xd3, 0x36, 0x17, 0x63, 0xf7, 0xe9, 0xb2,
- 0xd9, 0x5f, 0x4f, 0x0d, 0xa6, 0xe1, 0xcc, 0xbc
-};
-
-static const hash_testvector_t sha256_hash_testvectors[] = {
- { sizeof(sha256_short2_msg), sha256_short2_msg, sha256_short2_msg_digest },
- { sizeof(sha256_short4_msg), sha256_short4_msg, sha256_short4_msg_digest },
- { sizeof(sha256_long2_msg), sha256_long2_msg, sha256_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-384 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha384_short2_msg[] = {
- 0xb9
-};
-
-static const u_char sha384_short2_msg_digest[] = {
- 0xbc, 0x80, 0x89, 0xa1, 0x90, 0x07, 0xc0, 0xb1,
- 0x41, 0x95, 0xf4, 0xec, 0xc7, 0x40, 0x94, 0xfe,
- 0xc6, 0x4f, 0x01, 0xf9, 0x09, 0x29, 0x28, 0x2c,
- 0x2f, 0xb3, 0x92, 0x88, 0x15, 0x78, 0x20, 0x8a,
- 0xd4, 0x66, 0x82, 0x8b, 0x1c, 0x6c, 0x28, 0x3d,
- 0x27, 0x22, 0xcf, 0x0a, 0xd1, 0xab, 0x69, 0x38
-};
-
-static const u_char sha384_short4_msg[] = {
- 0xa4, 0x1c, 0x49, 0x77, 0x79, 0xc0, 0x37, 0x5f,
- 0xf1, 0x0a, 0x7f, 0x4e, 0x08, 0x59, 0x17, 0x39
-};
-
-static const u_char sha384_short4_msg_digest[] = {
- 0xc9, 0xa6, 0x84, 0x43, 0xa0, 0x05, 0x81, 0x22,
- 0x56, 0xb8, 0xec, 0x76, 0xb0, 0x05, 0x16, 0xf0,
- 0xdb, 0xb7, 0x4f, 0xab, 0x26, 0xd6, 0x65, 0x91,
- 0x3f, 0x19, 0x4b, 0x6f, 0xfb, 0x0e, 0x91, 0xea,
- 0x99, 0x67, 0x56, 0x6b, 0x58, 0x10, 0x9c, 0xbc,
- 0x67, 0x5c, 0xc2, 0x08, 0xe4, 0xc8, 0x23, 0xf7
-};
-
-static const u_char sha384_long2_msg[] = {
- 0x39, 0x96, 0x69, 0xe2, 0x8f, 0x6b, 0x9c, 0x6d,
- 0xbc, 0xbb, 0x69, 0x12, 0xec, 0x10, 0xff, 0xcf,
- 0x74, 0x79, 0x03, 0x49, 0xb7, 0xdc, 0x8f, 0xbe,
- 0x4a, 0x8e, 0x7b, 0x3b, 0x56, 0x21, 0xdb, 0x0f,
- 0x3e, 0x7d, 0xc8, 0x7f, 0x82, 0x32, 0x64, 0xbb,
- 0xe4, 0x0d, 0x18, 0x11, 0xc9, 0xea, 0x20, 0x61,
- 0xe1, 0xc8, 0x4a, 0xd1, 0x0a, 0x23, 0xfa, 0xc1,
- 0x72, 0x7e, 0x72, 0x02, 0xfc, 0x3f, 0x50, 0x42,
- 0xe6, 0xbf, 0x58, 0xcb, 0xa8, 0xa2, 0x74, 0x6e,
- 0x1f, 0x64, 0xf9, 0xb9, 0xea, 0x35, 0x2c, 0x71,
- 0x15, 0x07, 0x05, 0x3c, 0xf4, 0xe5, 0x33, 0x9d,
- 0x52, 0x86, 0x5f, 0x25, 0xcc, 0x22, 0xb5, 0xe8,
- 0x77, 0x84, 0xa1, 0x2f, 0xc9, 0x61, 0xd6, 0x6c,
- 0xb6, 0xe8, 0x95, 0x73, 0x19, 0x9a, 0x2c, 0xe6,
- 0x56, 0x5c, 0xbd, 0xf1, 0x3d, 0xca, 0x40, 0x38,
- 0x32, 0xcf, 0xcb, 0x0e, 0x8b, 0x72, 0x11, 0xe8,
- 0x3a, 0xf3, 0x2a, 0x11, 0xac, 0x17, 0x92, 0x9f,
- 0xf1, 0xc0, 0x73, 0xa5, 0x1c, 0xc0, 0x27, 0xaa,
- 0xed, 0xef, 0xf8, 0x5a, 0xad, 0x7c, 0x2b, 0x7c,
- 0x5a, 0x80, 0x3e, 0x24, 0x04, 0xd9, 0x6d, 0x2a,
- 0x77, 0x35, 0x7b, 0xda, 0x1a, 0x6d, 0xae, 0xed,
- 0x17, 0x15, 0x1c, 0xb9, 0xbc, 0x51, 0x25, 0xa4,
- 0x22, 0xe9, 0x41, 0xde, 0x0c, 0xa0, 0xfc, 0x50,
- 0x11, 0xc2, 0x3e, 0xcf, 0xfe, 0xfd, 0xd0, 0x96,
- 0x76, 0x71, 0x1c, 0xf3, 0xdb, 0x0a, 0x34, 0x40,
- 0x72, 0x0e ,0x16, 0x15, 0xc1, 0xf2, 0x2f, 0xbc,
- 0x3c, 0x72, 0x1d, 0xe5, 0x21, 0xe1, 0xb9, 0x9b,
- 0xa1, 0xbd, 0x55, 0x77, 0x40, 0x86, 0x42, 0x14,
- 0x7e, 0xd0, 0x96
-};
-
-static const u_char sha384_long2_msg_digest[] = {
- 0x4f, 0x44, 0x0d, 0xb1, 0xe6, 0xed, 0xd2, 0x89,
- 0x9f, 0xa3, 0x35, 0xf0, 0x95, 0x15, 0xaa, 0x02,
- 0x5e, 0xe1, 0x77, 0xa7, 0x9f, 0x4b, 0x4a, 0xaf,
- 0x38, 0xe4, 0x2b, 0x5c, 0x4d, 0xe6, 0x60, 0xf5,
- 0xde, 0x8f, 0xb2, 0xa5, 0xb2, 0xfb, 0xd2, 0xa3,
- 0xcb, 0xff, 0xd2, 0x0c, 0xff, 0x12, 0x88, 0xc0
-};
-
-static const hash_testvector_t sha384_hash_testvectors[] = {
- { sizeof(sha384_short2_msg), sha384_short2_msg, sha384_short2_msg_digest },
- { sizeof(sha384_short4_msg), sha384_short4_msg, sha384_short4_msg_digest },
- { sizeof(sha384_long2_msg), sha384_long2_msg, sha384_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-512 hash test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha512_short2_msg[] = {
- 0xd0
-};
-
-static const u_char sha512_short2_msg_digest[] = {
- 0x99, 0x92, 0x20, 0x29, 0x38, 0xe8, 0x82, 0xe7,
- 0x3e, 0x20, 0xf6, 0xb6, 0x9e, 0x68, 0xa0, 0xa7,
- 0x14, 0x90, 0x90, 0x42, 0x3d, 0x93, 0xc8, 0x1b,
- 0xab, 0x3f, 0x21, 0x67, 0x8d, 0x4a, 0xce, 0xee,
- 0xe5, 0x0e, 0x4e, 0x8c, 0xaf, 0xad, 0xa4, 0xc8,
- 0x5a, 0x54, 0xea, 0x83, 0x06, 0x82, 0x6c, 0x4a,
- 0xd6, 0xe7, 0x4c, 0xec, 0xe9, 0x63, 0x1b, 0xfa,
- 0x8a, 0x54, 0x9b, 0x4a, 0xb3, 0xfb, 0xba, 0x15
-};
-
-static const u_char sha512_short4_msg[] = {
- 0x8d, 0x4e, 0x3c, 0x0e, 0x38, 0x89, 0x19, 0x14,
- 0x91, 0x81, 0x6e, 0x9d, 0x98, 0xbf, 0xf0, 0xa0
-};
-
-static const u_char sha512_short4_msg_digest[] = {
- 0xcb, 0x0b, 0x67, 0xa4, 0xb8, 0x71, 0x2c, 0xd7,
- 0x3c, 0x9a, 0xab, 0xc0, 0xb1, 0x99, 0xe9, 0x26,
- 0x9b, 0x20, 0x84, 0x4a, 0xfb, 0x75, 0xac, 0xbd,
- 0xd1, 0xc1, 0x53, 0xc9, 0x82, 0x89, 0x24, 0xc3,
- 0xdd, 0xed, 0xaa, 0xfe, 0x66, 0x9c, 0x5f, 0xdd,
- 0x0b, 0xc6, 0x6f, 0x63, 0x0f, 0x67, 0x73, 0x98,
- 0x82, 0x13, 0xeb, 0x1b, 0x16, 0xf5, 0x17, 0xad,
- 0x0d, 0xe4, 0xb2, 0xf0, 0xc9, 0x5c, 0x90, 0xf8
-};
-
-static const u_char sha512_long2_msg[] = {
- 0xa5, 0x5f, 0x20, 0xc4, 0x11, 0xaa, 0xd1, 0x32,
- 0x80, 0x7a, 0x50, 0x2d, 0x65, 0x82, 0x4e, 0x31,
- 0xa2, 0x30, 0x54, 0x32, 0xaa, 0x3d, 0x06, 0xd3,
- 0xe2, 0x82, 0xa8, 0xd8, 0x4e, 0x0d, 0xe1, 0xde,
- 0x69, 0x74, 0xbf, 0x49, 0x54, 0x69, 0xfc, 0x7f,
- 0x33, 0x8f, 0x80, 0x54, 0xd5, 0x8c, 0x26, 0xc4,
- 0x93, 0x60, 0xc3, 0xe8, 0x7a, 0xf5, 0x65, 0x23,
- 0xac, 0xf6, 0xd8, 0x9d, 0x03, 0xe5, 0x6f, 0xf2,
- 0xf8, 0x68, 0x00, 0x2b, 0xc3, 0xe4, 0x31, 0xed,
- 0xc4, 0x4d, 0xf2, 0xf0, 0x22, 0x3d, 0x4b, 0xb3,
- 0xb2, 0x43, 0x58, 0x6e, 0x1a, 0x7d, 0x92, 0x49,
- 0x36, 0x69, 0x4f, 0xcb, 0xba, 0xf8, 0x8d, 0x95,
- 0x19, 0xe4, 0xeb, 0x50, 0xa6, 0x44, 0xf8, 0xe4,
- 0xf9, 0x5e, 0xb0, 0xea, 0x95, 0xbc, 0x44, 0x65,
- 0xc8, 0x82, 0x1a, 0xac, 0xd2, 0xfe, 0x15, 0xab,
- 0x49, 0x81, 0x16, 0x4b, 0xbb, 0x6d, 0xc3, 0x2f,
- 0x96, 0x90, 0x87, 0xa1, 0x45, 0xb0, 0xd9, 0xcc,
- 0x9c, 0x67, 0xc2, 0x2b, 0x76, 0x32, 0x99, 0x41,
- 0x9c, 0xc4, 0x12, 0x8b, 0xe9, 0xa0, 0x77, 0xb3,
- 0xac, 0xe6, 0x34, 0x06, 0x4e, 0x6d, 0x99, 0x28,
- 0x35, 0x13, 0xdc, 0x06, 0xe7, 0x51, 0x5d, 0x0d,
- 0x73, 0x13, 0x2e, 0x9a, 0x0d, 0xc6, 0xd3, 0xb1,
- 0xf8, 0xb2, 0x46, 0xf1, 0xa9, 0x8a, 0x3f, 0xc7,
- 0x29, 0x41, 0xb1, 0xe3, 0xbb, 0x20, 0x98, 0xe8,
- 0xbf, 0x16, 0xf2, 0x68, 0xd6, 0x4f, 0x0b, 0x0f,
- 0x47, 0x07, 0xfe, 0x1e, 0xa1, 0xa1, 0x79, 0x1b,
- 0xa2, 0xf3, 0xc0, 0xc7, 0x58, 0xe5, 0xf5, 0x51,
- 0x86, 0x3a, 0x96, 0xc9, 0x49, 0xad, 0x47, 0xd7,
- 0xfb, 0x40, 0xd2
-};
-
-static const u_char sha512_long2_msg_digest[] = {
- 0xc6, 0x65, 0xbe, 0xfb, 0x36, 0xda, 0x18, 0x9d,
- 0x78, 0x82, 0x2d, 0x10, 0x52, 0x8c, 0xbf, 0x3b,
- 0x12, 0xb3, 0xee, 0xf7, 0x26, 0x03, 0x99, 0x09,
- 0xc1, 0xa1, 0x6a, 0x27, 0x0d, 0x48, 0x71, 0x93,
- 0x77, 0x96, 0x6b, 0x95, 0x7a, 0x87, 0x8e, 0x72,
- 0x05, 0x84, 0x77, 0x9a, 0x62, 0x82, 0x5c, 0x18,
- 0xda, 0x26, 0x41, 0x5e, 0x49, 0xa7, 0x17, 0x6a,
- 0x89, 0x4e, 0x75, 0x10, 0xfd, 0x14, 0x51, 0xf5
-};
-
-static const hash_testvector_t sha512_hash_testvectors[] = {
- { sizeof(sha512_short2_msg), sha512_short2_msg, sha512_short2_msg_digest },
- { sizeof(sha512_short4_msg), sha512_short4_msg, sha512_short4_msg_digest },
- { sizeof(sha512_long2_msg), sha512_long2_msg, sha512_long2_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* SHA-256, SHA-384, and SHA-512 hmac test vectors
- * from RFC 4231 "Identifiers and Test Vectors for HMAC-SHA-224,
- * HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512"
- * December 2005, M. Nystrom, RSA Security
- */
-
-static const u_char sha2_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b
-};
-
-static const u_char sha2_hmac1_msg[] = {
- 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-};
-
-static const u_char sha2_hmac1_256[] = {
- 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
- 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
- 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
- 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7
-};
-
-static const u_char sha2_hmac1_384[] = {
- 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
- 0x6b, 0x08, 0x25, 0xf4, 0xab ,0x46, 0x90, 0x7f,
- 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
- 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
- 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
- 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6
-};
-
-static const u_char sha2_hmac1_512[] = {
- 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
- 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
- 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
- 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
- 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
- 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
- 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
- 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54
-};
-
-static const u_char sha2_hmac2_key[] = {
- 0x4a, 0x65, 0x66, 0x65
-};
-
-static const u_char sha2_hmac2_msg[] = {
- 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
- 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
- 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
- 0x69, 0x6e, 0x67, 0x3f
-};
-
-static const u_char sha2_hmac2_256[] = {
- 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
- 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
- 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
- 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43
-};
-
-static const u_char sha2_hmac2_384[] = {
- 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
- 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
- 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
- 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
- 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
- 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49
-};
-
-static const u_char sha2_hmac2_512[] = {
- 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
- 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
- 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
- 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
- 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
- 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
- 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
- 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37
-};
-
-static const u_char sha2_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa
-};
-
-static const u_char sha2_hmac3_msg[] = {
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd
-};
-
-static const u_char sha2_hmac3_256[] = {
- 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
- 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
- 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
- 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe
-};
-
-static const u_char sha2_hmac3_384[] = {
- 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
- 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
- 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
- 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
- 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
- 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27
-};
-
-static const u_char sha2_hmac3_512[] = {
- 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
- 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
- 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
- 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
- 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
- 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
- 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
- 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb
-};
-
-static const u_char sha2_hmac4_key[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19
-};
-
-static const u_char sha2_hmac4_msg[] = {
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd
-};
-
-static const u_char sha2_hmac4_256[] = {
- 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
- 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
- 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
- 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b
-};
-
-static const u_char sha2_hmac4_384[] = {
- 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
- 0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
- 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
- 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
- 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
- 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb
-};
-
-static const u_char sha2_hmac4_512[] = {
- 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
- 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
- 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
- 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
- 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
- 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
- 0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
- 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd
-};
-
-static const u_char sha2_hmac6_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa
-};
-
-static const u_char sha2_hmac6_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
- 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
- 0x20, 0x46, 0x69, 0x72, 0x73, 0x74
-};
-
-static const u_char sha2_hmac6_256[] = {
- 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
- 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
- 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
- 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54
-};
-
-static const u_char sha2_hmac6_384[] = {
- 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
- 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
- 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
- 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
- 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
- 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52
-};
-
-static const u_char sha2_hmac6_512[] = {
- 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
- 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
- 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
- 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
- 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
- 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
- 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
- 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98
-};
-
-static const u_char sha2_hmac7_msg[] = {
- 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
- 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x75,
- 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x6c,
- 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74, 0x68,
- 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
- 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6b, 0x65,
- 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20,
- 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, 0x74,
- 0x68, 0x61, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63,
- 0x6b, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x64,
- 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65,
- 0x20, 0x6b, 0x65, 0x79, 0x20, 0x6e, 0x65, 0x65,
- 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65,
- 0x20, 0x68, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20,
- 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x62,
- 0x65, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x65,
- 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
- 0x20, 0x48, 0x4d, 0x41, 0x43, 0x20, 0x61, 0x6c,
- 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x2e
-};
-
-static const u_char sha2_hmac7_256[] = {
- 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
- 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
- 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
- 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2
-};
-
-static const u_char sha2_hmac7_384[] = {
- 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
- 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
- 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
- 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
- 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
- 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e
-};
-
-static const u_char sha2_hmac7_512[] = {
- 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
- 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
- 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
- 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
- 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
- 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
- 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
- 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58
-};
-
-static const hmac_testvector_t sha256_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_256 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_256 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_256 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_256 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_256 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_256 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static const hmac_testvector_t sha384_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_384 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_384 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_384 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_384 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_384 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_384 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-static const hmac_testvector_t sha512_hmac_testvectors[] = {
- { sizeof(sha2_hmac1_key), sha2_hmac1_key, sizeof(sha2_hmac1_msg), sha2_hmac1_msg, sha2_hmac1_512 },
- { sizeof(sha2_hmac2_key), sha2_hmac2_key, sizeof(sha2_hmac2_msg), sha2_hmac2_msg, sha2_hmac2_512 },
- { sizeof(sha2_hmac3_key), sha2_hmac3_key, sizeof(sha2_hmac3_msg), sha2_hmac3_msg, sha2_hmac3_512 },
- { sizeof(sha2_hmac4_key), sha2_hmac4_key, sizeof(sha2_hmac4_msg), sha2_hmac4_msg, sha2_hmac4_512 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac6_msg), sha2_hmac6_msg, sha2_hmac6_512 },
- { sizeof(sha2_hmac6_key), sha2_hmac6_key, sizeof(sha2_hmac7_msg), sha2_hmac7_msg, sha2_hmac7_512 },
- { 0, NULL, 0, NULL, NULL }
-};
-
-struct hash_desc hash_desc_sha2_256 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_256,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha256_context),
- hash_block_size: SHA2_256_BLOCK_SIZE,
- hash_digest_size: SHA2_256_DIGEST_SIZE,
- hash_testvectors: sha256_hash_testvectors,
- hmac_testvectors: sha256_hmac_testvectors,
- hash_init: (void (*)(void *))sha256_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha256_write,
- hash_final:(void (*)(u_char *, void *))sha256_hash_final
-};
-
-struct hash_desc hash_desc_sha2_384 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_384,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha512_context),
- hash_block_size: SHA2_384_BLOCK_SIZE,
- hash_digest_size: SHA2_384_DIGEST_SIZE,
- hash_testvectors: sha384_hash_testvectors,
- hmac_testvectors: sha384_hmac_testvectors,
- hash_init: (void (*)(void *))sha384_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha512_write,
- hash_final:(void (*)(u_char *, void *))sha384_hash_final
-};
-
-struct hash_desc hash_desc_sha2_512 = {
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA2_512,
- algo_next: NULL,
- hash_ctx_size: sizeof(sha512_context),
- hash_block_size: SHA2_512_BLOCK_SIZE,
- hash_digest_size: SHA2_512_DIGEST_SIZE,
- hash_testvectors: sha512_hash_testvectors,
- hmac_testvectors: sha512_hmac_testvectors,
- hash_init: (void (*)(void *))sha512_init,
- hash_update: (void (*)(void *, const u_char *, size_t ))sha512_write,
- hash_final:(void (*)(u_char *, void *))sha512_hash_final
-};
-
-int ike_alg_sha2_init(void);
-
-int
-ike_alg_sha2_init(void)
-{
- int ret
-;
- ret = ike_alg_register_hash(&hash_desc_sha2_256);
- if (ret)
- goto out;
- ret = ike_alg_register_hash(&hash_desc_sha2_384);
- if (ret)
- goto out;
- ret = ike_alg_register_hash(&hash_desc_sha2_512);
-
-out:
- return ret;
-}
-
-/*
-IKE_ALG_INIT_NAME: ike_alg_sha2_init
-*/
diff --git a/src/pluto/alg/ike_alg_twofish.c b/src/pluto/alg/ike_alg_twofish.c
deleted file mode 100644
index 1788bc394..000000000
--- a/src/pluto/alg/ike_alg_twofish.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "libtwofish/twofish_cbc.h"
-#include "alg_info.h"
-#include "ike_alg.h"
-
-#define TWOFISH_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
-#define TWOFISH_KEY_MIN_LEN 128
-#define TWOFISH_KEY_DEF_LEN 128
-#define TWOFISH_KEY_MAX_LEN 256
-
-static void
-do_twofish(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
-{
- twofish_context twofish_ctx;
- char iv_bak[TWOFISH_CBC_BLOCK_SIZE];
- char *new_iv = NULL; /* logic will avoid copy to NULL */
-
- twofish_set_key(&twofish_ctx, key, key_size);
- /*
- * my TWOFISH cbc does not touch passed IV (optimization for
- * ESP handling), so I must "emulate" des-like IV
- * crunching
- */
- if (!enc)
- memcpy(new_iv=iv_bak,
- (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE,
- TWOFISH_CBC_BLOCK_SIZE);
-
- twofish_cbc_encrypt(&twofish_ctx, buf, buf, buf_size, iv, enc);
-
- if (enc)
- new_iv = (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE;
-
- memcpy(iv, new_iv, TWOFISH_CBC_BLOCK_SIZE);
-}
-
-struct encrypt_desc encrypt_desc_twofish =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_TWOFISH_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(twofish_context),
- enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
- keydeflen: TWOFISH_KEY_MIN_LEN,
- keyminlen: TWOFISH_KEY_DEF_LEN,
- keymaxlen: TWOFISH_KEY_MAX_LEN,
- do_crypt: do_twofish,
-};
-
-struct encrypt_desc encrypt_desc_twofish_ssh =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_TWOFISH_CBC_SSH,
- algo_next: NULL,
- enc_ctxsize: sizeof(twofish_context),
- enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
- keydeflen: TWOFISH_KEY_MIN_LEN,
- keyminlen: TWOFISH_KEY_DEF_LEN,
- keymaxlen: TWOFISH_KEY_MAX_LEN,
- do_crypt: do_twofish,
-};
-
-int ike_alg_twofish_init(void);
-
-int
-ike_alg_twofish_init(void)
-{
- int ret = ike_alg_register_enc(&encrypt_desc_twofish);
-
- if (ike_alg_register_enc(&encrypt_desc_twofish_ssh) < 0)
- plog("ike_alg_twofish_init(): Experimental OAKLEY_TWOFISH_CBC_SSH activation failed");
-
- return ret;
-}
-/*
-IKE_ALG_INIT_NAME: ike_alg_twofish_init
-*/
diff --git a/src/pluto/alg/ike_alginit.c b/src/pluto/alg/ike_alginit.c
deleted file mode 100644
index 8784bf31b..000000000
--- a/src/pluto/alg/ike_alginit.c
+++ /dev/null
@@ -1,7 +0,0 @@
-extern int ike_alg_init(void); int ike_alg_init(void) {
-{ extern int ike_alg_aes_init (void); ike_alg_aes_init();}
-{ extern int ike_alg_blowfish_init (void); ike_alg_blowfish_init();}
-{ extern int ike_alg_serpent_init (void); ike_alg_serpent_init();}
-{ extern int ike_alg_sha2_init (void); ike_alg_sha2_init();}
-{ extern int ike_alg_twofish_init (void); ike_alg_twofish_init();}
-return 0;}
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c
index cd02d2358..a85a18905 100644
--- a/src/pluto/alg_info.c
+++ b/src/pluto/alg_info.c
@@ -1,6 +1,7 @@
/*
* Algorithm info parsing and creation functions
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: alg_info.c 3846 2008-04-18 17:01:45Z andreas $
*/
#include <stddef.h>
@@ -27,390 +26,187 @@
#include <ctype.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include <pfkeyv2.h>
+#include <utils.h>
+#include <utils/lexparser.h>
+#include <crypto/diffie_hellman.h>
+#include <crypto/transform.h>
+#include <crypto/proposal/proposal_keywords.h>
+
+
#include "alg_info.h"
#include "constants.h"
-#ifndef NO_PLUTO
#include "defs.h"
#include "log.h"
#include "whack.h"
-#include "sha1.h"
-#include "md5.h"
#include "crypto.h"
#include "kernel_alg.h"
#include "ike_alg.h"
-#else
-/*
- * macros/functions for compilation without pluto (eg: spi for manual conns)
- */
-#include <assert.h>
-#define passert(x) assert(x)
-extern int debug; /* eg: spi.c */
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define RC_LOG_SERIOUS
-#define loglog(x, args...) fprintf(stderr, ##args);
-#define alloc_thing(thing, name) alloc_bytes(sizeof (thing), name)
-void * alloc_bytes(size_t size, const char *name) {
- void *p=malloc(size);
- if (p == NULL)
- fprintf(stderr, "unable to malloc %lu bytes for %s",
- (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-#define pfreeany(ptr) free(ptr)
-#endif /* NO_PLUTO */
/*
* sadb/ESP aa attrib converters
*/
-int
-alg_info_esp_aa2sadb(int auth)
-{
- int sadb_aalg = 0;
-
- switch(auth) {
- case AUTH_ALGORITHM_HMAC_MD5:
- case AUTH_ALGORITHM_HMAC_SHA1:
- sadb_aalg = auth + 1;
- break;
- case AUTH_ALGORITHM_HMAC_SHA2_256:
- case AUTH_ALGORITHM_HMAC_SHA2_384:
- case AUTH_ALGORITHM_HMAC_SHA2_512:
- case AUTH_ALGORITHM_HMAC_RIPEMD:
- sadb_aalg = auth;
- break;
- default:
- /* loose ... */
- sadb_aalg = auth;
- }
- return sadb_aalg;
-}
-
-int /* __attribute__ ((unused)) */
-alg_info_esp_sadb2aa(int sadb_aalg)
-{
- int auth = 0;
-
- switch(sadb_aalg) {
- case SADB_AALG_MD5HMAC:
- case SADB_AALG_SHA1HMAC:
- auth = sadb_aalg - 1;
- break;
- /* since they are the same ... :) */
- case AUTH_ALGORITHM_HMAC_SHA2_256:
- case AUTH_ALGORITHM_HMAC_SHA2_384:
- case AUTH_ALGORITHM_HMAC_SHA2_512:
- case AUTH_ALGORITHM_HMAC_RIPEMD:
- auth = sadb_aalg;
- break;
- default:
- /* loose ... */
- auth = sadb_aalg;
- }
- return auth;
-}
-
-/*
- * Search enum_name array with in prefixed uppercase
- */
-static int
-enum_search_prefix (enum_names *ed, const char *prefix, const char *str, int strlen)
-{
- char buf[64];
- char *ptr;
- int ret;
- int len = sizeof(buf) - 1; /* reserve space for final \0 */
-
- for (ptr = buf; *prefix; *ptr++ = *prefix++, len--);
- while (strlen-- && len-- && *str) *ptr++ = toupper(*str++);
- *ptr = 0;
-
- DBG(DBG_CRYPT,
- DBG_log("enum_search_prefix () calling enum_search(%p, \"%s\")"
- , ed, buf)
- )
- ret = enum_search(ed, buf);
- return ret;
-}
-
-/*
- * Search enum_name array with in prefixed and postfixed uppercase
- */
-static int
-enum_search_ppfix (enum_names *ed, const char *prefix, const char *postfix, const char *str, int strlen)
-{
- char buf[64];
- char *ptr;
- int ret;
- int len = sizeof(buf) - 1; /* reserve space for final \0 */
-
- for (ptr = buf; *prefix; *ptr++ = *prefix++, len--);
- while (strlen-- && len-- && *str) *ptr++ = toupper(*str++);
- while (len-- && *postfix) *ptr++ = *postfix++;
- *ptr = 0;
-
- DBG(DBG_CRYPT,
- DBG_log("enum_search_ppfixi () calling enum_search(%p, \"%s\")"
- , ed, buf)
- )
- ret = enum_search(ed, buf);
- return ret;
-}
-
-/*
- * Search esp_transformid_names for a match, eg:
- * "3des" <=> "ESP_3DES"
- */
-#define ESP_MAGIC_ID 0x00ffff01
-
-static int
-ealg_getbyname_esp(const char *const str, int len)
+int alg_info_esp_aa2sadb(int auth)
{
- if (!str || !*str)
- return -1;
-
- /* leave special case for eg: "id248" string */
- if (strcmp("id", str) == 0)
- return ESP_MAGIC_ID;
-
- return enum_search_prefix(&esp_transformid_names, "ESP_", str, len);
+ int sadb_aalg = 0;
+
+ switch(auth) {
+ case AUTH_ALGORITHM_HMAC_MD5:
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ sadb_aalg = auth + 1;
+ break;
+ case AUTH_ALGORITHM_HMAC_SHA2_256:
+ case AUTH_ALGORITHM_HMAC_SHA2_384:
+ case AUTH_ALGORITHM_HMAC_SHA2_512:
+ case AUTH_ALGORITHM_HMAC_RIPEMD:
+ sadb_aalg = auth;
+ break;
+ default:
+ /* loose ... */
+ sadb_aalg = auth;
+ }
+ return sadb_aalg;
}
-/*
- * Search auth_alg_names for a match, eg:
- * "md5" <=> "AUTH_ALGORITHM_HMAC_MD5"
- */
-static int
-aalg_getbyname_esp(const char *const str, int len)
+int alg_info_esp_sadb2aa(int sadb_aalg)
{
- int ret;
- unsigned num;
-
- if (!str || !*str)
- return -1;
-
- /* interpret 'SHA' as 'SHA1' */
- if (strncasecmp("SHA", str, len) == 0)
- return AUTH_ALGORITHM_HMAC_SHA1;
-
- /* interpret 'AESXCBC' as 'AES_XCBC_MAC' */
- if (strncasecmp("AESXCBC", str, len) == 0)
- return AUTH_ALGORITHM_AES_XCBC_MAC;
-
- ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_", str ,len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_", str, len);
- if (ret >= 0)
- return ret;
-
- sscanf(str, "id%d%n", &ret, &num);
- return (ret >= 0 && num != strlen(str))? -1 : ret;
+ int auth = 0;
+
+ switch(sadb_aalg) {
+ case SADB_AALG_MD5HMAC:
+ case SADB_AALG_SHA1HMAC:
+ auth = sadb_aalg - 1;
+ break;
+ /* since they are the same ... :) */
+ case AUTH_ALGORITHM_HMAC_SHA2_256:
+ case AUTH_ALGORITHM_HMAC_SHA2_384:
+ case AUTH_ALGORITHM_HMAC_SHA2_512:
+ case AUTH_ALGORITHM_HMAC_RIPEMD:
+ auth = sadb_aalg;
+ break;
+ default:
+ /* loose ... */
+ auth = sadb_aalg;
+ }
+ return auth;
}
-static int
-modp_getbyname_esp(const char *const str, int len)
+void alg_info_free(struct alg_info *alg_info)
{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);
- return ret;
-}
-
-void
-alg_info_free(struct alg_info *alg_info)
-{
- pfreeany(alg_info);
+ free(alg_info);
}
/*
* Raw add routine: only checks for no duplicates
*/
-static void
-__alg_info_esp_add (struct alg_info_esp *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits)
+static void __alg_info_esp_add(struct alg_info_esp *alg_info, int ealg_id,
+ unsigned ek_bits, int aalg_id, unsigned ak_bits)
{
- struct esp_info *esp_info=alg_info->esp;
- unsigned cnt = alg_info->alg_info_cnt, i;
+ struct esp_info *esp_info = alg_info->esp;
+ unsigned cnt = alg_info->alg_info_cnt, i;
- /* check for overflows */
- passert(cnt < elemsof(alg_info->esp));
+ /* check for overflows */
+ passert(cnt < countof(alg_info->esp));
- /* dont add duplicates */
- for (i = 0; i < cnt; i++)
- {
- if (esp_info[i].esp_ealg_id == ealg_id
- && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits)
- && esp_info[i].esp_aalg_id == aalg_id
- && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits))
- return;
- }
+ /* dont add duplicates */
+ for (i = 0; i < cnt; i++)
+ {
+ if (esp_info[i].esp_ealg_id == ealg_id
+ && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits)
+ && esp_info[i].esp_aalg_id == aalg_id
+ && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits))
+ {
+ return;
+ }
+ }
- esp_info[cnt].esp_ealg_id = ealg_id;
- esp_info[cnt].esp_ealg_keylen = ek_bits;
- esp_info[cnt].esp_aalg_id = aalg_id;
- esp_info[cnt].esp_aalg_keylen = ak_bits;
+ esp_info[cnt].esp_ealg_id = ealg_id;
+ esp_info[cnt].esp_ealg_keylen = ek_bits;
+ esp_info[cnt].esp_aalg_id = aalg_id;
+ esp_info[cnt].esp_aalg_keylen = ak_bits;
- /* sadb values */
- esp_info[cnt].encryptalg = ealg_id;
- esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id);
- alg_info->alg_info_cnt++;
+ /* sadb values */
+ esp_info[cnt].encryptalg = ealg_id;
+ esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id);
+ alg_info->alg_info_cnt++;
- DBG(DBG_CRYPT,
- DBG_log("__alg_info_esp_add() ealg=%d aalg=%d cnt=%d"
- , ealg_id, aalg_id, alg_info->alg_info_cnt)
- )
+ DBG(DBG_CRYPT,
+ DBG_log("esp alg added: %s_%d/%s, cnt=%d",
+ enum_show(&esp_transformid_names, ealg_id), ek_bits,
+ enum_show(&auth_alg_names, aalg_id),
+ alg_info->alg_info_cnt)
+ )
}
/*
* Add ESP alg info _with_ logic (policy):
*/
-static void
-alg_info_esp_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits)
+static void alg_info_esp_add(struct alg_info *alg_info, int ealg_id,
+ int ek_bits, int aalg_id, int ak_bits)
{
- /* Policy: default to 3DES */
- if (ealg_id == 0)
- ealg_id = ESP_3DES;
-
- if (ealg_id > 0)
- {
-#ifndef NO_PLUTO
- if (aalg_id > 0)
-#else
- /* Allow no auth for manual conns (from spi.c) */
- if (aalg_id >= 0)
-#endif
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- aalg_id, ak_bits);
- else
+ /* Policy: default to 3DES */
+ if (ealg_id == 0)
{
- /* Policy: default to MD5 and SHA1 */
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- AUTH_ALGORITHM_HMAC_MD5, ak_bits);
- __alg_info_esp_add((struct alg_info_esp *)alg_info,
- ealg_id, ek_bits,
- AUTH_ALGORITHM_HMAC_SHA1, ak_bits);
+ ealg_id = ESP_3DES;
+ }
+ if (ealg_id > 0)
+ {
+ if (aalg_id > 0)
+ {
+ __alg_info_esp_add((struct alg_info_esp *)alg_info,
+ ealg_id, ek_bits,
+ aalg_id, ak_bits);
+ }
+ else
+ {
+ /* Policy: default to MD5 and SHA1 */
+ __alg_info_esp_add((struct alg_info_esp *)alg_info,
+ ealg_id, ek_bits,
+ AUTH_ALGORITHM_HMAC_MD5, ak_bits);
+ __alg_info_esp_add((struct alg_info_esp *)alg_info,
+ ealg_id, ek_bits,
+ AUTH_ALGORITHM_HMAC_SHA1, ak_bits);
+ }
}
- }
-}
-
-#ifndef NO_PLUTO
-/**************************************
- *
- * IKE alg
- *
- *************************************/
-/*
- * Search oakley_enc_names for a match, eg:
- * "3des_cbc" <=> "OAKLEY_3DES_CBC"
- */
-static int
-ealg_getbyname_ike(const char *const str, int len)
-{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_enc_names,"OAKLEY_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_enc_names, "OAKLEY_", "_CBC", str, len);
- return ret;
-}
-
-/*
- * Search oakley_hash_names for a match, eg:
- * "md5" <=> "OAKLEY_MD5"
- */
-static int
-aalg_getbyname_ike(const char *const str, int len)
-{
- int ret;
- unsigned num;
-
- if (!str || !*str)
- return -1;
-
- /* interpret 'SHA1' as 'SHA' */
- if (strncasecmp("SHA1", str, len) == 0)
- return enum_search(&oakley_hash_names, "OAKLEY_SHA");
-
- ret = enum_search_prefix(&oakley_hash_names,"OAKLEY_", str, len);
- if (ret >= 0)
- return ret;
-
- sscanf(str, "id%d%n", &ret, &num);
- return (ret >=0 && num != strlen(str))? -1 : ret;
-}
-
-/*
- * Search oakley_group_names for a match, eg:
- * "modp1024" <=> "OAKLEY_GROUP_MODP1024"
- */
-static int
-modp_getbyname_ike(const char *const str, int len)
-{
- int ret;
-
- if (!str || !*str)
- return -1;
-
- ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len);
- if (ret >= 0)
- return ret;
-
- ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);
- return ret;
}
-static void
-__alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits, int modp_id)
+static void __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id,
+ unsigned ek_bits, int aalg_id, unsigned ak_bits,
+ int modp_id)
{
- struct ike_info *ike_info = alg_info->ike;
- unsigned cnt = alg_info->alg_info_cnt;
- unsigned i;
+ struct ike_info *ike_info = alg_info->ike;
+ unsigned cnt = alg_info->alg_info_cnt;
+ unsigned i;
- /* check for overflows */
- passert(cnt < elemsof(alg_info->ike));
+ /* check for overflows */
+ passert(cnt < countof(alg_info->ike));
- /* dont add duplicates */
- for (i = 0;i < cnt; i++)
+ /* dont add duplicates */
+ for (i = 0; i < cnt; i++)
{
- if (ike_info[i].ike_ealg == ealg_id
- && (!ek_bits || ike_info[i].ike_eklen == ek_bits)
- && ike_info[i].ike_halg == aalg_id
- && (!ak_bits || ike_info[i].ike_hklen == ak_bits)
- && ike_info[i].ike_modp==modp_id)
- return;
- }
+ if (ike_info[i].ike_ealg == ealg_id
+ && (!ek_bits || ike_info[i].ike_eklen == ek_bits)
+ && ike_info[i].ike_halg == aalg_id
+ && (!ak_bits || ike_info[i].ike_hklen == ak_bits)
+ && ike_info[i].ike_modp==modp_id)
+ return;
+ }
- ike_info[cnt].ike_ealg = ealg_id;
- ike_info[cnt].ike_eklen = ek_bits;
- ike_info[cnt].ike_halg = aalg_id;
- ike_info[cnt].ike_hklen = ak_bits;
- ike_info[cnt].ike_modp = modp_id;
- alg_info->alg_info_cnt++;
+ ike_info[cnt].ike_ealg = ealg_id;
+ ike_info[cnt].ike_eklen = ek_bits;
+ ike_info[cnt].ike_halg = aalg_id;
+ ike_info[cnt].ike_hklen = ak_bits;
+ ike_info[cnt].ike_modp = modp_id;
+ alg_info->alg_info_cnt++;
- DBG(DBG_CRYPT,
- DBG_log("__alg_info_ike_add() ealg=%d aalg=%d modp_id=%d, cnt=%d"
- , ealg_id, aalg_id, modp_id
- , alg_info->alg_info_cnt)
- )
+ DBG(DBG_CRYPT,
+ DBG_log("ikg alg added: %s_%d/%s/%s, cnt=%d",
+ enum_show(&oakley_enc_names, ealg_id), ek_bits,
+ enum_show(&oakley_hash_names, aalg_id),
+ enum_show(&oakley_group_names, modp_id),
+ alg_info->alg_info_cnt)
+ )
}
/*
@@ -419,792 +215,449 @@ __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, unsigned ek_bits
*/
static int default_ike_groups[] = {
- OAKLEY_GROUP_MODP1536,
- OAKLEY_GROUP_MODP1024
+ MODP_1536_BIT,
+ MODP_1024_BIT
};
-/*
- * Add IKE alg info _with_ logic (policy):
+/*
+ * Add IKE alg info _with_ logic (policy):
*/
-static void
-alg_info_ike_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits, int modp_id)
+static void alg_info_ike_add (struct alg_info *alg_info, int ealg_id,
+ int ek_bits, int aalg_id, int ak_bits, int modp_id)
{
- int i = 0;
- int n_groups = elemsof(default_ike_groups);
-
- /* if specified modp_id avoid loop over default_ike_groups */
- if (modp_id)
- {
- n_groups=0;
- goto in_loop;
- }
-
- for (; n_groups--; i++)
- {
- modp_id = default_ike_groups[i];
-in_loop:
- /* Policy: default to 3DES */
- if (ealg_id == 0)
- ealg_id = OAKLEY_3DES_CBC;
+ int i = 0;
+ int n_groups = countof(default_ike_groups);
- if (ealg_id > 0)
+ /* if specified modp_id avoid loop over default_ike_groups */
+ if (modp_id)
{
- if (aalg_id > 0)
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- aalg_id, ak_bits,
- modp_id);
- else
- {
- /* Policy: default to MD5 and SHA */
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- OAKLEY_MD5, ak_bits,
- modp_id);
- __alg_info_ike_add((struct alg_info_ike *)alg_info,
- ealg_id, ek_bits,
- OAKLEY_SHA, ak_bits,
- modp_id);
- }
+ n_groups=0;
+ goto in_loop;
+ }
+
+ for (; n_groups--; i++)
+ {
+ modp_id = default_ike_groups[i];
+in_loop:
+ /* Policy: default to 3DES */
+ if (ealg_id == 0)
+ {
+ ealg_id = OAKLEY_3DES_CBC;
+ }
+ if (ealg_id > 0)
+ {
+ if (aalg_id > 0)
+ {
+ __alg_info_ike_add((struct alg_info_ike *)alg_info,
+ ealg_id, ek_bits,
+ aalg_id, ak_bits,
+ modp_id);
+ }
+ else
+ {
+ /* Policy: default to MD5 and SHA */
+ __alg_info_ike_add((struct alg_info_ike *)alg_info,
+ ealg_id, ek_bits,
+ OAKLEY_MD5, ak_bits,
+ modp_id);
+ __alg_info_ike_add((struct alg_info_ike *)alg_info,
+ ealg_id, ek_bits,
+ OAKLEY_SHA, ak_bits,
+ modp_id);
+ }
+ }
}
- }
-}
-#endif /* NO_PLUTO */
-
-/*
- * Creates a new alg_info by parsing passed string
- */
-enum parser_state_esp {
- ST_INI,
- ST_EA, /* encrypt algo */
- ST_EA_END,
- ST_EK, /* enc. key length */
- ST_EK_END,
- ST_AA, /* auth algo */
- ST_AA_END,
- ST_AK, /* auth. key length */
- ST_AK_END,
- ST_MODP, /* modp spec */
- ST_FLAG_STRICT,
- ST_END,
- ST_EOF,
- ST_ERR
-};
-
-static const char *parser_state_esp_names[] = {
- "ST_INI",
- "ST_EA",
- "ST_EA_END",
- "ST_EK",
- "ST_EK_END",
- "ST_AA",
- "ST_AA_END",
- "ST_AK",
- "ST_AK_END",
- "ST_MOPD",
- "ST_FLAG_STRICT",
- "ST_END",
- "ST_EOF",
- "ST_ERR"
-};
-
-static const char*
-parser_state_name_esp(enum parser_state_esp state)
-{
- return parser_state_esp_names[state];
-}
-
-/* XXX:jjo to implement different parser for ESP and IKE */
-struct parser_context {
- unsigned state, old_state;
- unsigned protoid;
- char ealg_buf[16];
- char aalg_buf[16];
- char modp_buf[16];
- int (*ealg_getbyname)(const char *const str, int len);
- int (*aalg_getbyname)(const char *const str, int len);
- int (*modp_getbyname)(const char *const str, int len);
- char *ealg_str;
- char *aalg_str;
- char *modp_str;
- int eklen;
- int aklen;
- int ch;
- const char *err;
-};
-
-static inline void
-parser_set_state(struct parser_context *p_ctx, enum parser_state_esp state)
-{
- if (state != p_ctx->state)
- {
- p_ctx->old_state = p_ctx->state;
- p_ctx->state = state;
- }
}
-static int
-parser_machine(struct parser_context *p_ctx)
+static status_t alg_info_add(chunk_t alg, unsigned protoid,
+ int *ealg, size_t *ealg_keysize,
+ int *aalg, size_t *aalg_keysize, int *dh_group)
{
- int ch = p_ctx->ch;
-
- /* special 'absolute' cases */
- p_ctx->err = "No error.";
+ const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len);
- /* chars that end algo strings */
- switch (ch){
- case 0: /* end-of-string */
- case '!': /* flag as strict algo list */
- case ',': /* algo string separator */
- switch (p_ctx->state) {
- case ST_EA:
- case ST_EK:
- case ST_AA:
- case ST_AK:
- case ST_MODP:
- case ST_FLAG_STRICT:
- {
- enum parser_state_esp next_state = 0;
-
- switch (ch) {
- case 0:
- next_state = ST_EOF;
- break;
- case ',':
- next_state = ST_END;
- break;
- case '!':
- next_state = ST_FLAG_STRICT;
- break;
- }
- /* ch? parser_set_state(p_ctx, ST_END) : parser_set_state(p_ctx, ST_EOF) ; */
- parser_set_state(p_ctx, next_state);
- goto out;
- }
- default:
- p_ctx->err = "String ended with invalid char";
- goto err;
- }
- }
-re_eval:
- switch (p_ctx->state) {
- case ST_INI:
- if (isspace(ch))
- break;
- if (isalnum(ch))
- {
- *(p_ctx->ealg_str++) = ch;
- parser_set_state(p_ctx, ST_EA);
- break;
- }
- p_ctx->err = "No alphanum. char initially found";
- goto err;
- case ST_EA:
- if (isalpha(ch) || ch == '_')
- {
- *(p_ctx->ealg_str++) = ch;
- break;
- }
- if (isdigit(ch))
- {
- /* bravely switch to enc keylen */
- *(p_ctx->ealg_str) = 0;
- parser_set_state(p_ctx, ST_EK);
- goto re_eval;
- }
- if (ch == '-')
- {
- *(p_ctx->ealg_str) = 0;
- parser_set_state(p_ctx, ST_EA_END);
- break;
- }
- p_ctx->err = "No valid char found after enc alg string";
- goto err;
- case ST_EA_END:
- if (isdigit(ch))
- {
- /* bravely switch to enc keylen */
- parser_set_state(p_ctx, ST_EK);
- goto re_eval;
- }
- if (isalpha(ch))
- {
- parser_set_state(p_ctx, ST_AA);
- goto re_eval;
- }
- p_ctx->err = "No alphanum char found after enc alg separator";
- goto err;
- case ST_EK:
- if (ch == '-')
- {
- parser_set_state(p_ctx, ST_EK_END);
- break;
- }
- if (isdigit(ch))
- {
- p_ctx->eklen = p_ctx->eklen*10 + ch - '0';
- break;
- }
- p_ctx->err = "Non digit or valid separator found while reading enc keylen";
- goto err;
- case ST_EK_END:
- if (isalpha(ch))
- {
- parser_set_state(p_ctx, ST_AA);
- goto re_eval;
- }
- p_ctx->err = "Non alpha char found after enc keylen end separator";
- goto err;
- case ST_AA:
- if (ch == '-')
- {
- *(p_ctx->aalg_str++) = 0;
- parser_set_state(p_ctx, ST_AA_END);
- break;
- }
- if (isalnum(ch) || ch == '_')
- {
- *(p_ctx->aalg_str++) = ch;
- break;
- }
- p_ctx->err = "Non alphanum or valid separator found in auth string";
- goto err;
- case ST_AA_END:
- if (isdigit(ch))
- {
- parser_set_state(p_ctx, ST_AK);
- goto re_eval;
- }
- /* Only allow modpXXXX string if we have a modp_getbyname method */
- if ((p_ctx->modp_getbyname) && isalpha(ch))
- {
- parser_set_state(p_ctx, ST_MODP);
- goto re_eval;
- }
- p_ctx->err = "Non initial digit found for auth keylen";
- goto err;
- case ST_AK:
- if (ch=='-')
- {
- parser_set_state(p_ctx, ST_AK_END);
- break;
- }
- if (isdigit(ch))
+ if (token == NULL)
{
- p_ctx->aklen = p_ctx->aklen*10 + ch - '0';
- break;
+ return FAILED;
}
- p_ctx->err = "Non digit found for auth keylen";
- goto err;
- case ST_AK_END:
- /* Only allow modpXXXX string if we have a modp_getbyname method */
- if ((p_ctx->modp_getbyname) && isalpha(ch))
+ switch (token->type)
{
- parser_set_state(p_ctx, ST_MODP);
- goto re_eval;
- }
- p_ctx->err = "Non alpha char found after auth keylen";
- goto err;
- case ST_MODP:
- if (isalnum(ch))
- {
- *(p_ctx->modp_str++) = ch;
- break;
- }
- p_ctx->err = "Non alphanum char found after in modp string";
- goto err;
- case ST_FLAG_STRICT:
- if (ch == 0)
- parser_set_state(p_ctx, ST_END);
- p_ctx->err = "Flags character(s) must be at end of whole string";
- goto err;
-
- /* XXX */
- case ST_END:
- case ST_EOF:
- case ST_ERR:
- break;
- /* XXX */
- }
-out:
- return p_ctx->state;
-err:
- parser_set_state(p_ctx, ST_ERR);
- return ST_ERR;
+ case ENCRYPTION_ALGORITHM:
+ if (*ealg != 0)
+ {
+ return FAILED;
+ }
+ *ealg = (protoid == PROTO_ISAKMP) ?
+ oakley_from_encryption_algorithm(token->algorithm) :
+ esp_from_encryption_algorithm(token->algorithm);
+ if (*ealg == 0)
+ {
+ return FAILED;
+ }
+ *ealg_keysize = token->keysize;
+ break;
+ case INTEGRITY_ALGORITHM:
+ if (*aalg != 0)
+ {
+ return FAILED;
+ }
+ *aalg = (protoid == PROTO_ISAKMP) ?
+ oakley_from_integrity_algorithm(token->algorithm) :
+ esp_from_integrity_algorithm(token->algorithm);
+ if (*aalg == 0)
+ {
+ return FAILED;
+ }
+ *aalg_keysize = token->keysize;
+ break;
+ case DIFFIE_HELLMAN_GROUP:
+ if (protoid == PROTO_ISAKMP)
+ {
+ if (*dh_group != 0)
+ {
+ return FAILED;
+ }
+ *dh_group = token->algorithm;
+ }
+ break;
+ default:
+ return FAILED;
+ }
+ return SUCCESS;
}
-/*
- * Must be called for each "new" char, with new
- * character in ctx.ch
- */
-static void
-parser_init(struct parser_context *p_ctx, unsigned protoid)
-{
- memset(p_ctx, 0, sizeof (*p_ctx));
- p_ctx->protoid = protoid; /* XXX: jjo */
- p_ctx->protoid = PROTO_IPSEC_ESP;
- p_ctx->ealg_str = p_ctx->ealg_buf;
- p_ctx->aalg_str = p_ctx->aalg_buf;
- p_ctx->modp_str = p_ctx->modp_buf;
- p_ctx->state = ST_INI;
-
- switch (protoid) {
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- p_ctx->ealg_getbyname = ealg_getbyname_ike;
- p_ctx->aalg_getbyname = aalg_getbyname_ike;
- p_ctx->modp_getbyname = modp_getbyname_ike;
- break;
-#endif
- case PROTO_IPSEC_ESP:
- p_ctx->ealg_getbyname = ealg_getbyname_esp;
- p_ctx->aalg_getbyname = aalg_getbyname_esp;
- break;
- }
-}
-static int
-parser_alg_info_add(struct parser_context *p_ctx, struct alg_info *alg_info)
+static status_t alg_info_parse_str(struct alg_info *alg_info, char *alg_str)
{
- int ealg_id = 0;
- int aalg_id = 0;
- int modp_id = 0;
-#ifndef NO_PLUTO
- const struct oakley_group_desc *gd;
-#endif
+ char *strict, *single;
+ status_t status = SUCCESS;
- if (*p_ctx->ealg_buf)
- {
- ealg_id = p_ctx->ealg_getbyname(p_ctx->ealg_buf, strlen(p_ctx->ealg_buf));
- if (ealg_id == ESP_MAGIC_ID)
- {
- ealg_id = p_ctx->eklen;
- p_ctx->eklen = 0;
- }
- if (ealg_id < 0)
+ strict = alg_str + strlen(alg_str) - 1;
+ if (*strict == '!')
{
- p_ctx->err = "enc_alg not found";
- return -1;
+ alg_info->alg_info_flags |= ALG_INFO_F_STRICT;
+ *strict = '\0';
}
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() ealg_getbyname(\"%s\")=%d"
- , p_ctx->ealg_buf
- , ealg_id)
- )
- }
- if (*p_ctx->aalg_buf)
- {
- aalg_id = p_ctx->aalg_getbyname(p_ctx->aalg_buf, strlen(p_ctx->aalg_buf));
- if (aalg_id < 0)
+ while ((single = strsep(&alg_str, ",")))
{
- p_ctx->err = "hash_alg not found";
- return -1;
- }
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() aalg_getbyname(\"%s\")=%d"
- , p_ctx->aalg_buf
- , aalg_id)
- )
- }
- if (p_ctx->modp_getbyname && *p_ctx->modp_buf)
- {
- modp_id = p_ctx->modp_getbyname(p_ctx->modp_buf, strlen(p_ctx->modp_buf));
- if (modp_id < 0)
- {
- p_ctx->err = "modp group not found";
- return -1;
- }
- DBG(DBG_CRYPT,
- DBG_log("parser_alg_info_add() modp_getbyname(\"%s\")=%d"
- , p_ctx->modp_buf
- , modp_id)
- )
- }
- switch (alg_info->alg_info_protoid) {
- case PROTO_IPSEC_ESP:
- alg_info_esp_add(alg_info,
- ealg_id, p_ctx->eklen,
- aalg_id, p_ctx->aklen);
- break;
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- if (modp_id && !(gd = lookup_group(modp_id)))
- {
- p_ctx->err = "found modp group id, but not supported";
- return -1;
- }
- alg_info_ike_add(alg_info,
- ealg_id, p_ctx->eklen,
- aalg_id, p_ctx->aklen,
- modp_id);
- break;
-#endif
- default:
- return -1;
- }
- return 0;
-}
+ chunk_t string = { (u_char *)single, strlen(single) };
+ int ealg = 0;
+ int aalg = 0;
+ int dh_group = 0;
+ size_t ealg_keysize = 0;
+ size_t aalg_keysize = 0;
-static int
-alg_info_parse_str (struct alg_info *alg_info, const char *alg_str, const char **err_p)
-{
- struct parser_context ctx;
- int ret;
- const char *ptr;
- static char err_buf[256];
-
- *err_buf = 0;
- parser_init(&ctx, alg_info->alg_info_protoid);
- if (err_p)
- *err_p = NULL;
+ eat_whitespace(&string);
- /* use default if nul esp string */
- if (!*alg_str)
- {
- switch (alg_info->alg_info_protoid) {
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- alg_info_ike_add(alg_info, 0, 0, 0, 0, 0);
- return 0;
-#endif
- case PROTO_IPSEC_ESP:
- alg_info_esp_add(alg_info, 0, 0, 0, 0);
- return 0;
- default:
- /* IMPOSSIBLE */
- passert(alg_info->alg_info_protoid);
- }
- }
+ if (string.len > 0)
+ {
+ chunk_t alg;
+
+ /* get all token, separated by '-' */
+ while (extract_token(&alg, '-', &string))
+ {
+ status |= alg_info_add(alg, alg_info->alg_info_protoid,
+ &ealg, &ealg_keysize,
+ &aalg, &aalg_keysize, &dh_group);
+ }
+ if (string.len)
+ {
+ status |= alg_info_add(string, alg_info->alg_info_protoid,
+ &ealg, &ealg_keysize,
+ &aalg, &aalg_keysize, &dh_group);
+ }
+ }
+ if (status == SUCCESS)
- for (ret = 0, ptr = alg_str; ret < ST_EOF;)
- {
- ctx.ch = *ptr++;
- ret = parser_machine(&ctx);
-
- switch (ret) {
- case ST_FLAG_STRICT:
- alg_info->alg_info_flags |= ALG_INFO_F_STRICT;
- break;
- case ST_END:
- case ST_EOF:
- DBG(DBG_CRYPT,
- DBG_log("alg_info_parse_str() ealg_buf=%s aalg_buf=%s"
- "eklen=%d aklen=%d",
- ctx.ealg_buf, ctx.aalg_buf,
- ctx.eklen, ctx.aklen)
- )
- if (parser_alg_info_add(&ctx, alg_info) < 0)
- {
- snprintf(err_buf, sizeof(err_buf),
- "%s, enc_alg=\"%s\", auth_alg=\"%s\", modp=\"%s\"",
- ctx.err,
- ctx.ealg_buf,
- ctx.aalg_buf,
- ctx.modp_buf);
- goto err;
- }
- /* zero out for next run (ST_END) */
- parser_init(&ctx, alg_info->alg_info_protoid);
- break;
- case ST_ERR:
- snprintf(err_buf, sizeof(err_buf),
- "%s, just after \"%.*s\" (old_state=%s)",
- ctx.err,
- (int)(ptr-alg_str-1), alg_str ,
- parser_state_name_esp(ctx.old_state));
- goto err;
- default:
- if (!ctx.ch)
- break;
+ {
+ switch (alg_info->alg_info_protoid)
+ {
+ case PROTO_IPSEC_ESP:
+ alg_info_esp_add(alg_info, ealg, ealg_keysize,
+ aalg, aalg_keysize);
+ break;
+ case PROTO_ISAKMP:
+ alg_info_ike_add(alg_info, ealg, ealg_keysize,
+ aalg, aalg_keysize,
+ dh_group);
+ break;
+ default:
+ break;
+ }
+ }
}
- }
- return 0;
-err:
- if (err_p)
- *err_p=err_buf;
- return -1;
+ return status;
}
-struct alg_info_esp *
-alg_info_esp_create_from_str (const char *alg_str, const char **err_p)
+struct alg_info_esp *alg_info_esp_create_from_str(char *alg_str)
{
- struct alg_info_esp *alg_info_esp;
- char esp_buf[256];
- static char err_buf[256];
- char *pfs_name;
- int ret = 0;
- /*
- * alg_info storage should be sized dynamically
- * but this may require 2passes to know
- * transform count in advance.
- */
- alg_info_esp = alloc_thing (struct alg_info_esp, "alg_info_esp");
- if (!alg_info_esp)
- goto out;
-
- pfs_name=index (alg_str, ';');
- if (pfs_name)
- {
- memcpy(esp_buf, alg_str, pfs_name-alg_str);
- esp_buf[pfs_name-alg_str] = 0;
- alg_str = esp_buf;
- pfs_name++;
-
- /* if pfs strings AND first char is not '0' */
- if (*pfs_name && pfs_name[0] != '0')
+ struct alg_info_esp *alg_info_esp;
+ char esp_buf[BUF_LEN];
+ char *pfs_name;
+ status_t status = SUCCESS;
+ /*
+ * alg_info storage should be sized dynamically
+ * but this may require 2passes to know
+ * transform count in advance.
+ */
+ alg_info_esp = malloc_thing (struct alg_info_esp);
+ zero(alg_info_esp);
+
+ pfs_name=index (alg_str, ';');
+ if (pfs_name)
{
- ret = modp_getbyname_esp(pfs_name, strlen(pfs_name));
- if (ret < 0)
- {
- /* Bomb if pfsgroup not found */
- DBG(DBG_CRYPT,
- DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found"
- , pfs_name)
- )
- if (*err_p)
- {
- snprintf(err_buf, sizeof(err_buf),
- "pfsgroup \"%s\" not found",
- pfs_name);
+ memcpy(esp_buf, alg_str, pfs_name-alg_str);
+ esp_buf[pfs_name-alg_str] = 0;
+ alg_str = esp_buf;
+ pfs_name++;
- *err_p = err_buf;
+ /* if pfs strings AND first char is not '0' */
+ if (*pfs_name && pfs_name[0] != '0')
+ {
+ const proposal_token_t *token;
+
+ token = proposal_get_token(pfs_name, strlen(pfs_name));
+ if (token == NULL || token->type != DIFFIE_HELLMAN_GROUP)
+ {
+ /* Bomb if pfsgroup not found */
+ DBG(DBG_CRYPT,
+ DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found"
+ , pfs_name)
+ )
+ status = FAILED;
+ goto out;
+ }
+ alg_info_esp->esp_pfsgroup = token->algorithm;
}
- goto out;
- }
- alg_info_esp->esp_pfsgroup = ret;
}
- }
- else
- alg_info_esp->esp_pfsgroup = 0;
-
- alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP;
- ret = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str, err_p) ;
+ else
+ {
+ alg_info_esp->esp_pfsgroup = 0;
+ }
+ alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP;
+ status = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str);
+
out:
- if (ret < 0)
- {
- pfreeany(alg_info_esp);
- alg_info_esp = NULL;
- }
- return alg_info_esp;
+ if (status != SUCCESS)
+ {
+ free(alg_info_esp);
+ alg_info_esp = NULL;
+ }
+ return alg_info_esp;
}
-#ifndef NO_PLUTO
-struct alg_info_ike *
-alg_info_ike_create_from_str (const char *alg_str, const char **err_p)
+struct alg_info_ike *alg_info_ike_create_from_str(char *alg_str)
{
- struct alg_info_ike *alg_info_ike;
- /*
- * alg_info storage should be sized dynamically
- * but this may require 2passes to know
- * transform count in advance.
- */
- alg_info_ike = alloc_thing (struct alg_info_ike, "alg_info_ike");
- alg_info_ike->alg_info_protoid = PROTO_ISAKMP;
-
- if (alg_info_parse_str((struct alg_info *)alg_info_ike,
- alg_str, err_p) < 0)
- {
- pfreeany(alg_info_ike);
- return NULL;
- }
- return alg_info_ike;
+ struct alg_info_ike *alg_info_ike;
+ /*
+ * alg_info storage should be sized dynamically
+ * but this may require 2passes to know
+ * transform count in advance.
+ */
+ alg_info_ike = malloc_thing (struct alg_info_ike);
+ zero(alg_info_ike);
+ alg_info_ike->alg_info_protoid = PROTO_ISAKMP;
+
+ if (alg_info_parse_str((struct alg_info *)alg_info_ike, alg_str) != SUCCESS)
+ {
+ free(alg_info_ike);
+ return NULL;
+ }
+ return alg_info_ike;
}
-#endif
/*
- * alg_info struct can be shared by
- * several connections instances,
- * handle free() with ref_cnts
+ * alg_info struct can be shared by
+ * several connections instances,
+ * handle free() with ref_cnts
*/
void
alg_info_addref(struct alg_info *alg_info)
{
- if (alg_info != NULL)
- {
- alg_info->ref_cnt++;
- DBG(DBG_CRYPT,
- DBG_log("alg_info_addref() alg_info->ref_cnt=%d"
- , alg_info->ref_cnt)
- )
- }
+ if (alg_info != NULL)
+ {
+ alg_info->ref_cnt++;
+ }
}
void
alg_info_delref(struct alg_info **alg_info_p)
{
- struct alg_info *alg_info = *alg_info_p;
+ struct alg_info *alg_info = *alg_info_p;
- if (alg_info != NULL)
- {
- passert(alg_info->ref_cnt != 0);
- alg_info->ref_cnt--;
- DBG(DBG_CRYPT,
- DBG_log("alg_info_delref() alg_info->ref_cnt=%d"
- , alg_info->ref_cnt)
- )
- if (alg_info->ref_cnt == 0)
+ if (alg_info != NULL)
{
- DBG(DBG_CRYPT,
- DBG_log("alg_info_delref() freeing alg_info")
- )
- alg_info_free(alg_info);
+ passert(alg_info->ref_cnt != 0);
+ alg_info->ref_cnt--;
+ if (alg_info->ref_cnt == 0)
+ {
+ alg_info_free(alg_info);
+ }
+ *alg_info_p = NULL;
}
- *alg_info_p = NULL;
- }
}
/* snprint already parsed transform list (alg_info) */
int
alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info)
{
- char *ptr = buf;
- int np = 0;
- struct esp_info *esp_info;
-#ifndef NO_PLUTO
- struct ike_info *ike_info;
-#endif
- int cnt;
-
- switch (alg_info->alg_info_protoid) {
- case PROTO_IPSEC_ESP:
- {
- struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info;
+ char *ptr = buf;
+ int np = 0;
+ struct esp_info *esp_info;
+ struct ike_info *ike_info;
+ int cnt;
+
+ switch (alg_info->alg_info_protoid) {
+ case PROTO_IPSEC_ESP:
+ {
+ struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info;
+
+ ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt)
+ {
+ np = snprintf(ptr, buflen, "%s",
+ enum_show(&esp_transformid_names, esp_info->esp_ealg_id));
+ ptr += np;
+ buflen -= np;
+ if (esp_info->esp_ealg_keylen)
+ {
+ np = snprintf(ptr, buflen, "_%u", esp_info->esp_ealg_keylen);
+ ptr += np;
+ buflen -= np;
+ }
+ np = snprintf(ptr, buflen, "/%s, ",
+ enum_show(&auth_alg_names, esp_info->esp_aalg_id));
+ ptr += np;
+ buflen -= np;
+ if (buflen < 0)
+ goto out;
+ }
+ if (alg_info_esp->esp_pfsgroup)
+ {
+ np = snprintf(ptr, buflen, "; pfsgroup=%s; ",
+ enum_show(&oakley_group_names, alg_info_esp->esp_pfsgroup));
+ ptr += np;
+ buflen -= np;
+ if (buflen < 0)
+ goto out;
+ }
+ break;
+ }
- ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt)
- {
- np = snprintf(ptr, buflen, "%d_%03d-%d, "
- , esp_info->esp_ealg_id
- , (int)esp_info->esp_ealg_keylen
- , esp_info->esp_aalg_id);
- ptr += np;
- buflen -= np;
- if (buflen < 0)
- goto out;
- }
- if (alg_info_esp->esp_pfsgroup)
- {
- np = snprintf(ptr, buflen, "; pfsgroup=%d; "
- , alg_info_esp->esp_pfsgroup);
+ case PROTO_ISAKMP:
+ ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt)
+ {
+ np = snprintf(ptr, buflen, "%s",
+ enum_show(&oakley_enc_names, ike_info->ike_ealg));
+ ptr += np;
+ buflen -= np;
+ if (ike_info->ike_eklen)
+ {
+ np = snprintf(ptr, buflen, "_%u", ike_info->ike_eklen);
+ ptr += np;
+ buflen -= np;
+ }
+ np = snprintf(ptr, buflen, "/%s/%s, ",
+ enum_show(&oakley_hash_names, ike_info->ike_halg),
+ enum_show(&oakley_group_names, ike_info->ike_modp));
+ ptr += np;
+ buflen -= np;
+ if (buflen < 0)
+ goto out;
+ }
+ break;
+ default:
+ np = snprintf(buf, buflen, "INVALID protoid=%d\n"
+ , alg_info->alg_info_protoid);
ptr += np;
buflen -= np;
- if (buflen < 0)
- goto out;
- }
- break;
- }
-#ifndef NO_PLUTO
- case PROTO_ISAKMP:
- ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt)
- {
- np = snprintf(ptr, buflen, "%d_%03d-%d-%d, "
- , ike_info->ike_ealg
- , (int)ike_info->ike_eklen
- , ike_info->ike_halg
- , ike_info->ike_modp);
- ptr += np;
- buflen -= np;
- if (buflen < 0)
goto out;
- }
- break;
-#endif
- default:
- np = snprintf(buf, buflen, "INVALID protoid=%d\n"
- , alg_info->alg_info_protoid);
- ptr += np;
- buflen -= np;
- goto out;
}
np = snprintf(ptr, buflen, "%s"
- , alg_info->alg_info_flags & ALG_INFO_F_STRICT?
- "strict":"");
+ , alg_info->alg_info_flags & ALG_INFO_F_STRICT?
+ "strict":"");
ptr += np;
buflen -= np;
out:
- if (buflen < 0)
- {
- loglog(RC_LOG_SERIOUS
- , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d"
- , buflen);
- }
-
- return ptr - buf;
+ if (buflen < 0)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d"
+ , buflen);
+ }
+
+ return ptr - buf;
}
-#ifndef NO_PLUTO
-int
-alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info)
+int alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info)
{
- char *ptr = buf;
+ char *ptr = buf;
- int cnt = alg_info->alg_info_cnt;
- struct esp_info *esp_info = alg_info->esp;
+ int cnt = alg_info->alg_info_cnt;
+ struct esp_info *esp_info = alg_info->esp;
- while (cnt--)
- {
- if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL)
- && kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL))
+ while (cnt--)
{
- u_int eklen = (esp_info->esp_ealg_keylen)
- ? esp_info->esp_ealg_keylen
- : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id)
- * BITS_PER_BYTE;
-
- u_int aklen = esp_info->esp_aalg_keylen
- ? esp_info->esp_aalg_keylen
- : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id)
- * BITS_PER_BYTE;
-
- int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ",
- esp_info->esp_ealg_id, eklen,
- esp_info->esp_aalg_id, aklen);
- ptr += ret;
- buflen -= ret;
- if (buflen < 0)
- break;
+ if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL)
+ && kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL))
+ {
+ u_int eklen = (esp_info->esp_ealg_keylen)
+ ? esp_info->esp_ealg_keylen
+ : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id)
+ * BITS_PER_BYTE;
+
+ u_int aklen = esp_info->esp_aalg_keylen
+ ? esp_info->esp_aalg_keylen
+ : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id)
+ * BITS_PER_BYTE;
+
+ int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ",
+ esp_info->esp_ealg_id, eklen,
+ esp_info->esp_aalg_id, aklen);
+ ptr += ret;
+ buflen -= ret;
+ if (buflen < 0)
+ break;
+ }
+ esp_info++;
}
- esp_info++;
- }
- return ptr - buf;
+ return ptr - buf;
}
-int
-alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info)
+int alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info)
{
- char *ptr = buf;
-
- int cnt = alg_info->alg_info_cnt;
- struct ike_info *ike_info = alg_info->ike;
+ char *ptr = buf;
- while (cnt--)
- {
- struct encrypt_desc *enc_desc = ike_alg_get_encrypter(ike_info->ike_ealg);
- struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg);
+ int cnt = alg_info->alg_info_cnt;
+ struct ike_info *ike_info = alg_info->ike;
- if (enc_desc != NULL && hash_desc != NULL
- && lookup_group(ike_info->ike_modp))
+ while (cnt--)
{
+ struct encrypt_desc *enc_desc = ike_alg_get_crypter(ike_info->ike_ealg);
+ struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg);
+ struct dh_desc *dh_desc = ike_alg_get_dh_group(ike_info->ike_modp);
- u_int eklen = (ike_info->ike_eklen)
- ? ike_info->ike_eklen
- : enc_desc->keydeflen;
-
- u_int aklen = (ike_info->ike_hklen)
- ? ike_info->ike_hklen
- : hash_desc->hash_digest_size * BITS_PER_BYTE;
+ if (enc_desc && hash_desc && dh_desc)
+ {
- int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ",
- ike_info->ike_ealg, eklen,
- ike_info->ike_halg, aklen,
- ike_info->ike_modp);
- ptr += ret;
- buflen -= ret;
- if (buflen < 0)
- break;
+ u_int eklen = (ike_info->ike_eklen)
+ ? ike_info->ike_eklen
+ : enc_desc->keydeflen;
+
+ u_int aklen = (ike_info->ike_hklen)
+ ? ike_info->ike_hklen
+ : hash_desc->hash_digest_size * BITS_PER_BYTE;
+
+ int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ",
+ ike_info->ike_ealg, eklen,
+ ike_info->ike_halg, aklen,
+ ike_info->ike_modp);
+ ptr += ret;
+ buflen -= ret;
+ if (buflen < 0)
+ break;
+ }
+ ike_info++;
}
- ike_info++;
- }
- return ptr - buf;
+ return ptr - buf;
}
-#endif /* NO_PLUTO */
+
diff --git a/src/pluto/alg_info.h b/src/pluto/alg_info.h
index cacc2a354..fcf7efca0 100644
--- a/src/pluto/alg_info.h
+++ b/src/pluto/alg_info.h
@@ -10,76 +10,71 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: alg_info.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef ALG_INFO_H
#define ALG_INFO_H
struct esp_info {
- u_int8_t transid; /* ESP transform */
- u_int16_t auth; /* AUTH */
- size_t enckeylen; /* keylength for ESP transform */
- size_t authkeylen; /* keylength for AUTH */
- u_int8_t encryptalg; /* normally encryptalg=transid */
- u_int8_t authalg; /* normally authalg=auth+1 */
+ u_int8_t transid; /* ESP transform */
+ u_int16_t auth; /* AUTH */
+ size_t enckeylen; /* keylength for ESP transform */
+ size_t authkeylen; /* keylength for AUTH */
+ u_int8_t encryptalg; /* normally encryptalg=transid */
+ u_int8_t authalg; /* normally authalg=auth+1 */
};
struct ike_info {
- u_int16_t ike_ealg; /* high 16 bit nums for reserved */
- u_int8_t ike_halg;
- size_t ike_eklen;
- size_t ike_hklen;
- u_int16_t ike_modp;
+ u_int16_t ike_ealg; /* high 16 bit nums for reserved */
+ u_int8_t ike_halg;
+ size_t ike_eklen;
+ size_t ike_hklen;
+ u_int16_t ike_modp;
};
#define ALG_INFO_COMMON \
- int alg_info_cnt; \
- int ref_cnt; \
- unsigned alg_info_flags; \
- unsigned alg_info_protoid
+ int alg_info_cnt; \
+ int ref_cnt; \
+ unsigned alg_info_flags; \
+ unsigned alg_info_protoid
struct alg_info {
- ALG_INFO_COMMON;
+ ALG_INFO_COMMON;
};
struct alg_info_esp {
- ALG_INFO_COMMON;
- struct esp_info esp[64];
- int esp_pfsgroup;
+ ALG_INFO_COMMON;
+ struct esp_info esp[64];
+ int esp_pfsgroup;
};
struct alg_info_ike {
- ALG_INFO_COMMON;
- struct ike_info ike[64];
+ ALG_INFO_COMMON;
+ struct ike_info ike[64];
};
#define esp_ealg_id transid
#define esp_aalg_id auth
-#define esp_ealg_keylen enckeylen /* bits */
-#define esp_aalg_keylen authkeylen /* bits */
+#define esp_ealg_keylen enckeylen /* bits */
+#define esp_aalg_keylen authkeylen /* bits */
-/* alg_info_flags bits */
-#define ALG_INFO_F_STRICT 0x01
+/* alg_info_flags bits */
+#define ALG_INFO_F_STRICT 0x01
extern int alg_info_esp_aa2sadb(int auth);
extern int alg_info_esp_sadb2aa(int sadb_aalg);
extern void alg_info_free(struct alg_info *alg_info);
extern void alg_info_addref(struct alg_info *alg_info);
extern void alg_info_delref(struct alg_info **alg_info);
-extern struct alg_info_esp* alg_info_esp_create_from_str(const char *alg_str
- , const char **err_p);
-extern struct alg_info_ike* alg_info_ike_create_from_str(const char *alg_str
- , const char **err_p);
+extern struct alg_info_esp* alg_info_esp_create_from_str(char *alg_str);
+extern struct alg_info_ike* alg_info_ike_create_from_str(char *alg_str);
extern int alg_info_parse(const char *str);
-extern int alg_info_snprint(char *buf, int buflen
- , struct alg_info *alg_info);
+extern int alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info);
extern int alg_info_snprint_esp(char *buf, int buflen
- , struct alg_info_esp *alg_info);
+ , struct alg_info_esp *alg_info);
extern int alg_info_snprint_ike(char *buf, int buflen
- , struct alg_info_ike *alg_info);
+ , struct alg_info_ike *alg_info);
#define ALG_INFO_ESP_FOREACH(ai, ai_esp, i) \
- for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++)
+ for (i=(ai)->alg_info_cnt,ai_esp=(ai)->esp; i--; ai_esp++)
#define ALG_INFO_IKE_FOREACH(ai, ai_ike, i) \
- for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++)
+ for (i=(ai)->alg_info_cnt,ai_ike=(ai)->ike; i--; ai_ike++)
#endif /* ALG_INFO_H */
diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c
deleted file mode 100644
index 6f3695874..000000000
--- a/src/pluto/asn1.c
+++ /dev/null
@@ -1,806 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: asn1.c 5041 2009-03-27 08:58:48Z andreas $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
-#include "log.h"
-
-/* some common prefabricated ASN.1 constants */
-
-static u_char ASN1_INTEGER_0_str[] = { 0x02, 0x00 };
-static u_char ASN1_INTEGER_1_str[] = { 0x02, 0x01, 0x01 };
-static u_char ASN1_INTEGER_2_str[] = { 0x02, 0x01, 0x02 };
-
-const chunk_t ASN1_INTEGER_0 = strchunk(ASN1_INTEGER_0_str);
-const chunk_t ASN1_INTEGER_1 = strchunk(ASN1_INTEGER_1_str);
-const chunk_t ASN1_INTEGER_2 = strchunk(ASN1_INTEGER_2_str);
-
-/* some popular algorithmIdentifiers */
-
-static u_char ASN1_md5_id_str[] = {
- 0x30, 0x0C,
- 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
- 0x05, 0x00
-};
-
-static u_char ASN1_sha1_id_str[] = {
- 0x30, 0x09,
- 0x06, 0x05, 0x2B, 0x0E,0x03, 0x02, 0x1A,
- 0x05, 0x00
-};
-
-static u_char ASN1_md5WithRSA_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04,
- 0x05, 0x00
-};
-
-static u_char ASN1_sha1WithRSA_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05,
- 0x05, 0x00
-};
-
-static u_char ASN1_rsaEncryption_id_str[] = {
- 0x30, 0x0D,
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
- 0x05, 0x00
-};
-
-const chunk_t ASN1_md5_id = strchunk(ASN1_md5_id_str);
-const chunk_t ASN1_sha1_id = strchunk(ASN1_sha1_id_str);
-const chunk_t ASN1_rsaEncryption_id = strchunk(ASN1_rsaEncryption_id_str);
-const chunk_t ASN1_md5WithRSA_id = strchunk(ASN1_md5WithRSA_id_str);
-const chunk_t ASN1_sha1WithRSA_id = strchunk(ASN1_sha1WithRSA_id_str);
-
-/* ASN.1 definition of an algorithmIdentifier */
-
-static const asn1Object_t algorithmIdentifierObjects[] = {
- { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "parameters", ASN1_EOC, ASN1_OPT |
- ASN1_RAW }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define ALGORITHM_ID_ALG 1
-#define ALGORITHM_ID_PARAMETERS 2
-#define ALGORITHM_ID_ROOF 4
-
-/*
- * return the ASN.1 encoded algorithm identifier
- */
-chunk_t
-asn1_algorithmIdentifier(int oid)
-{
- switch (oid)
- {
- case OID_RSA_ENCRYPTION:
- return ASN1_rsaEncryption_id;
- case OID_MD5_WITH_RSA:
- return ASN1_md5WithRSA_id;
- case OID_SHA1_WITH_RSA:
- return ASN1_sha1WithRSA_id;
- case OID_MD5:
- return ASN1_md5_id;
- case OID_SHA1:
- return ASN1_sha1_id;
- default:
- return empty_chunk;
- }
-}
-
-/* If the oid is listed in the oid_names table then the corresponding
- * position in the oid_names table is returned otherwise -1 is returned
- */
-int
-known_oid(chunk_t object)
-{
- int oid = 0;
-
- while (object.len)
- {
- if (oid_names[oid].octet == *object.ptr)
- {
- if (--object.len == 0 || oid_names[oid].down == 0)
- {
- return oid; /* found terminal symbol */
- }
- else
- {
- object.ptr++; oid++; /* advance to next hex octet */
- }
- }
- else
- {
- if (oid_names[oid].next)
- oid = oid_names[oid].next;
- else
- return OID_UNKNOWN;
- }
- }
- return -1;
-}
-
-/*
- * Decodes the length in bytes of an ASN.1 object
- */
-u_int
-asn1_length(chunk_t *blob)
-{
- u_char n;
- size_t len;
-
- /* advance from tag field on to length field */
- blob->ptr++;
- blob->len--;
-
- /* read first octet of length field */
- n = *blob->ptr++;
- blob->len--;
-
- if ((n & 0x80) == 0) /* single length octet */
- return n;
-
- /* composite length, determine number of length octets */
- n &= 0x7f;
-
- if (n > blob->len)
- {
- DBG(DBG_PARSING,
- DBG_log("number of length octets is larger than ASN.1 object")
- )
- return ASN1_INVALID_LENGTH;
- }
-
- if (n > sizeof(len))
- {
- DBG(DBG_PARSING,
- DBG_log("number of length octets is larger than limit of %d octets"
- , (int)sizeof(len))
- )
- return ASN1_INVALID_LENGTH;
- }
-
- len = 0;
-
- while (n-- > 0)
- {
- len = 256*len + *blob->ptr++;
- blob->len--;
- }
- if (len > blob->len)
- {
- DBG(DBG_PARSING,
- DBG_log("length is larger than remaining blob size")
- )
- return ASN1_INVALID_LENGTH;
- }
- return len;
-}
-
-/*
- * codes ASN.1 lengths up to a size of 16'777'215 bytes
- */
-void
-code_asn1_length(size_t length, chunk_t *code)
-{
- if (length < 128)
- {
- code->ptr[0] = length;
- code->len = 1;
- }
- else if (length < 256)
- {
- code->ptr[0] = 0x81;
- code->ptr[1] = (u_char) length;
- code->len = 2;
- }
- else if (length < 65536)
- {
- code->ptr[0] = 0x82;
- code->ptr[1] = length >> 8;
- code->ptr[2] = length & 0x00ff;
- code->len = 3;
- }
- else
- {
- code->ptr[0] = 0x83;
- code->ptr[1] = length >> 16;
- code->ptr[2] = (length >> 8) & 0x00ff;
- code->ptr[3] = length & 0x0000ff;
- code->len = 4;
- }
-}
-
-/*
- * build an empty asn.1 object with tag and length fields already filled in
- */
-u_char*
-build_asn1_object(chunk_t *object, asn1_t type, size_t datalen)
-{
- u_char length_buf[4];
- chunk_t length = { length_buf, 0 };
- u_char *pos;
-
- /* code the asn.1 length field */
- code_asn1_length(datalen, &length);
-
- /* allocate memory for the asn.1 TLV object */
- object->len = 1 + length.len + datalen;
- object->ptr = alloc_bytes(object->len, "asn1 object");
-
- /* set position pointer at the start of the object */
- pos = object->ptr;
-
- /* copy the asn.1 tag field and advance the pointer */
- *pos++ = type;
-
- /* copy the asn.1 length field and advance the pointer */
- chunkcpy(pos, length);
-
- return pos;
-}
-
-/*
- * build a simple ASN.1 object
- */
-chunk_t
-asn1_simple_object(asn1_t tag, chunk_t content)
-{
- chunk_t object;
-
- u_char *pos = build_asn1_object(&object, tag, content.len);
- chunkcpy(pos, content);
-
- return object;
-}
-
-/* Build an ASN.1 object from a variable number of individual chunks.
- * Depending on the mode, chunks either are moved ('m') or copied ('c').
- */
-chunk_t
-asn1_wrap(asn1_t type, const char *mode, ...)
-{
- chunk_t construct;
- va_list chunks;
- u_char *pos;
- int i;
- int count = strlen(mode);
-
- /* sum up lengths of individual chunks */
- va_start(chunks, mode);
- construct.len = 0;
- for (i = 0; i < count; i++)
- {
- chunk_t ch = va_arg(chunks, chunk_t);
- construct.len += ch.len;
- }
- va_end(chunks);
-
- /* allocate needed memory for construct */
- pos = build_asn1_object(&construct, type, construct.len);
-
- /* copy or move the chunks */
- va_start(chunks, mode);
- for (i = 0; i < count; i++)
- {
- chunk_t ch = va_arg(chunks, chunk_t);
-
- switch (*mode++)
- {
- case 'm':
- mv_chunk(&pos, ch);
- break;
- case 'c':
- default:
- chunkcpy(pos, ch);
- }
- }
- va_end(chunks);
-
- return construct;
-}
-
-/*
- * convert a MP integer into a DER coded ASN.1 object
- */
-chunk_t
-asn1_integer_from_mpz(const mpz_t value)
-{
- size_t bits = mpz_sizeinbase(value, 2); /* size in bits */
- size_t size = 1 + bits / BITS_PER_BYTE; /* size in bytes */
- chunk_t n = mpz_to_n(value, size);
-
- return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
-/*
- * determines if a character string is of type ASN.1 printableString
- */
-bool
-is_printablestring(chunk_t str)
-{
- const char printablestring_charset[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
- u_int i;
-
- for (i = 0; i < str.len; i++)
- {
- if (strchr(printablestring_charset, str.ptr[i]) == NULL)
- return FALSE;
- }
- return TRUE;
-}
-
-#define TIME_MAX 0x7fffffff
-
-/*
- * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time
- */
-time_t
-asn1totime(const chunk_t *utctime, asn1_t type)
-{
- struct tm t;
- time_t tc, tz_offset;
- u_char *eot = NULL;
-
- if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
- {
- tz_offset = 0; /* Zulu time with a zero time zone offset */
- }
- else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL)
- {
- int tz_hour, tz_min;
-
- if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
- {
- return 0; /* error in positive timezone offset format */
- }
- tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */
- }
- else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL)
- {
- int tz_hour, tz_min;
-
- if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
- {
- return 0; /* error in negative timezone offset format */
- }
- tz_offset = -3600*tz_hour - 60*tz_min; /* negative time zone offset */
- }
- else
- {
- return 0; /* error in time format */
- }
-
- /* parse ASN.1 time string */
- {
- const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
- "%4d%2d%2d%2d%2d";
-
- if (sscanf(utctime->ptr, format, &t.tm_year, &t.tm_mon, &t.tm_mday,
- &t.tm_hour, &t.tm_min) != 5)
- {
- return 0; /* error in time st [yy]yymmddhhmm time format */
- }
- }
-
- /* is there a seconds field? */
- if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14))
- {
- if (sscanf(eot-2, "%2d", &t.tm_sec) != 1)
- {
- return 0; /* error in ss seconds field format */
- }
- }
- else
- {
- t.tm_sec = 0;
- }
-
- /* representation of year */
- if (t.tm_year >= 1900)
- {
- t.tm_year -= 1900;
- }
- else if (t.tm_year >= 100)
- {
- return 0;
- }
- else if (t.tm_year < 50)
- {
- t.tm_year += 100;
- }
-
- /* representation of month 0..11*/
- t.tm_mon--;
-
- /* set daylight saving time to off */
- t.tm_isdst = 0;
-
- /* convert to time_t */
- tc = mktime(&t);
-
- /* if no conversion overflow occurred, compensate timezone */
- return (tc == -1) ? TIME_MAX : (tc - timezone - tz_offset);
-}
-
-/*
- * convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
- */
-chunk_t
-timetoasn1(const time_t *time, asn1_t type)
-{
- int offset;
- const char *format;
- char buf[TIMETOA_BUF];
- chunk_t formatted_time;
- struct tm *t = gmtime(time);
-
- if (type == ASN1_GENERALIZEDTIME)
- {
- format = "%04d%02d%02d%02d%02d%02dZ";
- offset = 1900;
- }
- else /* ASN1_UTCTIME */
- {
- format = "%02d%02d%02d%02d%02d%02dZ";
- offset = (t->tm_year < 100)? 0 : -100;
- }
- sprintf(buf, format, t->tm_year + offset, t->tm_mon + 1, t->tm_mday
- , t->tm_hour, t->tm_min, t->tm_sec);
- formatted_time.ptr = buf;
- formatted_time.len = strlen(buf);
- return asn1_simple_object(type, formatted_time);
-}
-
-
-/*
- * Initializes the internal context of the ASN.1 parser
- */
-void
-asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0,
- bool implicit, u_int cond)
-{
- ctx->blobs[0] = blob;
- ctx->level0 = level0;
- ctx->implicit = implicit;
- ctx->cond = cond;
- memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr));
-}
-
-/*
- * print the value of an ASN.1 simple object
- */
-static void
-debug_asn1_simple_object(chunk_t object, asn1_t type, u_int cond)
-{
- int oid;
-
- switch (type)
- {
- case ASN1_OID:
- oid = known_oid(object);
- if (oid != OID_UNKNOWN)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%s'",oid_names[oid].name);
- )
- return;
- }
- break;
- case ASN1_UTF8STRING:
- case ASN1_IA5STRING:
- case ASN1_PRINTABLESTRING:
- case ASN1_T61STRING:
- case ASN1_VISIBLESTRING:
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", (int)object.len, object.ptr);
- )
- return;
- case ASN1_UTCTIME:
- case ASN1_GENERALIZEDTIME:
- DBG(DBG_PARSING,
- time_t time = asn1totime(&object, type);
- DBG_log(" '%s'", timetoa(&time, TRUE));
- )
- return;
- default:
- break;
- }
- DBG(cond,
- DBG_dump_chunk("", object);
- )
-}
-
-/*
- * Parses and extracts the next ASN.1 object
- */
-bool
-extract_object(asn1Object_t const *objects,
- u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx)
-{
- asn1Object_t obj = objects[*objectID];
- chunk_t *blob;
- chunk_t *blob1;
- u_char *start_ptr;
-
- *object = empty_chunk;
-
- if (obj.flags & ASN1_END) /* end of loop or option found */
- {
- if (ctx->loopAddr[obj.level] && ctx->blobs[obj.level+1].len > 0)
- {
- *objectID = ctx->loopAddr[obj.level]; /* another iteration */
- obj = objects[*objectID];
- }
- else
- {
- ctx->loopAddr[obj.level] = 0; /* exit loop or option*/
- return TRUE;
- }
- }
-
- *level = ctx->level0 + obj.level;
- blob = ctx->blobs + obj.level;
- blob1 = blob + 1;
- start_ptr = blob->ptr;
-
- /* handle ASN.1 defaults values */
-
- if ((obj.flags & ASN1_DEF)
- && (blob->len == 0 || *start_ptr != obj.type) )
- {
- /* field is missing */
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", *level, obj.name);
- )
- if (obj.type & ASN1_CONSTRUCTED)
- {
- (*objectID)++ ; /* skip context-specific tag */
- }
- return TRUE;
- }
-
- /* handle ASN.1 options */
-
- if ((obj.flags & ASN1_OPT)
- && (blob->len == 0 || *start_ptr != obj.type))
- {
- /* advance to end of missing option field */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
-
- /* an ASN.1 object must possess at least a tag and length field */
-
- if (blob->len < 2)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
- *level, obj.name);
- )
- return FALSE;
- }
-
- blob1->len = asn1_length(blob);
-
- if (blob1->len == ASN1_INVALID_LENGTH)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
- *level, obj.name);
- )
- return FALSE;
- }
-
- blob1->ptr = blob->ptr;
- blob->ptr += blob1->len;
- blob->len -= blob1->len;
-
- /* return raw ASN.1 object without prior type checking */
-
- if (obj.flags & ASN1_RAW)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", *level, obj.name);
- )
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- return TRUE;
- }
-
- if (*start_ptr != obj.type && !(ctx->implicit && *objectID == 0))
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
- *level, obj.name, obj.type, *start_ptr);
- DBG_dump("", start_ptr, (u_int)(blob->ptr - start_ptr));
- )
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", ctx->level0+obj.level, obj.name);
- )
-
- /* In case of "SEQUENCE OF" or "SET OF" start a loop */
-
- if (obj.flags & ASN1_LOOP)
- {
- if (blob1->len > 0)
- {
- /* at least one item, start the loop */
- ctx->loopAddr[obj.level] = *objectID + 1;
- }
- else
- {
- /* no items, advance directly to end of loop */
- do
- (*objectID)++;
- while (!((objects[*objectID].flags & ASN1_END)
- && (objects[*objectID].level == obj.level)));
- return TRUE;
- }
- }
-
- if (obj.flags & ASN1_OBJ)
- {
- object->ptr = start_ptr;
- object->len = (size_t)(blob->ptr - start_ptr);
- DBG(ctx->cond,
- DBG_dump_chunk("", *object);
- )
- }
- else if (obj.flags & ASN1_BODY)
- {
- *object = *blob1;
- debug_asn1_simple_object(*object, obj.type, ctx->cond);
- }
- return TRUE;
-}
-
-/*
- * parse an ASN.1 simple type
- */
-bool
-parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
-, const char* name)
-{
- size_t len;
-
- /* an ASN.1 object must possess at least a tag and length field */
- if (object->len < 2)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN.1 object smaller than 2 octets",
- level, name);
- )
- return FALSE;
- }
-
- if (*object->ptr != type)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
- level, name, type, *object->ptr);
- )
- return FALSE;
- }
-
- len = asn1_length(object);
-
- if (len == ASN1_INVALID_LENGTH || object->len < len)
- {
- DBG(DBG_PARSING,
- DBG_log("L%d - %s: length of ASN.1 object invalid or too large",
- level, name);
- )
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_log("L%d - %s:", level, name);
- )
- debug_asn1_simple_object(*object, type, DBG_RAW);
- return TRUE;
-}
-
-/*
- * extracts an algorithmIdentifier
- */
-int
-parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int alg = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < ALGORITHM_ID_ROOF)
- {
- if (!extract_object(algorithmIdentifierObjects, &objectID, &object, &level, &ctx))
- return alg;
-
- switch (objectID)
- {
- case ALGORITHM_ID_ALG:
- alg = known_oid(object);
- break;
- case ALGORITHM_ID_PARAMETERS:
- if (parameters != NULL)
- *parameters = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- return alg;
- }
-
-/*
- * tests if a blob contains a valid ASN.1 set or sequence
- */
-bool
-is_asn1(chunk_t blob)
-{
- u_int len;
- u_char tag = *blob.ptr;
-
- if (tag != ASN1_SEQUENCE && tag != ASN1_SET)
- {
- DBG(DBG_PARSING,
- DBG_log(" file content is not binary ASN.1");
- )
- return FALSE;
- }
-
- len = asn1_length(&blob);
-
- /* exact match */
- if (len == blob.len)
- {
- return TRUE;
- }
-
- /* some websites append a surplus newline character to the blob */
- if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
- {
- return TRUE;
- }
-
- DBG(DBG_PARSING,
- DBG_log(" file size does not match ASN.1 coded length");
- )
- return FALSE;
-}
diff --git a/src/pluto/asn1.h b/src/pluto/asn1.h
deleted file mode 100644
index 730245e4a..000000000
--- a/src/pluto/asn1.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Simple ASN.1 parser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: asn1.h 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#ifndef _ASN1_H
-#define _ASN1_H
-
-#include <stdarg.h>
-#include <gmp.h>
-
-#include "defs.h"
-
-/* Defines some primitive ASN1 types */
-
-typedef enum {
- ASN1_EOC = 0x00,
- ASN1_BOOLEAN = 0x01,
- ASN1_INTEGER = 0x02,
- ASN1_BIT_STRING = 0x03,
- ASN1_OCTET_STRING = 0x04,
- ASN1_NULL = 0x05,
- ASN1_OID = 0x06,
- ASN1_ENUMERATED = 0x0A,
- ASN1_UTF8STRING = 0x0C,
- ASN1_NUMERICSTRING = 0x12,
- ASN1_PRINTABLESTRING = 0x13,
- ASN1_T61STRING = 0x14,
- ASN1_VIDEOTEXSTRING = 0x15,
- ASN1_IA5STRING = 0x16,
- ASN1_UTCTIME = 0x17,
- ASN1_GENERALIZEDTIME = 0x18,
- ASN1_GRAPHICSTRING = 0x19,
- ASN1_VISIBLESTRING = 0x1A,
- ASN1_GENERALSTRING = 0x1B,
- ASN1_UNIVERSALSTRING = 0x1C,
- ASN1_BMPSTRING = 0x1E,
-
- ASN1_CONSTRUCTED = 0x20,
-
- ASN1_SEQUENCE = 0x30,
-
- ASN1_SET = 0x31,
-
- ASN1_CONTEXT_S_0 = 0x80,
- ASN1_CONTEXT_S_1 = 0x81,
- ASN1_CONTEXT_S_2 = 0x82,
- ASN1_CONTEXT_S_3 = 0x83,
- ASN1_CONTEXT_S_4 = 0x84,
- ASN1_CONTEXT_S_5 = 0x85,
- ASN1_CONTEXT_S_6 = 0x86,
- ASN1_CONTEXT_S_7 = 0x87,
- ASN1_CONTEXT_S_8 = 0x88,
-
- ASN1_CONTEXT_C_0 = 0xA0,
- ASN1_CONTEXT_C_1 = 0xA1,
- ASN1_CONTEXT_C_2 = 0xA2,
- ASN1_CONTEXT_C_3 = 0xA3,
- ASN1_CONTEXT_C_4 = 0xA4,
- ASN1_CONTEXT_C_5 = 0xA5
-} asn1_t;
-
-/* Definition of ASN1 flags */
-
-#define ASN1_NONE 0x00
-#define ASN1_DEF 0x01
-#define ASN1_OPT 0x02
-#define ASN1_LOOP 0x04
-#define ASN1_END 0x08
-#define ASN1_OBJ 0x10
-#define ASN1_BODY 0x20
-#define ASN1_RAW 0x40
-
-#define ASN1_INVALID_LENGTH 0xffffffff
-
-/* definition of an ASN.1 object */
-
-typedef struct {
- u_int level;
- const u_char *name;
- asn1_t type;
- u_char flags;
-} asn1Object_t;
-
-#define ASN1_MAX_LEVEL 10
-
-typedef struct {
- bool implicit;
- u_int cond;
- u_int level0;
- u_int loopAddr[ASN1_MAX_LEVEL+1];
- chunk_t blobs[ASN1_MAX_LEVEL+2];
-} asn1_ctx_t;
-
-/* some common prefabricated ASN.1 constants */
-
-extern const chunk_t ASN1_INTEGER_0;
-extern const chunk_t ASN1_INTEGER_1;
-extern const chunk_t ASN1_INTEGER_2;
-
-/* some popular algorithmIdentifiers */
-extern const chunk_t ASN1_md5_id;
-extern const chunk_t ASN1_sha1_id;
-extern const chunk_t ASN1_rsaEncryption_id;
-extern const chunk_t ASN1_md5WithRSA_id;
-extern const chunk_t ASN1_sha1WithRSA_id;
-
-extern chunk_t asn1_algorithmIdentifier(int oid);
-extern int known_oid(chunk_t object);
-extern u_int asn1_length(chunk_t *blob);
-extern void code_asn1_length(size_t length, chunk_t *code);
-extern u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen);
-extern chunk_t asn1_integer_from_mpz(const mpz_t value);
-extern chunk_t asn1_simple_object(asn1_t tag, chunk_t content);
-extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
-extern bool is_printablestring(chunk_t str);
-extern time_t asn1totime(const chunk_t *utctime, asn1_t type);
-extern chunk_t timetoasn1(const time_t *time, asn1_t type);
-extern void asn1_init(asn1_ctx_t *ctx, chunk_t blob
- , u_int level0, bool implicit, u_int cond);
-extern bool extract_object(asn1Object_t const *objects
- , u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx);
-extern bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level
- , const char* name);
-extern int parse_algorithmIdentifier(chunk_t blob, int level0
- , chunk_t *parameters);
-extern bool is_asn1(chunk_t blob);
-
-#endif /* _ASN1_H */
-
diff --git a/src/pluto/ca.c b/src/pluto/ca.c
index 816db53a8..4fdb8cfe7 100644
--- a/src/pluto/ca.c
+++ b/src/pluto/ca.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ca.c 4709 2008-11-27 10:20:25Z martin $
*/
#include <stdlib.h>
@@ -23,7 +21,6 @@
#include <sys/types.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "constants.h"
#include "defs.h"
@@ -40,17 +37,17 @@
static x509cert_t *x509authcerts = NULL;
const ca_info_t empty_ca_info = {
- NULL , /* next */
- NULL , /* name */
- UNDEFINED_TIME,
- { NULL, 0 } , /* authName */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKey SerialNumber */
- NULL , /* ldaphost */
- NULL , /* ldapbase */
- NULL , /* ocspori */
- NULL , /* crluri */
- FALSE /* strictcrlpolicy */
+ NULL , /* next */
+ NULL , /* name */
+ UNDEFINED_TIME,
+ { NULL, 0 } , /* authName */
+ { NULL, 0 } , /* authKeyID */
+ { NULL, 0 } , /* authKey SerialNumber */
+ NULL , /* ldaphost */
+ NULL , /* ldapbase */
+ NULL , /* ocspori */
+ NULL , /* crluri */
+ FALSE /* strictcrlpolicy */
};
/* chained list of X.509 certification authority information records */
@@ -63,52 +60,52 @@ static ca_info_t *ca_infos = NULL;
bool
trusted_ca(chunk_t a, chunk_t b, int *pathlen)
{
- bool match = FALSE;
-
- /* no CA b specified -> any CA a is accepted */
- if (b.ptr == NULL)
- {
- *pathlen = (a.ptr == NULL)? 0 : MAX_CA_PATH_LEN;
- return TRUE;
- }
-
- /* no CA a specified -> trust cannot be established */
- if (a.ptr == NULL)
- {
- *pathlen = MAX_CA_PATH_LEN;
- return FALSE;
- }
+ bool match = FALSE;
+
+ /* no CA b specified -> any CA a is accepted */
+ if (b.ptr == NULL)
+ {
+ *pathlen = (a.ptr == NULL)? 0 : MAX_CA_PATH_LEN;
+ return TRUE;
+ }
+
+ /* no CA a specified -> trust cannot be established */
+ if (a.ptr == NULL)
+ {
+ *pathlen = MAX_CA_PATH_LEN;
+ return FALSE;
+ }
- *pathlen = 0;
+ *pathlen = 0;
- /* CA a equals CA b -> we have a match */
- if (same_dn(a, b))
- return TRUE;
+ /* CA a equals CA b -> we have a match */
+ if (same_dn(a, b))
+ return TRUE;
- /* CA a might be a subordinate CA of b */
- lock_authcert_list("trusted_ca");
+ /* CA a might be a subordinate CA of b */
+ lock_authcert_list("trusted_ca");
- while ((*pathlen)++ < MAX_CA_PATH_LEN)
- {
- x509cert_t *cacert = get_authcert(a, empty_chunk, empty_chunk, AUTH_CA);
+ while ((*pathlen)++ < MAX_CA_PATH_LEN)
+ {
+ x509cert_t *cacert = get_authcert(a, chunk_empty, chunk_empty, AUTH_CA);
- /* cacert not found or self-signed root cacert-> exit */
- if (cacert == NULL || same_dn(cacert->issuer, a))
- break;
+ /* cacert not found or self-signed root cacert-> exit */
+ if (cacert == NULL || same_dn(cacert->issuer, a))
+ break;
- /* does the issuer of CA a match CA b? */
- match = same_dn(cacert->issuer, b);
+ /* does the issuer of CA a match CA b? */
+ match = same_dn(cacert->issuer, b);
- /* we have a match and exit the loop */
- if (match)
- break;
+ /* we have a match and exit the loop */
+ if (match)
+ break;
- /* go one level up in the CA chain */
- a = cacert->issuer;
- }
-
- unlock_authcert_list("trusted_ca");
- return match;
+ /* go one level up in the CA chain */
+ a = cacert->issuer;
+ }
+
+ unlock_authcert_list("trusted_ca");
+ return match;
}
/*
@@ -117,36 +114,36 @@ trusted_ca(chunk_t a, chunk_t b, int *pathlen)
bool
match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen)
{
- /* if no ca is requested than any ca will match */
- if (requested_ca == NULL)
- {
- *our_pathlen = 0;
- return TRUE;
- }
-
- *our_pathlen = MAX_CA_PATH_LEN + 1;
+ /* if no ca is requested than any ca will match */
+ if (requested_ca == NULL)
+ {
+ *our_pathlen = 0;
+ return TRUE;
+ }
- while (requested_ca != NULL)
- {
- int pathlen;
+ *our_pathlen = MAX_CA_PATH_LEN + 1;
- if (trusted_ca(our_ca, requested_ca->name, &pathlen)
- && pathlen < *our_pathlen)
+ while (requested_ca != NULL)
{
- *our_pathlen = pathlen;
+ int pathlen;
+
+ if (trusted_ca(our_ca, requested_ca->name, &pathlen)
+ && pathlen < *our_pathlen)
+ {
+ *our_pathlen = pathlen;
+ }
+ requested_ca = requested_ca->next;
}
- requested_ca = requested_ca->next;
- }
- if (*our_pathlen > MAX_CA_PATH_LEN)
- {
- *our_pathlen = MAX_CA_PATH_LEN;
- return FALSE;
- }
- else
- {
- return TRUE;
- }
+ if (*our_pathlen > MAX_CA_PATH_LEN)
+ {
+ *our_pathlen = MAX_CA_PATH_LEN;
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
}
/*
@@ -155,9 +152,9 @@ match_requested_ca(generalName_t *requested_ca, chunk_t our_ca, int *our_pathlen
static void
free_first_authcert(void)
{
- x509cert_t *first = x509authcerts;
- x509authcerts = first->next;
- free_x509cert(first);
+ x509cert_t *first = x509authcerts;
+ x509authcerts = first->next;
+ free_x509cert(first);
}
/*
@@ -166,12 +163,12 @@ free_first_authcert(void)
void
free_authcerts(void)
{
- lock_authcert_list("free_authcerts");
+ lock_authcert_list("free_authcerts");
- while (x509authcerts != NULL)
- free_first_authcert();
+ while (x509authcerts != NULL)
+ free_first_authcert();
- unlock_authcert_list("free_authcerts");
+ unlock_authcert_list("free_authcerts");
}
/*
@@ -180,29 +177,29 @@ free_authcerts(void)
x509cert_t*
get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags)
{
- x509cert_t *cert = x509authcerts;
- x509cert_t *prev_cert = NULL;
-
- while (cert != NULL)
- {
- if (cert->authority_flags & auth_flags
- && ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
- : (same_dn(subject, cert->subject)
- && same_serial(serial, cert->serialNumber))))
+ x509cert_t *cert = x509authcerts;
+ x509cert_t *prev_cert = NULL;
+
+ while (cert != NULL)
{
- if (cert != x509authcerts)
- {
- /* bring the certificate up front */
- prev_cert->next = cert->next;
- cert->next = x509authcerts;
- x509authcerts = cert;
- }
- return cert;
+ if (cert->authority_flags & auth_flags
+ && ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
+ : (same_dn(subject, cert->subject)
+ && same_serial(serial, cert->serialNumber))))
+ {
+ if (cert != x509authcerts)
+ {
+ /* bring the certificate up front */
+ prev_cert->next = cert->next;
+ cert->next = x509authcerts;
+ x509authcerts = cert;
+ }
+ return cert;
+ }
+ prev_cert = cert;
+ cert = cert->next;
}
- prev_cert = cert;
- cert = cert->next;
- }
- return NULL;
+ return NULL;
}
/*
@@ -211,49 +208,49 @@ get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid, u_char auth_flags)
x509cert_t*
add_authcert(x509cert_t *cert, u_char auth_flags)
{
- x509cert_t *old_cert;
+ x509cert_t *old_cert;
- /* set authority flags */
- cert->authority_flags |= auth_flags;
+ /* set authority flags */
+ cert->authority_flags |= auth_flags;
- lock_authcert_list("add_authcert");
+ lock_authcert_list("add_authcert");
- old_cert = get_authcert(cert->subject, cert->serialNumber
- , cert->subjectKeyID, auth_flags);
+ old_cert = get_authcert(cert->subject, cert->serialNumber
+ , cert->subjectKeyID, auth_flags);
- if (old_cert != NULL)
- {
- if (same_x509cert(cert, old_cert))
- {
- /* cert is already present, just add additional authority flags */
- old_cert->authority_flags |= cert->authority_flags;
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" authcert is already present and identical")
- )
- unlock_authcert_list("add_authcert");
-
- free_x509cert(cert);
- return old_cert;
- }
- else
+ if (old_cert != NULL)
{
- /* cert is already present but will be replaced by new cert */
- free_first_authcert();
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" existing authcert deleted")
- )
+ if (same_x509cert(cert, old_cert))
+ {
+ /* cert is already present, just add additional authority flags */
+ old_cert->authority_flags |= cert->authority_flags;
+ DBG(DBG_CONTROL | DBG_PARSING ,
+ DBG_log(" authcert is already present and identical")
+ )
+ unlock_authcert_list("add_authcert");
+
+ free_x509cert(cert);
+ return old_cert;
+ }
+ else
+ {
+ /* cert is already present but will be replaced by new cert */
+ free_first_authcert();
+ DBG(DBG_CONTROL | DBG_PARSING ,
+ DBG_log(" existing authcert deleted")
+ )
+ }
}
- }
-
- /* add new authcert to chained list */
- cert->next = x509authcerts;
- x509authcerts = cert;
- share_x509cert(cert); /* set count to one */
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" authcert inserted")
- )
- unlock_authcert_list("add_authcert");
- return cert;
+
+ /* add new authcert to chained list */
+ cert->next = x509authcerts;
+ x509authcerts = cert;
+ share_x509cert(cert); /* set count to one */
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" authcert inserted")
+ )
+ unlock_authcert_list("add_authcert");
+ return cert;
}
/*
@@ -262,41 +259,41 @@ add_authcert(x509cert_t *cert, u_char auth_flags)
void
load_authcerts(const char *type, const char *path, u_char auth_flags)
{
- struct dirent **filelist;
- u_char buf[BUF_LEN];
- u_char *save_dir;
- int n;
-
- /* change directory to specified path */
- save_dir = getcwd(buf, BUF_LEN);
-
- if (chdir(path))
- {
- plog("Could not change to directory '%s'", path);
- }
- else
- {
- plog("Changing to directory '%s'", path);
- n = scandir(path, &filelist, file_select, alphasort);
-
- if (n < 0)
- plog(" scandir() error");
- else
- {
- while (n--)
- {
- cert_t cert;
+ struct dirent **filelist;
+ u_char buf[BUF_LEN];
+ u_char *save_dir;
+ int n;
- if (load_cert(filelist[n]->d_name, type, &cert))
- add_authcert(cert.u.x509, auth_flags);
+ /* change directory to specified path */
+ save_dir = getcwd(buf, BUF_LEN);
- free(filelist[n]);
- }
- free(filelist);
+ if (chdir(path))
+ {
+ plog("Could not change to directory '%s'", path);
}
- }
- /* restore directory path */
- ignore_result(chdir(save_dir));
+ else
+ {
+ plog("Changing to directory '%s'", path);
+ n = scandir(path, &filelist, file_select, alphasort);
+
+ if (n < 0)
+ plog(" scandir() error");
+ else
+ {
+ while (n--)
+ {
+ cert_t cert;
+
+ if (load_cert(filelist[n]->d_name, type, &cert))
+ add_authcert(cert.u.x509, auth_flags);
+
+ free(filelist[n]);
+ }
+ free(filelist);
+ }
+ }
+ /* restore directory path */
+ ignore_result(chdir(save_dir));
}
/*
@@ -305,9 +302,9 @@ load_authcerts(const char *type, const char *path, u_char auth_flags)
void
list_authcerts(const char *caption, u_char auth_flags, bool utc)
{
- lock_authcert_list("list_authcerts");
- list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
- unlock_authcert_list("list_authcerts");
+ lock_authcert_list("list_authcerts");
+ list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
+ unlock_authcert_list("list_authcerts");
}
/*
@@ -315,19 +312,19 @@ list_authcerts(const char *caption, u_char auth_flags, bool utc)
*/
static const x509cert_t*
get_alt_cacert(chunk_t subject, chunk_t serial, chunk_t keyid
- , const x509cert_t *cert)
+ , const x509cert_t *cert)
{
- while (cert != NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
- : (same_dn(subject, cert->subject)
- && same_serial(serial, cert->serialNumber)))
+ while (cert != NULL)
{
- return cert;
+ if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->subjectKeyID)
+ : (same_dn(subject, cert->subject)
+ && same_serial(serial, cert->serialNumber)))
+ {
+ return cert;
+ }
+ cert = cert->next;
}
- cert = cert->next;
- }
- return NULL;
+ return NULL;
}
/* establish trust into a candidate authcert by going up the trust chain.
@@ -336,85 +333,85 @@ get_alt_cacert(chunk_t subject, chunk_t serial, chunk_t keyid
bool
trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
{
- int pathlen;
-
- lock_authcert_list("trust_authcert_candidate");
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- const x509cert_t *authcert = NULL;
- u_char buf[BUF_LEN];
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
+ int pathlen;
- /* search in alternative chain first */
- authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, alt_chain);
+ lock_authcert_list("trust_authcert_candidate");
- if (authcert != NULL)
+ for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
{
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found in alternative chain")
- )
- }
- else
- {
- /* search in trusted chain */
- authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
+ const x509cert_t *authcert = NULL;
+ u_char buf[BUF_LEN];
- if (authcert != NULL)
- {
DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
+ dntoa(buf, BUF_LEN, cert->subject);
+ DBG_log("subject: '%s'",buf);
+ dntoa(buf, BUF_LEN, cert->issuer);
+ DBG_log("issuer: '%s'",buf);
+ if (cert->authKeyID.ptr != NULL)
+ {
+ datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
)
- }
- else
- {
- plog("issuer cacert not found");
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
- }
- }
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, authcert))
- {
- plog("certificate signature is invalid");
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
- )
+ /* search in alternative chain first */
+ authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID, alt_chain);
+
+ if (authcert != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("issuer cacert found in alternative chain")
+ )
+ }
+ else
+ {
+ /* search in trusted chain */
+ authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID, AUTH_CA);
+
+ if (authcert != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("issuer cacert found")
+ )
+ }
+ else
+ {
+ plog("issuer cacert not found");
+ unlock_authcert_list("trust_authcert_candidate");
+ return FALSE;
+ }
+ }
+
+ if (!x509_check_signature(cert->tbsCertificate, cert->signature,
+ cert->algorithm, authcert))
+ {
+ plog("certificate signature is invalid");
+ unlock_authcert_list("trust_authcert_candidate");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("certificate signature is valid")
+ )
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
- {
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- unlock_authcert_list("trust_authcert_candidate");
- return TRUE;
+ /* check if cert is a self-signed root ca */
+ if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("reached self-signed root ca")
+ )
+ unlock_authcert_list("trust_authcert_candidate");
+ return TRUE;
+ }
+
+ /* go up one step in the trust chain */
+ cert = authcert;
}
-
- /* go up one step in the trust chain */
- cert = authcert;
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- unlock_authcert_list("trust_authcert_candidate");
- return FALSE;
+ plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
+ unlock_authcert_list("trust_authcert_candidate");
+ return FALSE;
}
/*
@@ -423,19 +420,19 @@ trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
ca_info_t*
get_ca_info(chunk_t authname, chunk_t serial, chunk_t keyid)
{
- ca_info_t *ca= ca_infos;
+ ca_info_t *ca= ca_infos;
- while (ca!= NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID)
- : (same_dn(authname, ca->authName)
- && same_serial(serial, ca->authKeySerialNumber)))
+ while (ca!= NULL)
{
- return ca;
+ if ((keyid.ptr != NULL) ? same_keyid(keyid, ca->authKeyID)
+ : (same_dn(authname, ca->authName)
+ && same_serial(serial, ca->authKeySerialNumber)))
+ {
+ return ca;
+ }
+ ca = ca->next;
}
- ca = ca->next;
- }
- return NULL;
+ return NULL;
}
@@ -445,21 +442,18 @@ get_ca_info(chunk_t authname, chunk_t serial, chunk_t keyid)
static void
free_ca_info(ca_info_t* ca_info)
{
- if (ca_info == NULL)
- return;
-
- pfreeany(ca_info->name);
- pfreeany(ca_info->ldaphost);
- pfreeany(ca_info->ldapbase);
- pfreeany(ca_info->ocspuri);
-
- freeanychunk(ca_info->authName);
- freeanychunk(ca_info->authKeyID);
- freeanychunk(ca_info->authKeySerialNumber);
-
- free_generalNames(ca_info->crluri, TRUE);
-
- pfree(ca_info);
+ if (ca_info == NULL)
+ return;
+
+ free(ca_info->name);
+ free(ca_info->ldaphost);
+ free(ca_info->ldapbase);
+ free(ca_info->ocspuri);
+ free(ca_info->authName.ptr);
+ free(ca_info->authKeyID.ptr);
+ free(ca_info->authKeySerialNumber.ptr);
+ free_generalNames(ca_info->crluri, TRUE);
+ free(ca_info);
}
/*
@@ -468,13 +462,13 @@ free_ca_info(ca_info_t* ca_info)
void
free_ca_infos(void)
{
- while (ca_infos != NULL)
- {
- ca_info_t *ca = ca_infos;
+ while (ca_infos != NULL)
+ {
+ ca_info_t *ca = ca_infos;
- ca_infos = ca_infos->next;
- free_ca_info(ca);
- }
+ ca_infos = ca_infos->next;
+ free_ca_info(ca);
+ }
}
/*
@@ -483,28 +477,28 @@ free_ca_infos(void)
bool
find_ca_info_by_name(const char *name, bool delete)
{
- ca_info_t **ca_p = &ca_infos;
- ca_info_t *ca = *ca_p;
+ ca_info_t **ca_p = &ca_infos;
+ ca_info_t *ca = *ca_p;
- while (ca != NULL)
- {
- /* is there already an entry? */
- if (streq(name, ca->name))
+ while (ca != NULL)
{
- if (delete)
- {
- lock_ca_info_list("find_ca_info_by_name");
- *ca_p = ca->next;
- free_ca_info(ca);
- plog("deleting ca description \"%s\"", name);
- unlock_ca_info_list("find_ca_info_by_name");
- }
- return TRUE;
+ /* is there already an entry? */
+ if (streq(name, ca->name))
+ {
+ if (delete)
+ {
+ lock_ca_info_list("find_ca_info_by_name");
+ *ca_p = ca->next;
+ free_ca_info(ca);
+ plog("deleting ca description \"%s\"", name);
+ unlock_ca_info_list("find_ca_info_by_name");
+ }
+ return TRUE;
+ }
+ ca_p = &ca->next;
+ ca = *ca_p;
}
- ca_p = &ca->next;
- ca = *ca_p;
- }
- return FALSE;
+ return FALSE;
}
@@ -514,136 +508,133 @@ find_ca_info_by_name(const char *name, bool delete)
void
add_ca_info(const whack_message_t *msg)
{
- smartcard_t *sc = NULL;
- cert_t cert;
- bool valid_cert = FALSE;
- bool cached_cert = FALSE;
-
- if (find_ca_info_by_name(msg->name, FALSE))
- {
- loglog(RC_DUPNAME, "attempt to redefine ca record \"%s\"", msg->name);
- return;
- }
-
- if (scx_on_smartcard(msg->cacert))
- {
- /* load CA cert from smartcard */
- valid_cert = scx_load_cert(msg->cacert, &sc, &cert, &cached_cert);
- }
- else
- {
- /* load CA cert from file */
- valid_cert = load_ca_cert(msg->cacert, &cert);
- }
-
- if (valid_cert)
- {
- char buf[BUF_LEN];
- x509cert_t *cacert = cert.u.x509;
- ca_info_t *ca = NULL;
-
- /* does the authname already exist? */
- ca = get_ca_info(cacert->subject, cacert->serialNumber
- , cacert->subjectKeyID);
-
- if (ca != NULL)
- {
- /* ca_info is already present */
- loglog(RC_DUPNAME, " duplicate ca information in record \"%s\" found,"
- "ignoring \"%s\"", ca->name, msg->name);
- free_x509cert(cacert);
- return;
- }
+ smartcard_t *sc = NULL;
+ cert_t cert;
+ bool valid_cert = FALSE;
+ bool cached_cert = FALSE;
- plog("added ca description \"%s\"", msg->name);
-
- /* create and initialize new ca_info record */
- ca = alloc_thing(ca_info_t, "ca info");
- *ca = empty_ca_info;
-
- /* name */
- ca->name = clone_str(msg->name, "ca name");
-
- /* authName */
- clonetochunk(ca->authName, cacert->subject.ptr
- , cacert->subject.len, "authName");
- dntoa(buf, BUF_LEN, ca->authName);
- DBG(DBG_CONTROL,
- DBG_log("authname: '%s'", buf)
- )
-
- /* authSerialNumber */
- clonetochunk(ca->authKeySerialNumber, cacert->serialNumber.ptr
- , cacert->serialNumber.len, "authKeySerialNumber");
-
- /* authKeyID */
- if (cacert->subjectKeyID.ptr != NULL)
+ if (find_ca_info_by_name(msg->name, FALSE))
{
- clonetochunk(ca->authKeyID, cacert->subjectKeyID.ptr
- , cacert->subjectKeyID.len, "authKeyID");
- datatot(cacert->subjectKeyID.ptr, cacert->subjectKeyID.len, ':'
- , buf, BUF_LEN);
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log("authkey: %s", buf)
- )
+ loglog(RC_DUPNAME, "attempt to redefine ca record \"%s\"", msg->name);
+ return;
}
- /* ldaphost */
- ca->ldaphost = clone_str(msg->ldaphost, "ldaphost");
-
- /* ldapbase */
- ca->ldapbase = clone_str(msg->ldapbase, "ldapbase");
-
- /* ocspuri */
- if (msg->ocspuri != NULL)
+ if (scx_on_smartcard(msg->cacert))
{
- if (strncasecmp(msg->ocspuri, "http", 4) == 0)
- ca->ocspuri = clone_str(msg->ocspuri, "ocspuri");
- else
- plog(" ignoring ocspuri with unkown protocol");
+ /* load CA cert from smartcard */
+ valid_cert = scx_load_cert(msg->cacert, &sc, &cert, &cached_cert);
}
-
- /* crluri2*/
- if (msg->crluri2 != NULL)
+ else
{
- generalName_t gn =
- { NULL, GN_URI, {msg->crluri2, strlen(msg->crluri2)} };
-
- add_distribution_points(&gn, &ca->crluri);
+ /* load CA cert from file */
+ valid_cert = load_ca_cert(msg->cacert, &cert);
}
- /* crluri */
- if (msg->crluri != NULL)
+ if (valid_cert)
{
- generalName_t gn =
- { NULL, GN_URI, {msg->crluri, strlen(msg->crluri)} };
-
- add_distribution_points(&gn, &ca->crluri);
- }
-
- /* strictrlpolicy */
- ca->strictcrlpolicy = msg->whack_strict;
-
- /* insert ca_info record into the chained list */
- lock_ca_info_list("add_ca_info");
-
- ca->next = ca_infos;
- ca_infos = ca;
- ca->installed = time(NULL);
-
- unlock_ca_info_list("add_ca_info");
+ char buf[BUF_LEN];
+ x509cert_t *cacert = cert.u.x509;
+ ca_info_t *ca = NULL;
+
+ /* does the authname already exist? */
+ ca = get_ca_info(cacert->subject, cacert->serialNumber
+ , cacert->subjectKeyID);
+
+ if (ca != NULL)
+ {
+ /* ca_info is already present */
+ loglog(RC_DUPNAME, " duplicate ca information in record \"%s\" found,"
+ "ignoring \"%s\"", ca->name, msg->name);
+ free_x509cert(cacert);
+ return;
+ }
+
+ plog("added ca description \"%s\"", msg->name);
+
+ /* create and initialize new ca_info record */
+ ca = malloc_thing(ca_info_t);
+ *ca = empty_ca_info;
+
+ /* name */
+ ca->name = clone_str(msg->name);
+
+ /* authName */
+ ca->authName = chunk_clone(cacert->subject);
+ dntoa(buf, BUF_LEN, ca->authName);
+ DBG(DBG_CONTROL,
+ DBG_log("authname: '%s'", buf)
+ )
- /* add cacert to list of authcerts */
- if (!cached_cert && sc != NULL)
- {
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
- sc->last_cert.u.x509->count--;
- sc->last_cert.u.x509 = add_authcert(cacert, AUTH_CA);
- share_cert(sc->last_cert);
+ /* authSerialNumber */
+ ca->authKeySerialNumber = chunk_clone(cacert->serialNumber);
+
+ /* authKeyID */
+ if (cacert->subjectKeyID.ptr != NULL)
+ {
+ ca->authKeyID = chunk_clone(cacert->subjectKeyID);
+ datatot(cacert->subjectKeyID.ptr, cacert->subjectKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG(DBG_CONTROL | DBG_PARSING ,
+ DBG_log("authkey: %s", buf)
+ )
+ }
+
+ /* ldaphost */
+ ca->ldaphost = clone_str(msg->ldaphost);
+
+ /* ldapbase */
+ ca->ldapbase = clone_str(msg->ldapbase);
+
+ /* ocspuri */
+ if (msg->ocspuri != NULL)
+ {
+ if (strncasecmp(msg->ocspuri, "http", 4) == 0)
+ ca->ocspuri = clone_str(msg->ocspuri);
+ else
+ plog(" ignoring ocspuri with unkown protocol");
+ }
+
+ /* crluri2*/
+ if (msg->crluri2 != NULL)
+ {
+ generalName_t gn =
+ { NULL, GN_URI, {msg->crluri2, strlen(msg->crluri2)} };
+
+ add_distribution_points(&gn, &ca->crluri);
+ }
+
+ /* crluri */
+ if (msg->crluri != NULL)
+ {
+ generalName_t gn =
+ { NULL, GN_URI, {msg->crluri, strlen(msg->crluri)} };
+
+ add_distribution_points(&gn, &ca->crluri);
+ }
+
+ /* strictrlpolicy */
+ ca->strictcrlpolicy = msg->whack_strict;
+
+ /* insert ca_info record into the chained list */
+ lock_ca_info_list("add_ca_info");
+
+ ca->next = ca_infos;
+ ca_infos = ca;
+ ca->installed = time(NULL);
+
+ unlock_ca_info_list("add_ca_info");
+
+ /* add cacert to list of authcerts */
+ if (!cached_cert && sc != NULL)
+ {
+ if (sc->last_cert.type == CERT_X509_SIGNATURE)
+ sc->last_cert.u.x509->count--;
+ sc->last_cert.u.x509 = add_authcert(cacert, AUTH_CA);
+ share_cert(sc->last_cert);
+ }
+ if (sc != NULL)
+ time(&sc->last_load);
}
- if (sc != NULL)
- time(&sc->last_load);
- }
}
/*
@@ -652,51 +643,51 @@ add_ca_info(const whack_message_t *msg)
void
list_ca_infos(bool utc)
{
- ca_info_t *ca = ca_infos;
-
- if (ca != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 CA Information Records:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (ca != NULL)
- {
- u_char buf[BUF_LEN];
-
- /* strictpolicy per CA not supported yet
- *
- whack_log(RC_COMMENT, "%s, \"%s\", strictcrlpolicy: %s"
- , timetoa(&ca->installed, utc), ca->name
- , ca->strictcrlpolicy? "yes":"no");
- */
- whack_log(RC_COMMENT, "%s, \"%s\"", timetoa(&ca->installed, utc), ca->name);
- dntoa(buf, BUF_LEN, ca->authName);
- whack_log(RC_COMMENT, " authname: '%s'", buf);
- if (ca->ldaphost != NULL)
- whack_log(RC_COMMENT, " ldaphost: '%s'", ca->ldaphost);
- if (ca->ldapbase != NULL)
- whack_log(RC_COMMENT, " ldapbase: '%s'", ca->ldapbase);
- if (ca->ocspuri != NULL)
- whack_log(RC_COMMENT, " ocspuri: '%s'", ca->ocspuri);
-
- list_distribution_points(ca->crluri);
-
- if (ca->authKeyID.ptr != NULL)
+ ca_info_t *ca = ca_infos;
+
+ if (ca != NULL)
{
- datatot(ca->authKeyID.ptr, ca->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of X.509 CA Information Records:");
+ whack_log(RC_COMMENT, " ");
}
- if (ca->authKeySerialNumber.ptr != NULL)
+
+ while (ca != NULL)
{
- datatot(ca->authKeySerialNumber.ptr, ca->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
+ u_char buf[BUF_LEN];
+
+ /* strictpolicy per CA not supported yet
+ *
+ whack_log(RC_COMMENT, "%T, \"%s\", strictcrlpolicy: %s"
+ , &ca->installed, utc, ca->name
+ , ca->strictcrlpolicy? "yes":"no");
+ */
+ whack_log(RC_COMMENT, "%T, \"%s\"", &ca->installed, utc, ca->name);
+ dntoa(buf, BUF_LEN, ca->authName);
+ whack_log(RC_COMMENT, " authname: '%s'", buf);
+ if (ca->ldaphost != NULL)
+ whack_log(RC_COMMENT, " ldaphost: '%s'", ca->ldaphost);
+ if (ca->ldapbase != NULL)
+ whack_log(RC_COMMENT, " ldapbase: '%s'", ca->ldapbase);
+ if (ca->ocspuri != NULL)
+ whack_log(RC_COMMENT, " ocspuri: '%s'", ca->ocspuri);
+
+ list_distribution_points(ca->crluri);
+
+ if (ca->authKeyID.ptr != NULL)
+ {
+ datatot(ca->authKeyID.ptr, ca->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (ca->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(ca->authKeySerialNumber.ptr, ca->authKeySerialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
+ ca = ca->next;
}
- ca = ca->next;
- }
}
diff --git a/src/pluto/ca.h b/src/pluto/ca.h
index 13f874284..44d079b4c 100644
--- a/src/pluto/ca.h
+++ b/src/pluto/ca.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ca.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _CA_H
@@ -20,45 +18,45 @@
#include "x509.h"
#include "whack.h"
-#define MAX_CA_PATH_LEN 7
+#define MAX_CA_PATH_LEN 7
/* authority flags */
-#define AUTH_NONE 0x00 /* no authorities */
-#define AUTH_CA 0x01 /* certification authority */
-#define AUTH_AA 0x02 /* authorization authority */
-#define AUTH_OCSP 0x04 /* ocsp signing authority */
+#define AUTH_NONE 0x00 /* no authorities */
+#define AUTH_CA 0x01 /* certification authority */
+#define AUTH_AA 0x02 /* authorization authority */
+#define AUTH_OCSP 0x04 /* ocsp signing authority */
/* CA info structures */
typedef struct ca_info ca_info_t;
struct ca_info {
- ca_info_t *next;
- char *name;
- time_t installed;
- chunk_t authName;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- char *ldaphost;
- char *ldapbase;
- char *ocspuri;
- generalName_t *crluri;
- bool strictcrlpolicy;
+ ca_info_t *next;
+ char *name;
+ time_t installed;
+ chunk_t authName;
+ chunk_t authKeyID;
+ chunk_t authKeySerialNumber;
+ char *ldaphost;
+ char *ldapbase;
+ char *ocspuri;
+ generalName_t *crluri;
+ bool strictcrlpolicy;
};
extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
extern bool match_requested_ca(generalName_t *requested_ca
- , chunk_t our_ca, int *our_pathlen);
+ , chunk_t our_ca, int *our_pathlen);
extern x509cert_t* get_authcert(chunk_t subject, chunk_t serial, chunk_t keyid
- , u_char auth_flags);
+ , u_char auth_flags);
extern void load_authcerts(const char *type, const char *path
- , u_char auth_flags);
+ , u_char auth_flags);
extern x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags);
extern void free_authcerts(void);
extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
extern bool trust_authcert_candidate(const x509cert_t *cert
- , const x509cert_t *alt_chain);
+ , const x509cert_t *alt_chain);
extern ca_info_t* get_ca_info(chunk_t name, chunk_t serial, chunk_t keyid);
extern bool find_ca_info_by_name(const char *name, bool delete);
extern void add_ca_info(const whack_message_t *msg);
diff --git a/src/pluto/certs.c b/src/pluto/certs.c
index 43976a913..ca3019b9b 100644
--- a/src/pluto/certs.c
+++ b/src/pluto/certs.c
@@ -1,5 +1,7 @@
/* Certificate support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2002-2009 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
@@ -10,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: certs.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdlib.h>
@@ -19,241 +19,251 @@
#include <string.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include "library.h"
+#include "asn1/asn1.h"
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "asn1.h"
#include "id.h"
-#include "x509.h"
-#include "pgp.h"
#include "pem.h"
#include "certs.h"
-#include "pkcs1.h"
-/*
+/**
* used for initializatin of certs
*/
-const cert_t empty_cert = {CERT_NONE, {NULL}};
+const cert_t cert_empty = {CERT_NONE, {NULL}};
-/*
+/**
* extracts the certificate to be sent to the peer
*/
-chunk_t
-get_mycert(cert_t cert)
+chunk_t cert_get_encoding(cert_t cert)
{
- switch (cert.type)
- {
- case CERT_PGP:
- return cert.u.pgp->certificate;
- case CERT_X509_SIGNATURE:
- return cert.u.x509->certificate;
- default:
- return empty_chunk;
- }
+ switch (cert.type)
+ {
+ case CERT_PGP:
+ return cert.u.pgp->certificate;
+ case CERT_X509_SIGNATURE:
+ return cert.u.x509->certificate;
+ default:
+ return chunk_empty;
+ }
+}
+
+public_key_t* cert_get_public_key(const cert_t cert)
+{
+ switch (cert.type)
+ {
+ case CERT_PGP:
+ return cert.u.pgp->public_key;
+ break;
+ case CERT_X509_SIGNATURE:
+ return cert.u.x509->public_key;
+ break;
+ default:
+ return NULL;
+ }
}
/* load a coded key or certificate file with autodetection
* of binary DER or base64 PEM ASN.1 formats and armored PGP format
*/
-bool
-load_coded_file(const char *filename, prompt_pass_t *pass, const char *type
-, chunk_t *blob, bool *pgp)
+bool load_coded_file(char *filename, prompt_pass_t *pass, const char *type,
+ chunk_t *blob, bool *pgp)
{
- err_t ugh = NULL;
+ err_t ugh = NULL;
+
+ FILE *fd = fopen(filename, "r");
- FILE *fd = fopen(filename, "r");
+ if (fd)
+ {
+ int bytes;
+ fseek(fd, 0, SEEK_END );
+ blob->len = ftell(fd);
+ rewind(fd);
+ blob->ptr = malloc(blob->len);
+ bytes = fread(blob->ptr, 1, blob->len, fd);
+ fclose(fd);
+ plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
- if (fd)
- {
- int bytes;
- fseek(fd, 0, SEEK_END );
- blob->len = ftell(fd);
- rewind(fd);
- blob->ptr = alloc_bytes(blob->len, type);
- bytes = fread(blob->ptr, 1, blob->len, fd);
- fclose(fd);
- plog(" loaded %s file '%s' (%d bytes)", type, filename, bytes);
+ *pgp = FALSE;
- *pgp = FALSE;
+ /* try DER format */
+ if (is_asn1(*blob))
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" file coded in DER format");
+ )
+ return TRUE;
+ }
- /* try DER format */
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in DER format");
- )
- return TRUE;
- }
+ /* try PEM format */
+ ugh = pemtobin(blob, pass, filename, pgp);
- /* try PEM format */
- ugh = pemtobin(blob, pass, filename, pgp);
+ if (ugh == NULL)
+ {
+ if (*pgp)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" file coded in armored PGP format");
+ )
+ return TRUE;
+ }
+ if (is_asn1(*blob))
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" file coded in PEM format");
+ )
+ return TRUE;
+ }
+ ugh = "file coded in unknown format, discarded";
+ }
- if (ugh == NULL)
+ /* a conversion error has occured */
+ plog(" %s", ugh);
+ free(blob->ptr);
+ *blob = chunk_empty;
+ }
+ else
{
- if (*pgp)
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in armored PGP format");
- )
- return TRUE;
- }
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" file coded in PEM format");
- )
- return TRUE;
- }
- ugh = "file coded in unknown format, discarded";
+ plog(" could not open %s file '%s'", type, filename);
}
-
- /* a conversion error has occured */
- plog(" %s", ugh);
- pfree(blob->ptr);
- *blob = empty_chunk;
- }
- else
- {
- plog(" could not open %s file '%s'", type, filename);
- }
- return FALSE;
+ return FALSE;
}
-/*
- * Loads a PKCS#1 or PGP private RSA key file
+/**
+ * Loads a PKCS#1 or PGP privatekey file
*/
-err_t
-load_rsa_private_key(const char* filename, prompt_pass_t *pass
-, RSA_private_key_t *key)
+private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
+ key_type_t type)
{
- err_t ugh = NULL;
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
+ private_key_t *key = NULL;
+ chunk_t blob = chunk_empty;
+ bool pgp = FALSE;
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
+ char *path = concatenate_paths(PRIVATE_KEY_PATH, filename);
- if (load_coded_file(path, pass, "private key", &blob, &pgp))
- {
- if (pgp)
+ if (load_coded_file(path, pass, "private key", &blob, &pgp))
{
- if (!parse_pgp(blob, NULL, key))
- ugh = "syntax error in PGP private key file";
+ if (pgp)
+ {
+ parse_pgp(blob, NULL, &key);
+ }
+ else
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, type,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+ }
+ if (key == NULL)
+ {
+ plog(" syntax error in %s private key file", pgp ? "PGP":"PKCS#");
+ }
+ free(blob.ptr);
}
else
{
- if (!pkcs1_parse_private_key(blob, key))
- ugh = "syntax error in PKCS#1 private key file";
+ plog(" error loading private key file");
}
- pfree(blob.ptr);
- }
- else
- ugh = "error loading RSA private key file";
-
- return ugh;
+ return key;
}
-/*
+
+/**
* Loads a X.509 or OpenPGP certificate
*/
-bool
-load_cert(const char *filename, const char *label, cert_t *cert)
+bool load_cert(char *filename, const char *label, cert_t *cert)
{
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
+ bool pgp = FALSE;
+ chunk_t blob = chunk_empty;
- /* initialize cert struct */
- cert->type = CERT_NONE;
- cert->u.x509 = NULL;
+ /* initialize cert struct */
+ cert->type = CERT_NONE;
+ cert->u.x509 = NULL;
- if (load_coded_file(filename, NULL, label, &blob, &pgp))
- {
- if (pgp)
- {
- pgpcert_t *pgpcert = alloc_thing(pgpcert_t, "pgpcert");
- *pgpcert = empty_pgpcert;
- if (parse_pgp(blob, pgpcert, NULL))
- {
- cert->type = CERT_PGP;
- cert->u.pgp = pgpcert;
- return TRUE;
- }
- else
- {
- plog(" error in OpenPGP certificate");
- free_pgpcert(pgpcert);
- return FALSE;
- }
- }
- else
+ if (load_coded_file(filename, NULL, label, &blob, &pgp))
{
- x509cert_t *x509cert = alloc_thing(x509cert_t, "x509cert");
- *x509cert = empty_x509cert;
- if (parse_x509cert(blob, 0, x509cert))
- {
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return TRUE;
- }
- else
- {
- plog(" error in X.509 certificate");
- free_x509cert(x509cert);
- return FALSE;
- }
+ if (pgp)
+ {
+ pgpcert_t *pgpcert = malloc_thing(pgpcert_t);
+ *pgpcert = pgpcert_empty;
+ if (parse_pgp(blob, pgpcert, NULL))
+ {
+ cert->type = CERT_PGP;
+ cert->u.pgp = pgpcert;
+ return TRUE;
+ }
+ else
+ {
+ plog(" error in OpenPGP certificate");
+ free_pgpcert(pgpcert);
+ return FALSE;
+ }
+ }
+ else
+ {
+ x509cert_t *x509cert = malloc_thing(x509cert_t);
+ *x509cert = empty_x509cert;
+ if (parse_x509cert(blob, 0, x509cert))
+ {
+ cert->type = CERT_X509_SIGNATURE;
+ cert->u.x509 = x509cert;
+ return TRUE;
+ }
+ else
+ {
+ plog(" error in X.509 certificate");
+ free_x509cert(x509cert);
+ return FALSE;
+ }
+ }
}
- }
- return FALSE;
+ return FALSE;
}
-/*
+/**
* Loads a host certificate
*/
-bool
-load_host_cert(const char *filename, cert_t *cert)
+bool load_host_cert(char *filename, cert_t *cert)
{
- const char *path = concatenate_paths(HOST_CERT_PATH, filename);
+ char *path = concatenate_paths(HOST_CERT_PATH, filename);
- return load_cert(path, "host cert", cert);
+ return load_cert(path, "host cert", cert);
}
-/*
+/**
* Loads a CA certificate
*/
-bool
-load_ca_cert(const char *filename, cert_t *cert)
+bool load_ca_cert(char *filename, cert_t *cert)
{
- const char *path = concatenate_paths(CA_CERT_PATH, filename);
+ char *path = concatenate_paths(CA_CERT_PATH, filename);
- return load_cert(path, "CA cert", cert);
+ return load_cert(path, "CA cert", cert);
}
-/*
+/**
* establish equality of two certificates
*/
-bool
-same_cert(const cert_t *a, const cert_t *b)
+bool same_cert(const cert_t *a, const cert_t *b)
{
- return a->type == b->type && a->u.x509 == b->u.x509;
+ return a->type == b->type && a->u.x509 == b->u.x509;
}
-/* for each link pointing to the certif icate
- " increase the count by one
+/**
+ * for each link pointing to the certificate increase the count by one
*/
-void
-share_cert(cert_t cert)
+void share_cert(cert_t cert)
{
- switch (cert.type)
- {
- case CERT_PGP:
- share_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- share_x509cert(cert.u.x509);
- break;
- default:
- break;
- }
+ switch (cert.type)
+ {
+ case CERT_PGP:
+ share_pgpcert(cert.u.pgp);
+ break;
+ case CERT_X509_SIGNATURE:
+ share_x509cert(cert.u.x509);
+ break;
+ default:
+ break;
+ }
}
/* release of a certificate decreases the count by one
@@ -263,16 +273,16 @@ void
release_cert(cert_t cert)
{
switch (cert.type)
- {
- case CERT_PGP:
- release_pgpcert(cert.u.pgp);
- break;
- case CERT_X509_SIGNATURE:
- release_x509cert(cert.u.x509);
- break;
- default:
- break;
- }
+ {
+ case CERT_PGP:
+ release_pgpcert(cert.u.pgp);
+ break;
+ case CERT_X509_SIGNATURE:
+ release_x509cert(cert.u.x509);
+ break;
+ default:
+ break;
+ }
}
/*
@@ -281,7 +291,7 @@ release_cert(cert_t cert)
void
list_certs(bool utc)
{
- list_x509_end_certs(utc);
- list_pgp_end_certs(utc);
+ list_x509_end_certs(utc);
+ list_pgp_end_certs(utc);
}
diff --git a/src/pluto/certs.h b/src/pluto/certs.h
index b71c53e15..0810c52fa 100644
--- a/src/pluto/certs.h
+++ b/src/pluto/certs.h
@@ -1,5 +1,7 @@
/* Certificate support for IKE authentication
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2002-2009 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
@@ -10,66 +12,65 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: certs.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _CERTS_H
#define _CERTS_H
-#include "pkcs1.h"
+#include <credentials/keys/private_key.h>
+
#include "x509.h"
-#include "pgp.h"
+#include "pgpcert.h"
/* path definitions for private keys, end certs,
* cacerts, attribute certs and crls
*/
#define PRIVATE_KEY_PATH IPSEC_CONFDIR "/ipsec.d/private"
#define HOST_CERT_PATH IPSEC_CONFDIR "/ipsec.d/certs"
-#define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts"
-#define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts"
-#define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts"
-#define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts"
-#define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls"
-#define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs"
+#define CA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/cacerts"
+#define A_CERT_PATH IPSEC_CONFDIR "/ipsec.d/acerts"
+#define AA_CERT_PATH IPSEC_CONFDIR "/ipsec.d/aacerts"
+#define OCSP_CERT_PATH IPSEC_CONFDIR "/ipsec.d/ocspcerts"
+#define CRL_PATH IPSEC_CONFDIR "/ipsec.d/crls"
+#define REQ_PATH IPSEC_CONFDIR "/ipsec.d/reqs"
/* advance warning of imminent expiry of
* cacerts, public keys, and crls
*/
-#define CA_CERT_WARNING_INTERVAL 30 /* days */
-#define OCSP_CERT_WARNING_INTERVAL 30 /* days */
-#define PUBKEY_WARNING_INTERVAL 7 /* days */
-#define CRL_WARNING_INTERVAL 7 /* days */
-#define ACERT_WARNING_INTERVAL 1 /* day */
+#define CA_CERT_WARNING_INTERVAL 30 /* days */
+#define OCSP_CERT_WARNING_INTERVAL 30 /* days */
+#define PUBKEY_WARNING_INTERVAL 7 /* days */
+#define CRL_WARNING_INTERVAL 7 /* days */
+#define ACERT_WARNING_INTERVAL 1 /* day */
/* certificate access structure
* currently X.509 and OpenPGP certificates are supported
*/
typedef struct {
- u_char type;
- union {
- x509cert_t *x509;
- pgpcert_t *pgp;
- } u;
+ u_char type;
+ union {
+ x509cert_t *x509;
+ pgpcert_t *pgp;
+ } u;
} cert_t;
/* used for initialization */
-extern const cert_t empty_cert;
+extern const cert_t cert_empty;
/* do not send certificate requests
* flag set in plutomain.c and used in ipsec_doi.c
*/
extern bool no_cr_send;
-extern err_t load_rsa_private_key(const char* filename, prompt_pass_t *pass
- , RSA_private_key_t *key);
-extern chunk_t get_mycert(cert_t cert);
-extern bool load_coded_file(const char *filename, prompt_pass_t *pass
- , const char *type, chunk_t *blob, bool *pgp);
-extern bool load_cert(const char *filename, const char *label
- , cert_t *cert);
-extern bool load_host_cert(const char *filename, cert_t *cert);
-extern bool load_ca_cert(const char *filename, cert_t *cert);
+extern public_key_t* cert_get_public_key(const cert_t cert);
+extern chunk_t cert_get_encoding(cert_t cert);
+extern private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
+ key_type_t type);
+extern bool load_coded_file(char *filename, prompt_pass_t *pass,
+ const char *type, chunk_t *blob, bool *pgp);
+extern bool load_cert(char *filename, const char *label, cert_t *cert);
+extern bool load_host_cert(char *filename, cert_t *cert);
+extern bool load_ca_cert(char *filename, cert_t *cert);
extern bool same_cert(const cert_t *a, const cert_t *b);
extern void share_cert(cert_t cert);
extern void release_cert(cert_t cert);
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index cd118cb34..4deb722f7 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: connections.c 4924 2009-03-10 21:13:18Z andreas $
*/
#include <string.h>
@@ -25,20 +23,21 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "kameipsec.h"
+#include <credentials/keys/private_key.h>
+
#include "constants.h"
#include "defs.h"
#include "id.h"
#include "x509.h"
#include "ca.h"
#include "crl.h"
-#include "pgp.h"
+#include "pgpcert.h"
#include "certs.h"
#include "ac.h"
#include "smartcard.h"
@@ -48,13 +47,13 @@
#include "demux.h"
#include "state.h"
#include "timer.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "server.h"
#include "kernel.h"
#include "log.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "whack.h"
#include "alg_info.h"
#include "ike_alg.h"
@@ -62,7 +61,7 @@
#include "nat_traversal.h"
#include "virtual.h"
-static void flush_pending_by_connection(struct connection *c); /* forward */
+static void flush_pending_by_connection(struct connection *c); /* forward */
static struct connection *connections = NULL;
@@ -77,14 +76,14 @@ static struct connection *connections = NULL;
*/
struct host_pair {
- struct {
- ip_address addr;
- u_int16_t port; /* host order */
- } me, him;
- bool initial_connection_sent;
- struct connection *connections; /* connections with this pair */
- struct pending *pending; /* awaiting Keying Channel */
- struct host_pair *next;
+ struct {
+ ip_address addr;
+ u_int16_t port; /* host order */
+ } me, him;
+ bool initial_connection_sent;
+ struct connection *connections; /* connections with this pair */
+ struct pending *pending; /* awaiting Keying Channel */
+ struct host_pair *next;
};
static struct host_pair *host_pairs = NULL;
@@ -96,45 +95,45 @@ bool
same_peer_ids(const struct connection *c, const struct connection *d
, const struct id *his_id)
{
- return same_id(&c->spd.this.id, &d->spd.this.id)
- && same_id(his_id == NULL? &c->spd.that.id : his_id, &d->spd.that.id);
+ return same_id(&c->spd.this.id, &d->spd.this.id)
+ && same_id(his_id == NULL? &c->spd.that.id : his_id, &d->spd.that.id);
}
static struct host_pair *
find_host_pair(const ip_address *myaddr, u_int16_t myport
, const ip_address *hisaddr, u_int16_t hisport)
{
- struct host_pair *p, *prev;
-
- /* default hisaddr to an appropriate any */
- if (hisaddr == NULL)
- hisaddr = aftoinfo(addrtypeof(myaddr))->any;
-
- if (nat_traversal_enabled)
- {
- /**
- * port is not relevant in host_pair. with nat_traversal we
- * always use pluto_port (500)
- */
- myport = pluto_port;
- hisport = pluto_port;
- }
-
- for (prev = NULL, p = host_pairs; p != NULL; prev = p, p = p->next)
- {
- if (sameaddr(&p->me.addr, myaddr) && p->me.port == myport
- && sameaddr(&p->him.addr, hisaddr) && p->him.port == hisport)
+ struct host_pair *p, *prev;
+
+ /* default hisaddr to an appropriate any */
+ if (hisaddr == NULL)
+ hisaddr = aftoinfo(addrtypeof(myaddr))->any;
+
+ if (nat_traversal_enabled)
{
- if (prev != NULL)
- {
- prev->next = p->next; /* remove p from list */
- p->next = host_pairs; /* and stick it on front */
- host_pairs = p;
- }
- break;
+ /**
+ * port is not relevant in host_pair. with nat_traversal we
+ * always use pluto_port (500)
+ */
+ myport = pluto_port;
+ hisport = pluto_port;
}
- }
- return p;
+
+ for (prev = NULL, p = host_pairs; p != NULL; prev = p, p = p->next)
+ {
+ if (sameaddr(&p->me.addr, myaddr) && p->me.port == myport
+ && sameaddr(&p->him.addr, hisaddr) && p->him.port == hisport)
+ {
+ if (prev != NULL)
+ {
+ prev->next = p->next; /* remove p from list */
+ p->next = host_pairs; /* and stick it on front */
+ host_pairs = p;
+ }
+ break;
+ }
+ }
+ return p;
}
/* find head of list of connections with this pair of hosts */
@@ -142,63 +141,63 @@ static struct connection *
find_host_pair_connections(const ip_address *myaddr, u_int16_t myport
, const ip_address *hisaddr, u_int16_t hisport)
{
- struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport);
-
- if (nat_traversal_enabled && hp && hisaddr)
- {
- struct connection *c;
+ struct host_pair *hp = find_host_pair(myaddr, myport, hisaddr, hisport);
- for (c = hp->connections; c != NULL; c = c->hp_next)
+ if (nat_traversal_enabled && hp && hisaddr)
{
- if (c->spd.this.host_port == myport && c->spd.that.host_port == hisport)
- return c;
+ struct connection *c;
+
+ for (c = hp->connections; c != NULL; c = c->hp_next)
+ {
+ if (c->spd.this.host_port == myport && c->spd.that.host_port == hisport)
+ return c;
+ }
+ return NULL;
}
- return NULL;
- }
- return hp == NULL? NULL : hp->connections;
+ return hp == NULL? NULL : hp->connections;
}
static void
connect_to_host_pair(struct connection *c)
{
- if (oriented(*c))
- {
- struct host_pair *hp;
+ if (oriented(*c))
+ {
+ struct host_pair *hp;
- ip_address his_addr = (c->spd.that.allow_any)
- ? *aftoinfo(addrtypeof(&c->spd.that.host_addr))->any
- : c->spd.that.host_addr;
+ ip_address his_addr = (c->spd.that.allow_any)
+ ? *aftoinfo(addrtypeof(&c->spd.that.host_addr))->any
+ : c->spd.that.host_addr;
- hp = find_host_pair(&c->spd.this.host_addr, c->spd.this.host_port
- , &his_addr, c->spd.that.host_port);
+ hp = find_host_pair(&c->spd.this.host_addr, c->spd.this.host_port
+ , &his_addr, c->spd.that.host_port);
- if (hp == NULL)
+ if (hp == NULL)
+ {
+ /* no suitable host_pair -- build one */
+ hp = malloc_thing(struct host_pair);
+ hp->me.addr = c->spd.this.host_addr;
+ hp->him.addr = his_addr;
+ hp->me.port = nat_traversal_enabled ? pluto_port : c->spd.this.host_port;
+ hp->him.port = nat_traversal_enabled ? pluto_port : c->spd.that.host_port;
+ hp->initial_connection_sent = FALSE;
+ hp->connections = NULL;
+ hp->pending = NULL;
+ hp->next = host_pairs;
+ host_pairs = hp;
+ }
+ c->host_pair = hp;
+ c->hp_next = hp->connections;
+ hp->connections = c;
+ }
+ else
{
- /* no suitable host_pair -- build one */
- hp = alloc_thing(struct host_pair, "host_pair");
- hp->me.addr = c->spd.this.host_addr;
- hp->him.addr = his_addr;
- hp->me.port = nat_traversal_enabled ? pluto_port : c->spd.this.host_port;
- hp->him.port = nat_traversal_enabled ? pluto_port : c->spd.that.host_port;
- hp->initial_connection_sent = FALSE;
- hp->connections = NULL;
- hp->pending = NULL;
- hp->next = host_pairs;
- host_pairs = hp;
+ /* since this connection isn't oriented, we place it
+ * in the unoriented_connections list instead.
+ */
+ c->host_pair = NULL;
+ c->hp_next = unoriented_connections;
+ unoriented_connections = c;
}
- c->host_pair = hp;
- c->hp_next = hp->connections;
- hp->connections = c;
- }
- else
- {
- /* since this connection isn't oriented, we place it
- * in the unoriented_connections list instead.
- */
- c->host_pair = NULL;
- c->hp_next = unoriented_connections;
- unoriented_connections = c;
- }
}
/* find a connection by name.
@@ -209,317 +208,317 @@ connect_to_host_pair(struct connection *c)
struct connection *
con_by_name(const char *nm, bool strict)
{
- struct connection *p, *prev;
+ struct connection *p, *prev;
- for (prev = NULL, p = connections; ; prev = p, p = p->ac_next)
- {
- if (p == NULL)
+ for (prev = NULL, p = connections; ; prev = p, p = p->ac_next)
{
- if (strict)
- whack_log(RC_UNKNOWN_NAME
- , "no connection named \"%s\"", nm);
- break;
- }
- if (streq(p->name, nm)
- && (!strict || p->kind != CK_INSTANCE))
- {
- if (prev != NULL)
- {
- prev->ac_next = p->ac_next; /* remove p from list */
- p->ac_next = connections; /* and stick it on front */
- connections = p;
- }
- break;
+ if (p == NULL)
+ {
+ if (strict)
+ whack_log(RC_UNKNOWN_NAME
+ , "no connection named \"%s\"", nm);
+ break;
+ }
+ if (streq(p->name, nm)
+ && (!strict || p->kind != CK_INSTANCE))
+ {
+ if (prev != NULL)
+ {
+ prev->ac_next = p->ac_next; /* remove p from list */
+ p->ac_next = connections; /* and stick it on front */
+ connections = p;
+ }
+ break;
+ }
}
- }
- return p;
+ return p;
}
void
release_connection(struct connection *c, bool relations)
{
- if (c->kind == CK_INSTANCE)
- {
- /* This does everything we need.
- * Note that we will be called recursively by delete_connection,
- * but kind will be CK_GOING_AWAY.
- */
- delete_connection(c, relations);
- }
- else
- {
- flush_pending_by_connection(c);
- delete_states_by_connection(c, relations);
- unroute_connection(c);
- }
+ if (c->kind == CK_INSTANCE)
+ {
+ /* This does everything we need.
+ * Note that we will be called recursively by delete_connection,
+ * but kind will be CK_GOING_AWAY.
+ */
+ delete_connection(c, relations);
+ }
+ else
+ {
+ flush_pending_by_connection(c);
+ delete_states_by_connection(c, relations);
+ unroute_connection(c);
+ }
}
/* Delete a connection */
#define list_rm(etype, enext, e, ehead) { \
- etype **ep; \
- for (ep = &(ehead); *ep != (e); ep = &(*ep)->enext) \
- passert(*ep != NULL); /* we must not come up empty-handed */ \
- *ep = (e)->enext; \
- }
+ etype **ep; \
+ for (ep = &(ehead); *ep != (e); ep = &(*ep)->enext) \
+ passert(*ep != NULL); /* we must not come up empty-handed */ \
+ *ep = (e)->enext; \
+ }
void
delete_connection(struct connection *c, bool relations)
{
- struct connection *old_cur_connection
- = cur_connection == c? NULL : cur_connection;
+ struct connection *old_cur_connection
+ = cur_connection == c? NULL : cur_connection;
#ifdef DEBUG
- lset_t old_cur_debugging = cur_debugging;
+ lset_t old_cur_debugging = cur_debugging;
#endif
- set_cur_connection(c);
-
- /* Must be careful to avoid circularity:
- * we mark c as going away so it won't get deleted recursively.
- */
- passert(c->kind != CK_GOING_AWAY);
- if (c->kind == CK_INSTANCE)
- {
- plog("deleting connection \"%s\" instance with peer %s {isakmp=#%lu/ipsec=#%lu}"
- , c->name
- , ip_str(&c->spd.that.host_addr)
- , c->newest_isakmp_sa, c->newest_ipsec_sa);
- c->kind = CK_GOING_AWAY;
- }
- else
- {
- plog("deleting connection");
- }
- release_connection(c, relations); /* won't delete c */
-
- if (c->kind == CK_GROUP)
- delete_group(c);
-
- /* free up any logging resources */
- perpeer_logfree(c);
-
- /* find and delete c from connections list */
- list_rm(struct connection, ac_next, c, connections);
- cur_connection = old_cur_connection;
-
- /* find and delete c from the host pair list */
- if (c->host_pair == NULL)
- {
- if (c->ikev1)
- list_rm(struct connection, hp_next, c, unoriented_connections);
- }
- else
- {
- struct host_pair *hp = c->host_pair;
-
- list_rm(struct connection, hp_next, c, hp->connections);
- c->host_pair = NULL; /* redundant, but safe */
-
- /* if there are no more connections with this host_pair
- * and we haven't even made an initial contact, let's delete
- * this guy in case we were created by an attempted DOS attack.
+ set_cur_connection(c);
+
+ /* Must be careful to avoid circularity:
+ * we mark c as going away so it won't get deleted recursively.
*/
- if (hp->connections == NULL
- && !hp->initial_connection_sent)
+ passert(c->kind != CK_GOING_AWAY);
+ if (c->kind == CK_INSTANCE)
+ {
+ plog("deleting connection \"%s\" instance with peer %s {isakmp=#%lu/ipsec=#%lu}"
+ , c->name
+ , ip_str(&c->spd.that.host_addr)
+ , c->newest_isakmp_sa, c->newest_ipsec_sa);
+ c->kind = CK_GOING_AWAY;
+ }
+ else
+ {
+ plog("deleting connection");
+ }
+ release_connection(c, relations); /* won't delete c */
+
+ if (c->kind == CK_GROUP)
+ delete_group(c);
+
+ /* free up any logging resources */
+ perpeer_logfree(c);
+
+ /* find and delete c from connections list */
+ list_rm(struct connection, ac_next, c, connections);
+ cur_connection = old_cur_connection;
+
+ /* find and delete c from the host pair list */
+ if (c->host_pair == NULL)
{
- passert(hp->pending == NULL); /* ??? must deal with this! */
- list_rm(struct host_pair, next, hp, host_pairs);
- pfree(hp);
+ if (c->ikev1)
+ list_rm(struct connection, hp_next, c, unoriented_connections);
}
- }
+ else
+ {
+ struct host_pair *hp = c->host_pair;
- if (c->kind != CK_GOING_AWAY)
- pfreeany(c->spd.that.virt);
+ list_rm(struct connection, hp_next, c, hp->connections);
+ c->host_pair = NULL; /* redundant, but safe */
+ /* if there are no more connections with this host_pair
+ * and we haven't even made an initial contact, let's delete
+ * this guy in case we were created by an attempted DOS attack.
+ */
+ if (hp->connections == NULL
+ && !hp->initial_connection_sent)
+ {
+ passert(hp->pending == NULL); /* ??? must deal with this! */
+ list_rm(struct host_pair, next, hp, host_pairs);
+ free(hp);
+ }
+ }
+ if (c->kind != CK_GOING_AWAY)
+ {
+ free(c->spd.that.virt);
+ }
#ifdef DEBUG
- cur_debugging = old_cur_debugging;
+ cur_debugging = old_cur_debugging;
#endif
- pfreeany(c->name);
- free_id_content(&c->spd.this.id);
- pfreeany(c->spd.this.updown);
- freeanychunk(c->spd.this.ca);
- free_ietfAttrList(c->spd.this.groups);
- free_id_content(&c->spd.that.id);
- pfreeany(c->spd.that.updown);
- freeanychunk(c->spd.that.ca);
- free_ietfAttrList(c->spd.that.groups);
- free_generalNames(c->requested_ca, TRUE);
- gw_delref(&c->gw_info);
-
- lock_certs_and_keys("delete_connection");
- release_cert(c->spd.this.cert);
- scx_release(c->spd.this.sc);
- release_cert(c->spd.that.cert);
- scx_release(c->spd.that.sc);
- unlock_certs_and_keys("delete_connection");
-
- alg_info_delref((struct alg_info **)&c->alg_info_esp);
- alg_info_delref((struct alg_info **)&c->alg_info_ike);
-
- pfree(c);
+ free(c->name);
+ free_id_content(&c->spd.this.id);
+ free(c->spd.this.updown);
+ free(c->spd.this.ca.ptr);
+ free_ietfAttrList(c->spd.this.groups);
+ free_id_content(&c->spd.that.id);
+ free(c->spd.that.updown);
+ free(c->spd.that.ca.ptr);
+ free_ietfAttrList(c->spd.that.groups);
+ free_generalNames(c->requested_ca, TRUE);
+ gw_delref(&c->gw_info);
+
+ lock_certs_and_keys("delete_connection");
+ release_cert(c->spd.this.cert);
+ scx_release(c->spd.this.sc);
+ release_cert(c->spd.that.cert);
+ scx_release(c->spd.that.sc);
+ unlock_certs_and_keys("delete_connection");
+
+ alg_info_delref((struct alg_info **)&c->alg_info_esp);
+ alg_info_delref((struct alg_info **)&c->alg_info_ike);
+
+ free(c);
}
/* Delete connections with the specified name */
void
delete_connections_by_name(const char *name, bool strict)
{
- struct connection *c = con_by_name(name, strict);
+ struct connection *c = con_by_name(name, strict);
- for (; c != NULL; c = con_by_name(name, FALSE))
- delete_connection(c, FALSE);
+ for (; c != NULL; c = con_by_name(name, FALSE))
+ delete_connection(c, FALSE);
}
void
delete_every_connection(void)
{
- while (connections != NULL)
- delete_connection(connections, TRUE);
+ while (connections != NULL)
+ delete_connection(connections, TRUE);
}
void
release_dead_interfaces(void)
{
- struct host_pair *hp;
-
- for (hp = host_pairs; hp != NULL; hp = hp->next)
- {
- struct connection **pp
- , *p;
+ struct host_pair *hp;
- for (pp = &hp->connections; (p = *pp) != NULL; )
+ for (hp = host_pairs; hp != NULL; hp = hp->next)
{
- if (p->interface->change == IFN_DELETE)
- {
- /* this connection's interface is going away */
- enum connection_kind k = p->kind;
-
- release_connection(p, TRUE);
-
- if (k <= CK_PERMANENT)
- {
- /* The connection should have survived release:
- * move it to the unoriented_connections list.
- */
- passert(p == *pp);
-
- p->interface = NULL;
+ struct connection **pp
+ , *p;
- *pp = p->hp_next; /* advance *pp */
- p->host_pair = NULL;
- p->hp_next = unoriented_connections;
- unoriented_connections = p;
- }
- else
+ for (pp = &hp->connections; (p = *pp) != NULL; )
{
- /* The connection should have vanished,
- * but the previous connection remains.
- */
- passert(p != *pp);
+ if (p->interface->change == IFN_DELETE)
+ {
+ /* this connection's interface is going away */
+ enum connection_kind k = p->kind;
+
+ release_connection(p, TRUE);
+
+ if (k <= CK_PERMANENT)
+ {
+ /* The connection should have survived release:
+ * move it to the unoriented_connections list.
+ */
+ passert(p == *pp);
+
+ p->interface = NULL;
+
+ *pp = p->hp_next; /* advance *pp */
+ p->host_pair = NULL;
+ p->hp_next = unoriented_connections;
+ unoriented_connections = p;
+ }
+ else
+ {
+ /* The connection should have vanished,
+ * but the previous connection remains.
+ */
+ passert(p != *pp);
+ }
+ }
+ else
+ {
+ pp = &p->hp_next; /* advance pp */
+ }
}
- }
- else
- {
- pp = &p->hp_next; /* advance pp */
- }
}
- }
}
/* adjust orientations of connections to reflect newly added interfaces */
void
check_orientations(void)
{
- /* try to orient all the unoriented connections */
- {
- struct connection *c = unoriented_connections;
+ /* try to orient all the unoriented connections */
+ {
+ struct connection *c = unoriented_connections;
- unoriented_connections = NULL;
+ unoriented_connections = NULL;
- while (c != NULL)
- {
- struct connection *nxt = c->hp_next;
+ while (c != NULL)
+ {
+ struct connection *nxt = c->hp_next;
- (void)orient(c);
- connect_to_host_pair(c);
- c = nxt;
+ (void)orient(c);
+ connect_to_host_pair(c);
+ c = nxt;
+ }
}
- }
- /* Check that no oriented connection has become double-oriented.
- * In other words, the far side must not match one of our new interfaces.
- */
- {
- struct iface *i;
-
- for (i = interfaces; i != NULL; i = i->next)
+ /* Check that no oriented connection has become double-oriented.
+ * In other words, the far side must not match one of our new interfaces.
+ */
{
- if (i->change == IFN_ADD)
- {
- struct host_pair *hp;
+ struct iface *i;
- for (hp = host_pairs; hp != NULL; hp = hp->next)
+ for (i = interfaces; i != NULL; i = i->next)
{
- if (sameaddr(&hp->him.addr, &i->addr)
- && (!no_klips || hp->him.port == pluto_port))
- {
- /* bad news: the whole chain of connections
- * hanging off this host pair has both sides
- * matching an interface.
- * We'll get rid of them, using orient and
- * connect_to_host_pair. But we'll be lazy
- * and not ditch the host_pair itself (the
- * cost of leaving it is slight and cannot
- * be induced by a foe).
- */
- struct connection *c = hp->connections;
-
- hp->connections = NULL;
- while (c != NULL)
+ if (i->change == IFN_ADD)
{
- struct connection *nxt = c->hp_next;
-
- c->interface = NULL;
- (void)orient(c);
- connect_to_host_pair(c);
- c = nxt;
+ struct host_pair *hp;
+
+ for (hp = host_pairs; hp != NULL; hp = hp->next)
+ {
+ if (sameaddr(&hp->him.addr, &i->addr)
+ && (!no_klips || hp->him.port == pluto_port))
+ {
+ /* bad news: the whole chain of connections
+ * hanging off this host pair has both sides
+ * matching an interface.
+ * We'll get rid of them, using orient and
+ * connect_to_host_pair. But we'll be lazy
+ * and not ditch the host_pair itself (the
+ * cost of leaving it is slight and cannot
+ * be induced by a foe).
+ */
+ struct connection *c = hp->connections;
+
+ hp->connections = NULL;
+ while (c != NULL)
+ {
+ struct connection *nxt = c->hp_next;
+
+ c->interface = NULL;
+ (void)orient(c);
+ connect_to_host_pair(c);
+ c = nxt;
+ }
+ }
+ }
}
- }
}
- }
}
- }
}
static err_t
default_end(struct end *e, ip_address *dflt_nexthop)
{
- err_t ugh = NULL;
- const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr));
-
- if (afi == NULL)
- return "unknown address family in default_end";
-
- /* default ID to IP (but only if not NO_IP -- WildCard) */
- if (e->id.kind == ID_NONE && !isanyaddr(&e->host_addr))
- {
- e->id.kind = afi->id_addr;
- e->id.ip_addr = e->host_addr;
- e->has_id_wildcards = FALSE;
- }
-
- /* default nexthop to other side */
- if (isanyaddr(&e->host_nexthop))
- e->host_nexthop = *dflt_nexthop;
-
- /* default client to subnet containing only self
- * XXX This may mean that the client's address family doesn't match
- * tunnel_addr_family.
- */
- if (!e->has_client)
- ugh = addrtosubnet(&e->host_addr, &e->client);
-
- return ugh;
+ err_t ugh = NULL;
+ const struct af_info *afi = aftoinfo(addrtypeof(&e->host_addr));
+
+ if (afi == NULL)
+ return "unknown address family in default_end";
+
+ /* default ID to IP (but only if not NO_IP -- WildCard) */
+ if (e->id.kind == ID_ANY && !isanyaddr(&e->host_addr))
+ {
+ e->id.kind = afi->id_addr;
+ e->id.ip_addr = e->host_addr;
+ e->has_id_wildcards = FALSE;
+ }
+
+ /* default nexthop to other side */
+ if (isanyaddr(&e->host_nexthop))
+ e->host_nexthop = *dflt_nexthop;
+
+ /* default client to subnet containing only self
+ * XXX This may mean that the client's address family doesn't match
+ * tunnel_addr_family.
+ */
+ if (!e->has_client)
+ ugh = addrtosubnet(&e->host_addr, &e->client);
+
+ return ugh;
}
/* Format the topology of a connection end, leaving out defaults.
@@ -535,710 +534,702 @@ format_end(char *buf
, bool is_left
, lset_t policy)
{
- char client[SUBNETTOT_BUF];
- const char *client_sep = "";
- char protoport[sizeof(":255/65535")];
- const char *host = NULL;
- char host_space[ADDRTOT_BUF];
- char host_port[sizeof(":65535")];
- char host_id[BUF_LEN + 2];
- char hop[ADDRTOT_BUF];
- const char *hop_sep = "";
- const char *open_brackets = "";
- const char *close_brackets = "";
-
- if (isanyaddr(&this->host_addr))
- {
- switch (policy & (POLICY_GROUP | POLICY_OPPO))
+ char client[SUBNETTOT_BUF];
+ const char *client_sep = "";
+ char protoport[sizeof(":255/65535")];
+ const char *host = NULL;
+ char host_space[ADDRTOT_BUF];
+ char host_port[sizeof(":65535")];
+ char host_id[BUF_LEN + 2];
+ char hop[ADDRTOT_BUF];
+ const char *hop_sep = "";
+ const char *open_brackets = "";
+ const char *close_brackets = "";
+
+ if (isanyaddr(&this->host_addr))
{
- case POLICY_GROUP:
- host = "%group";
- break;
- case POLICY_OPPO:
- host = "%opportunistic";
- break;
- case POLICY_GROUP | POLICY_OPPO:
- host = "%opportunisticgroup";
- break;
- default:
- host = "%any";
- break;
+ switch (policy & (POLICY_GROUP | POLICY_OPPO))
+ {
+ case POLICY_GROUP:
+ host = "%group";
+ break;
+ case POLICY_OPPO:
+ host = "%opportunistic";
+ break;
+ case POLICY_GROUP | POLICY_OPPO:
+ host = "%opportunisticgroup";
+ break;
+ default:
+ host = "%any";
+ break;
+ }
}
- }
-
- client[0] = '\0';
-
- if (is_virtual_end(this) && isanyaddr(&this->host_addr))
- {
- host = "%virtual";
- }
-
- /* [client===] */
- if (this->has_client)
- {
- ip_address client_net, client_mask;
-
- networkof(&this->client, &client_net);
- maskof(&this->client, &client_mask);
- client_sep = "===";
-
- /* {client_subnet_wildcard} */
- if (this->has_client_wildcard)
- {
- open_brackets = "{";
- close_brackets = "}";
- }
-
- if (isanyaddr(&client_net) && isanyaddr(&client_mask)
- && (policy & (POLICY_GROUP | POLICY_OPPO)))
- client_sep = ""; /* boring case */
- else if (subnetisnone(&this->client))
- strcpy(client, "?");
+
+ client[0] = '\0';
+
+ if (is_virtual_end(this) && isanyaddr(&this->host_addr))
+ {
+ host = "%virtual";
+ }
+
+ /* [client===] */
+ if (this->has_client)
+ {
+ ip_address client_net, client_mask;
+
+ networkof(&this->client, &client_net);
+ maskof(&this->client, &client_mask);
+ client_sep = "===";
+
+ /* {client_subnet_wildcard} */
+ if (this->has_client_wildcard)
+ {
+ open_brackets = "{";
+ close_brackets = "}";
+ }
+
+ if (isanyaddr(&client_net) && isanyaddr(&client_mask)
+ && (policy & (POLICY_GROUP | POLICY_OPPO)))
+ client_sep = ""; /* boring case */
+ else if (subnetisnone(&this->client))
+ strcpy(client, "?");
+ else
+ subnettot(&this->client, 0, client, sizeof(client));
+ }
+ else if (this->modecfg && isanyaddr(&this->host_srcip))
+ {
+ /* we are mode config client */
+ client_sep = "===";
+ strcpy(client, "%modecfg");
+ }
+
+ /* host */
+ if (host == NULL)
+ {
+ addrtot(&this->host_addr, 0, host_space, sizeof(host_space));
+ host = host_space;
+ }
+
+ host_port[0] = '\0';
+ if (this->host_port != IKE_UDP_PORT)
+ snprintf(host_port, sizeof(host_port), ":%u"
+ , this->host_port);
+
+ /* payload portocol and port */
+ protoport[0] = '\0';
+ if (this->has_port_wildcard)
+ snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol);
+ else if (this->port || this->protocol)
+ snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol
+ , this->port);
+
+ /* id, if different from host */
+ host_id[0] = '\0';
+ if (this->id.kind == ID_MYID)
+ {
+ strcpy(host_id, "[%myid]");
+ }
+ else if (!(this->id.kind == ID_ANY
+ || (id_is_ipaddr(&this->id) && sameaddr(&this->id.ip_addr, &this->host_addr))))
+ {
+ int len = idtoa(&this->id, host_id+1, sizeof(host_id)-2);
+
+ host_id[0] = '[';
+ strcpy(&host_id[len < 0? (ptrdiff_t)sizeof(host_id)-2 : 1 + len], "]");
+ }
+
+ /* [---hop] */
+ hop[0] = '\0';
+ hop_sep = "";
+ if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr))
+ {
+ addrtot(&this->host_nexthop, 0, hop, sizeof(hop));
+ hop_sep = "---";
+ }
+
+ if (is_left)
+ snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
+ , open_brackets, client, close_brackets, client_sep
+ , this->allow_any? "%":""
+ , host, host_port, host_id, protoport
+ , hop_sep, hop);
else
- subnettot(&this->client, 0, client, sizeof(client));
- }
- else if (this->modecfg && isanyaddr(&this->host_srcip))
- {
- /* we are mode config client */
- client_sep = "===";
- strcpy(client, "%modecfg");
- }
-
- /* host */
- if (host == NULL)
- {
- addrtot(&this->host_addr, 0, host_space, sizeof(host_space));
- host = host_space;
- }
-
- host_port[0] = '\0';
- if (this->host_port != IKE_UDP_PORT)
- snprintf(host_port, sizeof(host_port), ":%u"
- , this->host_port);
-
- /* payload portocol and port */
- protoport[0] = '\0';
- if (this->has_port_wildcard)
- snprintf(protoport, sizeof(protoport), ":%u/%%any", this->protocol);
- else if (this->port || this->protocol)
- snprintf(protoport, sizeof(protoport), ":%u/%u", this->protocol
- , this->port);
-
- /* id, if different from host */
- host_id[0] = '\0';
- if (this->id.kind == ID_MYID)
- {
- strcpy(host_id, "[%myid]");
- }
- else if (!(this->id.kind == ID_NONE
- || (id_is_ipaddr(&this->id) && sameaddr(&this->id.ip_addr, &this->host_addr))))
- {
- int len = idtoa(&this->id, host_id+1, sizeof(host_id)-2);
-
- host_id[0] = '[';
- strcpy(&host_id[len < 0? (ptrdiff_t)sizeof(host_id)-2 : 1 + len], "]");
- }
-
- /* [---hop] */
- hop[0] = '\0';
- hop_sep = "";
- if (that != NULL && !sameaddr(&this->host_nexthop, &that->host_addr))
- {
- addrtot(&this->host_nexthop, 0, hop, sizeof(hop));
- hop_sep = "---";
- }
-
- if (is_left)
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
- , open_brackets, client, close_brackets, client_sep
- , this->allow_any? "%":""
- , host, host_port, host_id, protoport
- , hop_sep, hop);
- else
- snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
- , hop, hop_sep
- , this->allow_any? "%":""
- , host, host_port, host_id, protoport, client_sep
- , open_brackets, client, close_brackets);
- return strlen(buf);
+ snprintf(buf, buf_len, "%s%s%s%s%s%s%s%s%s%s%s"
+ , hop, hop_sep
+ , this->allow_any? "%":""
+ , host, host_port, host_id, protoport, client_sep
+ , open_brackets, client, close_brackets);
+ return strlen(buf);
}
/* format topology of a connection.
* Two symmetric ends separated by ...
*/
-#define CONNECTION_BUF (2 * (END_BUF - 1) + 4)
+#define CONNECTION_BUF (2 * (END_BUF - 1) + 4)
static size_t
format_connection(char *buf, size_t buf_len
- , const struct connection *c
- , struct spd_route *sr)
+ , const struct connection *c
+ , struct spd_route *sr)
{
- size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY);
+ size_t w = format_end(buf, buf_len, &sr->this, &sr->that, TRUE, LEMPTY);
- w += snprintf(buf + w, buf_len - w, "...");
- return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);
+ w += snprintf(buf + w, buf_len - w, "...");
+ return w + format_end(buf + w, buf_len - w, &sr->that, &sr->this, FALSE, c->policy);
}
static void
unshare_connection_strings(struct connection *c)
{
- c->name = clone_str(c->name, "connection name");
-
- unshare_id_content(&c->spd.this.id);
- c->spd.this.updown = clone_str(c->spd.this.updown, "updown");
- scx_share(c->spd.this.sc);
- share_cert(c->spd.this.cert);
- if (c->spd.this.ca.ptr != NULL)
- clonetochunk(c->spd.this.ca, c->spd.this.ca.ptr, c->spd.this.ca.len, "ca string");
-
- unshare_id_content(&c->spd.that.id);
- c->spd.that.updown = clone_str(c->spd.that.updown, "updown");
- scx_share(c->spd.that.sc);
- share_cert(c->spd.that.cert);
- if (c->spd.that.ca.ptr != NULL)
- clonetochunk(c->spd.that.ca, c->spd.that.ca.ptr, c->spd.that.ca.len, "ca string");
-
- /* increment references to algo's */
- alg_info_addref((struct alg_info *)c->alg_info_esp);
- alg_info_addref((struct alg_info *)c->alg_info_ike);
+ c->name = clone_str(c->name);
+
+ unshare_id_content(&c->spd.this.id);
+ c->spd.this.updown = clone_str(c->spd.this.updown);
+ scx_share(c->spd.this.sc);
+ share_cert(c->spd.this.cert);
+ c->spd.this.ca = chunk_clone(c->spd.this.ca);
+
+ unshare_id_content(&c->spd.that.id);
+ c->spd.that.updown = clone_str(c->spd.that.updown);
+ scx_share(c->spd.that.sc);
+ share_cert(c->spd.that.cert);
+ c->spd.that.ca = chunk_clone(c->spd.that.ca);
+
+ /* increment references to algo's */
+ alg_info_addref((struct alg_info *)c->alg_info_esp);
+ alg_info_addref((struct alg_info *)c->alg_info_ike);
}
-static void
-load_end_certificate(const char *filename, struct end *dst)
+static void load_end_certificate(char *filename, struct end *dst)
{
- time_t valid_until;
- cert_t cert;
- bool valid_cert = FALSE;
- bool cached_cert = FALSE;
+ time_t valid_until;
+ cert_t cert;
+ bool valid_cert = FALSE;
+ bool cached_cert = FALSE;
- /* initialize end certificate */
- dst->cert.type = CERT_NONE;
- dst->cert.u.x509 = NULL;
+ /* initialize end certificate */
+ dst->cert.type = CERT_NONE;
+ dst->cert.u.x509 = NULL;
- /* initialize smartcard info record */
- dst->sc = NULL;
+ /* initialize smartcard info record */
+ dst->sc = NULL;
- if (filename != NULL)
- {
- if (scx_on_smartcard(filename))
+ if (filename != NULL)
{
- /* load cert from smartcard */
- valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert);
- }
- else
- {
- /* load cert from file */
- valid_cert = load_host_cert(filename, &cert);
+ if (scx_on_smartcard(filename))
+ {
+ /* load cert from smartcard */
+ valid_cert = scx_load_cert(filename, &dst->sc, &cert, &cached_cert);
+ }
+ else
+ {
+ /* load cert from file */
+ valid_cert = load_host_cert(filename, &cert);
+ }
}
- }
- if (valid_cert)
- {
- err_t ugh = NULL;
-
- switch (cert.type)
+ if (valid_cert)
{
- case CERT_PGP:
- select_pgpcert_id(cert.u.pgp, &dst->id);
-
- if (cached_cert)
- dst->cert = cert;
- else
- {
- valid_until = cert.u.pgp->until;
- add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.pgp = add_pgpcert(cert.u.pgp);
- }
- break;
- case CERT_X509_SIGNATURE:
- select_x509cert_id(cert.u.x509, &dst->id);
-
- if (cached_cert)
- dst->cert = cert;
- else
- {
- /* check validity of cert */
- valid_until = cert.u.x509->notAfter;
- ugh = check_validity(cert.u.x509, &valid_until);
- if (ugh != NULL)
+ err_t ugh = NULL;
+
+ switch (cert.type)
{
- plog(" %s", ugh);
- free_x509cert(cert.u.x509);
- break;
- }
+ case CERT_PGP:
+ select_pgpcert_id(cert.u.pgp, &dst->id);
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
- add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL);
- dst->cert.type = cert.type;
- dst->cert.u.x509 = add_x509cert(cert.u.x509);
- }
- /* if no CA is defined, use issuer as default */
- if (dst->ca.ptr == NULL)
- dst->ca = dst->cert.u.x509->issuer;
- break;
- default:
- break;
- }
+ if (cached_cert)
+ dst->cert = cert;
+ else
+ {
+ valid_until = cert.u.pgp->until;
+ add_pgp_public_key(cert.u.pgp, cert.u.pgp->until, DAL_LOCAL);
+ dst->cert.type = cert.type;
+ dst->cert.u.pgp = add_pgpcert(cert.u.pgp);
+ }
+ break;
+ case CERT_X509_SIGNATURE:
+ select_x509cert_id(cert.u.x509, &dst->id);
- /* cache the certificate that was last retrieved from the smartcard */
- if (dst->sc != NULL)
- {
- if (!same_cert(&dst->sc->last_cert, &dst->cert))
- {
- lock_certs_and_keys("load_end_certificates");
- release_cert(dst->sc->last_cert);
- dst->sc->last_cert = dst->cert;
- share_cert(dst->cert);
- unlock_certs_and_keys("load_end_certificates");
- }
- time(&dst->sc->last_load);
+ if (cached_cert)
+ dst->cert = cert;
+ else
+ {
+ /* check validity of cert */
+ valid_until = cert.u.x509->notAfter;
+ ugh = check_validity(cert.u.x509, &valid_until);
+ if (ugh != NULL)
+ {
+ plog(" %s", ugh);
+ free_x509cert(cert.u.x509);
+ break;
+ }
+
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is valid")
+ )
+ add_x509_public_key(cert.u.x509, valid_until, DAL_LOCAL);
+ dst->cert.type = cert.type;
+ dst->cert.u.x509 = add_x509cert(cert.u.x509);
+ }
+ /* if no CA is defined, use issuer as default */
+ if (dst->ca.ptr == NULL)
+ dst->ca = dst->cert.u.x509->issuer;
+ break;
+ default:
+ break;
+ }
+
+ /* cache the certificate that was last retrieved from the smartcard */
+ if (dst->sc != NULL)
+ {
+ if (!same_cert(&dst->sc->last_cert, &dst->cert))
+ {
+ lock_certs_and_keys("load_end_certificates");
+ release_cert(dst->sc->last_cert);
+ dst->sc->last_cert = dst->cert;
+ share_cert(dst->cert);
+ unlock_certs_and_keys("load_end_certificates");
+ }
+ time(&dst->sc->last_load);
+ }
}
- }
}
static bool
extract_end(struct end *dst, const whack_end_t *src, const char *which)
{
- bool same_ca = FALSE;
-
- /* decode id, if any */
- if (src->id == NULL)
- {
- dst->id.kind = ID_NONE;
- }
- else
- {
- err_t ugh = atoid(src->id, &dst->id, TRUE);
+ bool same_ca = FALSE;
- if (ugh != NULL)
+ /* decode id, if any */
+ if (src->id == NULL)
{
- loglog(RC_BADID, "bad %s --id: %s (ignored)", which, ugh);
- dst->id = empty_id; /* ignore bad one */
+ dst->id.kind = ID_ANY;
}
- }
+ else
+ {
+ err_t ugh = atoid(src->id, &dst->id, TRUE);
- dst->ca = empty_chunk;
+ if (ugh != NULL)
+ {
+ loglog(RC_BADID, "bad %s --id: %s (ignored)", which, ugh);
+ dst->id = empty_id; /* ignore bad one */
+ }
+ }
+
+ dst->ca = chunk_empty;
- /* decode CA distinguished name, if any */
- if (src->ca != NULL)
- {
- if streq(src->ca, "%same")
- same_ca = TRUE;
- else if (!streq(src->ca, "%any"))
+ /* decode CA distinguished name, if any */
+ if (src->ca != NULL)
{
- err_t ugh;
-
- dst->ca.ptr = temporary_cyclic_buffer();
- ugh = atodn(src->ca, &dst->ca);
- if (ugh != NULL)
- {
- plog("bad CA string '%s': %s (ignored)", src->ca, ugh);
- dst->ca = empty_chunk;
- }
+ if streq(src->ca, "%same")
+ same_ca = TRUE;
+ else if (!streq(src->ca, "%any"))
+ {
+ err_t ugh;
+
+ dst->ca.ptr = temporary_cyclic_buffer();
+ ugh = atodn(src->ca, &dst->ca);
+ if (ugh != NULL)
+ {
+ plog("bad CA string '%s': %s (ignored)", src->ca, ugh);
+ dst->ca = chunk_empty;
+ }
+ }
}
- }
-
- /* load local end certificate and extract ID, if any */
- load_end_certificate(src->cert, dst);
-
- /* does id has wildcards? */
- dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0;
-
- /* decode group attributes, if any */
- decode_groups(src->groups, &dst->groups);
-
- /* the rest is simple copying of corresponding fields */
- dst->host_addr = src->host_addr;
- dst->host_nexthop = src->host_nexthop;
- dst->host_srcip = src->host_srcip;
- dst->has_natip = src->has_natip;
- dst->client = src->client;
- dst->protocol = src->protocol;
- dst->port = src->port;
- dst->has_port_wildcard = src->has_port_wildcard;
- dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand;
- dst->has_client = src->has_client;
- dst->has_client_wildcard = src->has_client_wildcard;
- dst->modecfg = src->modecfg;
- dst->hostaccess = src->hostaccess;
- dst->allow_any = src->allow_any;
- dst->sendcert = src->sendcert;
- dst->updown = src->updown;
- dst->host_port = src->host_port;
-
- /* if host sourceip is defined but no client is present
- * behind the host then set client to sourceip/32
- */
- if (addrbytesptr(&dst->host_srcip, NULL)
- && !isanyaddr(&dst->host_srcip)
- && !dst->has_natip
- && !dst->has_client)
- {
- err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client);
- if (ugh != NULL)
- plog("could not assign host sourceip to client subnet");
- else
- dst->has_client = TRUE;
- }
- return same_ca;
+ /* load local end certificate and extract ID, if any */
+ load_end_certificate(src->cert, dst);
+
+ /* does id has wildcards? */
+ dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0;
+
+ /* decode group attributes, if any */
+ decode_groups(src->groups, &dst->groups);
+
+ /* the rest is simple copying of corresponding fields */
+ dst->host_addr = src->host_addr;
+ dst->host_nexthop = src->host_nexthop;
+ dst->host_srcip = src->host_srcip;
+ dst->has_natip = src->has_natip;
+ dst->client = src->client;
+ dst->protocol = src->protocol;
+ dst->port = src->port;
+ dst->has_port_wildcard = src->has_port_wildcard;
+ dst->key_from_DNS_on_demand = src->key_from_DNS_on_demand;
+ dst->has_client = src->has_client;
+ dst->has_client_wildcard = src->has_client_wildcard;
+ dst->modecfg = src->modecfg;
+ dst->hostaccess = src->hostaccess;
+ dst->allow_any = src->allow_any;
+ dst->sendcert = src->sendcert;
+ dst->updown = src->updown;
+ dst->host_port = src->host_port;
+
+ /* if host sourceip is defined but no client is present
+ * behind the host then set client to sourceip/32
+ */
+ if (addrbytesptr(&dst->host_srcip, NULL)
+ && !isanyaddr(&dst->host_srcip)
+ && !dst->has_natip
+ && !dst->has_client)
+ {
+ err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client);
+
+ if (ugh != NULL)
+ plog("could not assign host sourceip to client subnet");
+ else
+ dst->has_client = TRUE;
+ }
+ return same_ca;
}
static bool
check_connection_end(const whack_end_t *this, const whack_end_t *that
, const whack_message_t *wm)
{
- if (wm->addr_family != addrtypeof(&this->host_addr)
- || wm->addr_family != addrtypeof(&this->host_nexthop)
- || (this->has_client? wm->tunnel_addr_family : wm->addr_family)
- != subnettypeof(&this->client)
- || subnettypeof(&this->client) != subnettypeof(&that->client))
- {
- /* this should have been diagnosed by whack, so we need not be clear
- * !!! overloaded use of RC_CLASH
- */
- loglog(RC_CLASH, "address family inconsistency in connection");
- return FALSE;
- }
+ if (wm->addr_family != addrtypeof(&this->host_addr)
+ || wm->addr_family != addrtypeof(&this->host_nexthop)
+ || (this->has_client? wm->tunnel_addr_family : wm->addr_family)
+ != subnettypeof(&this->client)
+ || subnettypeof(&this->client) != subnettypeof(&that->client))
+ {
+ /* this should have been diagnosed by whack, so we need not be clear
+ * !!! overloaded use of RC_CLASH
+ */
+ loglog(RC_CLASH, "address family inconsistency in connection");
+ return FALSE;
+ }
- if (isanyaddr(&that->host_addr))
- {
- /* other side is wildcard: we must check if other conditions met */
- if (isanyaddr(&this->host_addr))
+ if (isanyaddr(&that->host_addr))
{
- loglog(RC_ORIENT, "connection must specify host IP address for our side");
- return FALSE;
+ /* other side is wildcard: we must check if other conditions met */
+ if (isanyaddr(&this->host_addr))
+ {
+ loglog(RC_ORIENT, "connection must specify host IP address for our side");
+ return FALSE;
+ }
}
- }
- if (this->virt && (!isanyaddr(&this->host_addr) || this->has_client))
- {
- loglog(RC_CLASH,
- "virtual IP must only be used with %%any and without client");
- return FALSE;
- }
+ if (this->virt && (!isanyaddr(&this->host_addr) || this->has_client))
+ {
+ loglog(RC_CLASH,
+ "virtual IP must only be used with %%any and without client");
+ return FALSE;
+ }
- return TRUE; /* happy */
+ return TRUE; /* happy */
}
struct connection *
find_connection_by_reqid(uint32_t reqid)
{
- struct connection *c;
+ struct connection *c;
- reqid &= ~3;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->spd.reqid == reqid)
- return c;
- }
+ reqid &= ~3;
+ for (c = connections; c != NULL; c = c->ac_next)
+ {
+ if (c->spd.reqid == reqid)
+ return c;
+ }
- return NULL;
+ return NULL;
}
static uint32_t
gen_reqid(void)
{
- uint32_t start;
- static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;
-
- start = reqid;
- do {
- reqid += 4;
- if (reqid == 0)
- reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4;
- if (!find_connection_by_reqid(reqid))
- return reqid;
- } while (reqid != start);
-
- exit_log("unable to allocate reqid");
- return 0; /* never reached ... */
+ uint32_t start;
+ static uint32_t reqid = IPSEC_MANUAL_REQID_MAX & ~3;
+
+ start = reqid;
+ do {
+ reqid += 4;
+ if (reqid == 0)
+ reqid = (IPSEC_MANUAL_REQID_MAX & ~3) + 4;
+ if (!find_connection_by_reqid(reqid))
+ return reqid;
+ } while (reqid != start);
+
+ exit_log("unable to allocate reqid");
+ return 0; /* never reached ... */
}
void
add_connection(const whack_message_t *wm)
{
- if (con_by_name(wm->name, FALSE) != NULL)
- {
- loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name);
- }
- else if (wm->right.protocol != wm->left.protocol)
- {
- /* this should haven been diagnosed by whack
- * !!! overloaded use of RC_CLASH
- */
- loglog(RC_CLASH, "the protocol must be the same for leftport and rightport");
- }
- else if (check_connection_end(&wm->right, &wm->left, wm)
- && check_connection_end(&wm->left, &wm->right, wm))
- {
- bool same_rightca, same_leftca;
- struct connection *c = alloc_thing(struct connection, "struct connection");
-
- c->name = wm->name;
- c->ikev1 = wm->ikev1;
- c->policy = wm->policy;
-
- if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp)
- loglog(RC_COMMENT
- , "ignoring --compress in \"%s\" because KLIPS is not configured to do IPCOMP"
- , c->name);
-
- if (wm->esp)
+ if (con_by_name(wm->name, FALSE) != NULL)
{
- const char *ugh;
-
- DBG(DBG_CONTROL,
- DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL")
- )
- c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : "", &ugh);
-
- DBG(DBG_CRYPT|DBG_CONTROL,
- static char buf[256]="<NULL>";
-
- if (c->alg_info_esp)
- alg_info_snprint(buf, sizeof(buf)
- ,(struct alg_info *)c->alg_info_esp);
- DBG_log("esp string values: %s", buf);
- )
- if (c->alg_info_esp)
- {
- if (c->alg_info_esp->alg_info_cnt==0)
- loglog(RC_LOG_SERIOUS
- , "got 0 transforms for esp=\"%s\"", wm->esp);
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "esp string error: %s", ugh? ugh : "Unknown");
- }
+ loglog(RC_DUPNAME, "attempt to redefine connection \"%s\"", wm->name);
}
-
- if (wm->ike)
+ else if (wm->right.protocol != wm->left.protocol)
{
- const char *ugh;
-
- DBG(DBG_CONTROL,
- DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL")
- )
- c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "", &ugh);
-
- DBG(DBG_CRYPT|DBG_CONTROL,
- static char buf[256]="<NULL>";
-
- if (c->alg_info_ike)
- alg_info_snprint(buf, sizeof(buf)
- , (struct alg_info *)c->alg_info_ike);
- DBG_log("ike string values: %s", buf);
- )
- if (c->alg_info_ike)
- {
- if (c->alg_info_ike->alg_info_cnt==0)
- loglog(RC_LOG_SERIOUS
- , "got 0 transforms for ike=\"%s\"", wm->ike);
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "ike string error: %s", ugh? ugh : "Unknown");
- }
+ /* this should haven been diagnosed by whack
+ * !!! overloaded use of RC_CLASH
+ */
+ loglog(RC_CLASH, "the protocol must be the same for leftport and rightport");
}
-
- c->sa_ike_life_seconds = wm->sa_ike_life_seconds;
- c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds;
- c->sa_rekey_margin = wm->sa_rekey_margin;
- c->sa_rekey_fuzz = wm->sa_rekey_fuzz;
- c->sa_keying_tries = wm->sa_keying_tries;
+ else if (check_connection_end(&wm->right, &wm->left, wm)
+ && check_connection_end(&wm->left, &wm->right, wm))
+ {
+ bool same_rightca, same_leftca;
+ struct connection *c = malloc_thing(struct connection);
- /* RFC 3706 DPD */
- c->dpd_delay = wm->dpd_delay;
- c->dpd_timeout = wm->dpd_timeout;
- c->dpd_action = wm->dpd_action;
+ zero(c);
+ c->name = wm->name;
+ c->ikev1 = wm->ikev1;
+ c->policy = wm->policy;
- c->addr_family = wm->addr_family;
- c->tunnel_addr_family = wm->tunnel_addr_family;
+ if ((c->policy & POLICY_COMPRESS) && !can_do_IPcomp)
+ loglog(RC_COMMENT
+ , "ignoring --compress in \"%s\" because KLIPS is not configured to do IPCOMP"
+ , c->name);
- c->requested_ca = NULL;
+ if (wm->esp)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL")
+ )
+ c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : "");
+
+ DBG(DBG_CRYPT|DBG_CONTROL,
+ static char buf[BUF_LEN]="<NULL>";
+
+ if (c->alg_info_esp)
+ alg_info_snprint(buf, sizeof(buf)
+ ,(struct alg_info *)c->alg_info_esp);
+ DBG_log("esp proposal: %s", buf);
+ )
+ if (c->alg_info_esp)
+ {
+ if (c->alg_info_esp->alg_info_cnt==0)
+ loglog(RC_LOG_SERIOUS
+ , "got 0 transforms for esp=\"%s\"", wm->esp);
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "esp string error");
+ }
+ }
+
+ if (wm->ike)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL")
+ )
+ c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "");
+
+ DBG(DBG_CRYPT|DBG_CONTROL,
+ static char buf[BUF_LEN]="<NULL>";
+
+ if (c->alg_info_ike)
+ alg_info_snprint(buf, sizeof(buf)
+ , (struct alg_info *)c->alg_info_ike);
+ DBG_log("ike proposal: %s", buf);
+ )
+ if (c->alg_info_ike)
+ {
+ if (c->alg_info_ike->alg_info_cnt==0)
+ loglog(RC_LOG_SERIOUS
+ , "got 0 transforms for ike=\"%s\"", wm->ike);
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "ike string error:");
+ }
+ }
+
+ c->sa_ike_life_seconds = wm->sa_ike_life_seconds;
+ c->sa_ipsec_life_seconds = wm->sa_ipsec_life_seconds;
+ c->sa_rekey_margin = wm->sa_rekey_margin;
+ c->sa_rekey_fuzz = wm->sa_rekey_fuzz;
+ c->sa_keying_tries = wm->sa_keying_tries;
- same_leftca = extract_end(&c->spd.this, &wm->left, "left");
- same_rightca = extract_end(&c->spd.that, &wm->right, "right");
+ /* RFC 3706 DPD */
+ c->dpd_delay = wm->dpd_delay;
+ c->dpd_timeout = wm->dpd_timeout;
+ c->dpd_action = wm->dpd_action;
- if (same_rightca)
- c->spd.that.ca = c->spd.this.ca;
- else if (same_leftca)
- c->spd.this.ca = c->spd.that.ca;
+ c->addr_family = wm->addr_family;
+ c->tunnel_addr_family = wm->tunnel_addr_family;
- default_end(&c->spd.this, &c->spd.that.host_addr);
- default_end(&c->spd.that, &c->spd.this.host_addr);
+ c->requested_ca = NULL;
- /* force any wildcard host IP address, any wildcard subnet
- * or any wildcard ID to that end
- */
- if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard
- || c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards
- || c->spd.this.allow_any)
- {
- struct end t = c->spd.this;
+ same_leftca = extract_end(&c->spd.this, &wm->left, "left");
+ same_rightca = extract_end(&c->spd.that, &wm->right, "right");
- c->spd.this = c->spd.that;
- c->spd.that = t;
- }
+ if (same_rightca)
+ c->spd.that.ca = c->spd.this.ca;
+ else if (same_leftca)
+ c->spd.this.ca = c->spd.that.ca;
- c->spd.next = NULL;
- c->spd.reqid = gen_reqid();
+ default_end(&c->spd.this, &c->spd.that.host_addr);
+ default_end(&c->spd.that, &c->spd.this.host_addr);
- /* set internal fields */
- c->instance_serial = 0;
- c->ac_next = connections;
- connections = c;
- c->interface = NULL;
- c->spd.routing = RT_UNROUTED;
- c->newest_isakmp_sa = SOS_NOBODY;
- c->newest_ipsec_sa = SOS_NOBODY;
- c->spd.eroute_owner = SOS_NOBODY;
-
- if (c->policy & POLICY_GROUP)
- {
- c->kind = CK_GROUP;
- add_group(c);
- }
- else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy))
- || c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard
- || c->spd.that.has_id_wildcards || c->spd.that.allow_any)
- {
- /* Opportunistic or Road Warrior or wildcard client subnet
- * or wildcard ID */
- c->kind = CK_TEMPLATE;
- }
- else
- {
- c->kind = CK_PERMANENT;
- }
- set_policy_prio(c); /* must be after kind is set */
+ /* force any wildcard host IP address, any wildcard subnet
+ * or any wildcard ID to that end
+ */
+ if (isanyaddr(&c->spd.this.host_addr) || c->spd.this.has_client_wildcard
+ || c->spd.this.has_port_wildcard || c->spd.this.has_id_wildcards
+ || c->spd.this.allow_any)
+ {
+ struct end t = c->spd.this;
+
+ c->spd.this = c->spd.that;
+ c->spd.that = t;
+ }
+
+ c->spd.next = NULL;
+ c->spd.reqid = gen_reqid();
+
+ /* set internal fields */
+ c->instance_serial = 0;
+ c->ac_next = connections;
+ connections = c;
+ c->interface = NULL;
+ c->spd.routing = RT_UNROUTED;
+ c->newest_isakmp_sa = SOS_NOBODY;
+ c->newest_ipsec_sa = SOS_NOBODY;
+ c->spd.eroute_owner = SOS_NOBODY;
+
+ if (c->policy & POLICY_GROUP)
+ {
+ c->kind = CK_GROUP;
+ add_group(c);
+ }
+ else if ((isanyaddr(&c->spd.that.host_addr) && !NEVER_NEGOTIATE(c->policy))
+ || c->spd.that.has_client_wildcard || c->spd.that.has_port_wildcard
+ || c->spd.that.has_id_wildcards || c->spd.that.allow_any)
+ {
+ /* Opportunistic or Road Warrior or wildcard client subnet
+ * or wildcard ID */
+ c->kind = CK_TEMPLATE;
+ }
+ else
+ {
+ c->kind = CK_PERMANENT;
+ }
+ set_policy_prio(c); /* must be after kind is set */
#ifdef DEBUG
- c->extra_debugging = wm->debugging;
+ c->extra_debugging = wm->debugging;
#endif
- c->gw_info = NULL;
+ c->gw_info = NULL;
- passert(!(wm->left.virt && wm->right.virt));
- if (wm->left.virt || wm->right.virt)
- {
- passert(isanyaddr(&c->spd.that.host_addr));
- c->spd.that.virt = create_virtual(c,
- wm->left.virt ? wm->left.virt : wm->right.virt);
- if (c->spd.that.virt)
- c->spd.that.has_client = TRUE;
- }
+ passert(!(wm->left.virt && wm->right.virt));
+ if (wm->left.virt || wm->right.virt)
+ {
+ passert(isanyaddr(&c->spd.that.host_addr));
+ c->spd.that.virt = create_virtual(c,
+ wm->left.virt ? wm->left.virt : wm->right.virt);
+ if (c->spd.that.virt)
+ c->spd.that.has_client = TRUE;
+ }
- unshare_connection_strings(c);
- (void)orient(c);
+ unshare_connection_strings(c);
+ (void)orient(c);
- if (c->ikev1)
- connect_to_host_pair(c);
+ if (c->ikev1)
+ connect_to_host_pair(c);
- /* log all about this connection */
- plog("added connection description \"%s\"", c->name);
- DBG(DBG_CONTROL,
- char topo[CONNECTION_BUF];
-
- (void) format_connection(topo, sizeof(topo), c, &c->spd);
-
- DBG_log("%s", topo);
-
- /* Make sure that address families can be correctly inferred
- * from printed ends.
- */
- passert(c->addr_family == addrtypeof(&c->spd.this.host_addr)
- && c->addr_family == addrtypeof(&c->spd.this.host_nexthop)
- && (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family)
- == subnettypeof(&c->spd.this.client)
-
- && c->addr_family == addrtypeof(&c->spd.that.host_addr)
- && c->addr_family == addrtypeof(&c->spd.that.host_nexthop)
- && (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family)
- == subnettypeof(&c->spd.that.client));
-
- DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;"
- " rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s"
- , (unsigned long) c->sa_ike_life_seconds
- , (unsigned long) c->sa_ipsec_life_seconds
- , (unsigned long) c->sa_rekey_margin
- , (unsigned long) c->sa_rekey_fuzz
- , (unsigned long) c->sa_keying_tries
- , prettypolicy(c->policy));
- );
- }
+ /* log all about this connection */
+ plog("added connection description \"%s\"", c->name);
+ DBG(DBG_CONTROL,
+ char topo[CONNECTION_BUF];
+
+ (void) format_connection(topo, sizeof(topo), c, &c->spd);
+
+ DBG_log("%s", topo);
+
+ /* Make sure that address families can be correctly inferred
+ * from printed ends.
+ */
+ passert(c->addr_family == addrtypeof(&c->spd.this.host_addr)
+ && c->addr_family == addrtypeof(&c->spd.this.host_nexthop)
+ && (c->spd.this.has_client? c->tunnel_addr_family : c->addr_family)
+ == subnettypeof(&c->spd.this.client)
+
+ && c->addr_family == addrtypeof(&c->spd.that.host_addr)
+ && c->addr_family == addrtypeof(&c->spd.that.host_nexthop)
+ && (c->spd.that.has_client? c->tunnel_addr_family : c->addr_family)
+ == subnettypeof(&c->spd.that.client));
+
+ DBG_log("ike_life: %lus; ipsec_life: %lus; rekey_margin: %lus;"
+ " rekey_fuzz: %lu%%; keyingtries: %lu; policy: %s"
+ , (unsigned long) c->sa_ike_life_seconds
+ , (unsigned long) c->sa_ipsec_life_seconds
+ , (unsigned long) c->sa_rekey_margin
+ , (unsigned long) c->sa_rekey_fuzz
+ , (unsigned long) c->sa_keying_tries
+ , prettypolicy(c->policy));
+ );
+ }
}
/* Derive a template connection from a group connection and target.
* Similar to instantiate(). Happens at whack --listen.
* Returns name of new connection. May be NULL.
- * Caller is responsible for pfreeing.
+ * Caller is responsible for freeing.
*/
char *
add_group_instance(struct connection *group, const ip_subnet *target)
{
- char namebuf[100]
- , targetbuf[SUBNETTOT_BUF];
- struct connection *t;
- char *name = NULL;
-
- passert(group->kind == CK_GROUP);
- passert(oriented(*group));
-
- /* manufacture a unique name for this template */
- subnettot(target, 0, targetbuf, sizeof(targetbuf));
- snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf);
-
- if (con_by_name(namebuf, FALSE) != NULL)
- {
- loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\""
- , namebuf);
- }
- else
- {
- t = clone_thing(*group, "group instance");
- t->name = namebuf;
- unshare_connection_strings(t);
- name = clone_str(t->name, "group instance name");
- t->spd.that.client = *target;
- t->policy &= ~(POLICY_GROUP | POLICY_GROUTED);
- t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy)
- ? CK_TEMPLATE : CK_INSTANCE;
+ char namebuf[100]
+ , targetbuf[SUBNETTOT_BUF];
+ struct connection *t;
+ char *name = NULL;
- /* reset log file info */
- t->log_file_name = NULL;
- t->log_file = NULL;
- t->log_file_err = FALSE;
+ passert(group->kind == CK_GROUP);
+ passert(oriented(*group));
- t->spd.reqid = gen_reqid();
+ /* manufacture a unique name for this template */
+ subnettot(target, 0, targetbuf, sizeof(targetbuf));
+ snprintf(namebuf, sizeof(namebuf), "%s#%s", group->name, targetbuf);
- if (t->spd.that.virt)
+ if (con_by_name(namebuf, FALSE) != NULL)
{
- DBG_log("virtual_ip not supported in group instance");
- t->spd.that.virt = NULL;
+ loglog(RC_DUPNAME, "group name + target yields duplicate name \"%s\""
+ , namebuf);
}
+ else
+ {
+ t = clone_thing(*group);
+ t->name = namebuf;
+ unshare_connection_strings(t);
+ name = clone_str(t->name);
+ t->spd.that.client = *target;
+ t->policy &= ~(POLICY_GROUP | POLICY_GROUTED);
+ t->kind = isanyaddr(&t->spd.that.host_addr) && !NEVER_NEGOTIATE(t->policy)
+ ? CK_TEMPLATE : CK_INSTANCE;
+
+ /* reset log file info */
+ t->log_file_name = NULL;
+ t->log_file = NULL;
+ t->log_file_err = FALSE;
+
+ t->spd.reqid = gen_reqid();
+
+ if (t->spd.that.virt)
+ {
+ DBG_log("virtual_ip not supported in group instance");
+ t->spd.that.virt = NULL;
+ }
- /* add to connections list */
- t->ac_next = connections;
- connections = t;
+ /* add to connections list */
+ t->ac_next = connections;
+ connections = t;
- /* same host_pair as parent: stick after parent on list */
- group->hp_next = t;
+ /* same host_pair as parent: stick after parent on list */
+ group->hp_next = t;
- /* route if group is routed */
- if (group->policy & POLICY_GROUTED)
- {
- if (!trap_connection(t))
- whack_log(RC_ROUTE, "could not route");
+ /* route if group is routed */
+ if (group->policy & POLICY_GROUTED)
+ {
+ if (!trap_connection(t))
+ whack_log(RC_ROUTE, "could not route");
+ }
}
- }
- return name;
+ return name;
}
/* an old target has disappeared for a group: delete instance */
@@ -1246,17 +1237,17 @@ void
remove_group_instance(const struct connection *group USED_BY_DEBUG
, const char *name)
{
- passert(group->kind == CK_GROUP);
- passert(oriented(*group));
+ passert(group->kind == CK_GROUP);
+ passert(oriented(*group));
- delete_connections_by_name(name, FALSE);
+ delete_connections_by_name(name, FALSE);
}
/* Common part of instantiating a Road Warrior or Opportunistic connection.
* his_id can be used to carry over an ID discovered in Phase 1.
* It must not disagree with the one in c, but if that is unspecified,
* the new connection will use his_id.
- * If his_id is NULL, and c.that.id is uninstantiated (ID_NONE), the
+ * If his_id is NULL, and c.that.id is uninstantiated (ID_ANY), the
* new connection will continue to have an uninstantiated that.id.
* Note: instantiation does not affect port numbers.
*
@@ -1267,90 +1258,90 @@ instantiate(struct connection *c, const ip_address *him
, u_int16_t his_port
, const struct id *his_id)
{
- struct connection *d;
- int wildcards;
-
- passert(c->kind == CK_TEMPLATE);
- passert(c->spd.next == NULL);
-
- c->instance_serial++;
- d = clone_thing(*c, "temporary connection");
- d->spd.that.allow_any = FALSE;
-
- if (his_id != NULL)
- {
- passert(match_id(his_id, &d->spd.that.id, &wildcards));
- d->spd.that.id = *his_id;
- d->spd.that.has_id_wildcards = FALSE;
- }
- unshare_connection_strings(d);
- unshare_ietfAttrList(&d->spd.this.groups);
- unshare_ietfAttrList(&d->spd.that.groups);
- d->kind = CK_INSTANCE;
-
- passert(oriented(*d));
- d->spd.that.host_addr = *him;
- setportof(htons(c->spd.that.port), &d->spd.that.host_addr);
-
- if (his_port) d->spd.that.host_port = his_port;
-
- default_end(&d->spd.that, &d->spd.this.host_addr);
-
- /* We cannot guess what our next_hop should be, but if it was
- * explicitly specified as 0.0.0.0, we set it to be him.
- * (whack will not allow nexthop to be elided in RW case.)
- */
- default_end(&d->spd.this, &d->spd.that.host_addr);
- d->spd.next = NULL;
- d->spd.reqid = gen_reqid();
-
- /* set internal fields */
- d->ac_next = connections;
- connections = d;
- d->spd.routing = RT_UNROUTED;
- d->newest_isakmp_sa = SOS_NOBODY;
- d->newest_ipsec_sa = SOS_NOBODY;
- d->spd.eroute_owner = SOS_NOBODY;
-
- /* reset log file info */
- d->log_file_name = NULL;
- d->log_file = NULL;
- d->log_file_err = FALSE;
-
- connect_to_host_pair(d);
-
- return d;
- if (sameaddr(&d->spd.that.host_addr, &d->spd.this.host_nexthop))
- {
- d->spd.this.host_nexthop = *him;
- }
+ struct connection *d;
+ int wildcards;
+
+ passert(c->kind == CK_TEMPLATE);
+ passert(c->spd.next == NULL);
+
+ c->instance_serial++;
+ d = clone_thing(*c);
+ d->spd.that.allow_any = FALSE;
+
+ if (his_id != NULL)
+ {
+ passert(match_id(his_id, &d->spd.that.id, &wildcards));
+ d->spd.that.id = *his_id;
+ d->spd.that.has_id_wildcards = FALSE;
+ }
+ unshare_connection_strings(d);
+ unshare_ietfAttrList(&d->spd.this.groups);
+ unshare_ietfAttrList(&d->spd.that.groups);
+ d->kind = CK_INSTANCE;
+
+ passert(oriented(*d));
+ d->spd.that.host_addr = *him;
+ setportof(htons(c->spd.that.port), &d->spd.that.host_addr);
+
+ if (his_port) d->spd.that.host_port = his_port;
+
+ default_end(&d->spd.that, &d->spd.this.host_addr);
+
+ /* We cannot guess what our next_hop should be, but if it was
+ * explicitly specified as 0.0.0.0, we set it to be him.
+ * (whack will not allow nexthop to be elided in RW case.)
+ */
+ default_end(&d->spd.this, &d->spd.that.host_addr);
+ d->spd.next = NULL;
+ d->spd.reqid = gen_reqid();
+
+ /* set internal fields */
+ d->ac_next = connections;
+ connections = d;
+ d->spd.routing = RT_UNROUTED;
+ d->newest_isakmp_sa = SOS_NOBODY;
+ d->newest_ipsec_sa = SOS_NOBODY;
+ d->spd.eroute_owner = SOS_NOBODY;
+
+ /* reset log file info */
+ d->log_file_name = NULL;
+ d->log_file = NULL;
+ d->log_file_err = FALSE;
+
+ connect_to_host_pair(d);
+
+ return d;
+ if (sameaddr(&d->spd.that.host_addr, &d->spd.this.host_nexthop))
+ {
+ d->spd.this.host_nexthop = *him;
+ }
}
struct connection *
rw_instantiate(struct connection *c, const ip_address *him, u_int16_t his_port
, const ip_subnet *his_net, const struct id *his_id)
{
- struct connection *d = instantiate(c, him, his_port, his_id);
-
- if (d && his_net && is_virtual_connection(c))
- {
- d->spd.that.client = *his_net;
- d->spd.that.virt = NULL;
- if (subnetishost(his_net) && addrinsubnet(him, his_net))
- d->spd.that.has_client = FALSE;
- }
-
- if (d->policy & POLICY_OPPO)
- {
- /* This must be before we know the client addresses.
- * Fill in one that is impossible. This prevents anyone else from
- * trying to use this connection to get to a particular client
- */
- d->spd.that.client = *aftoinfo(subnettypeof(&d->spd.that.client))->none;
- }
- DBG(DBG_CONTROL
- , DBG_log("instantiated \"%s\" for %s" , d->name, ip_str(him)));
- return d;
+ struct connection *d = instantiate(c, him, his_port, his_id);
+
+ if (d && his_net && is_virtual_connection(c))
+ {
+ d->spd.that.client = *his_net;
+ d->spd.that.virt = NULL;
+ if (subnetishost(his_net) && addrinsubnet(him, his_net))
+ d->spd.that.has_client = FALSE;
+ }
+
+ if (d->policy & POLICY_OPPO)
+ {
+ /* This must be before we know the client addresses.
+ * Fill in one that is impossible. This prevents anyone else from
+ * trying to use this connection to get to a particular client
+ */
+ d->spd.that.client = *aftoinfo(subnettypeof(&d->spd.that.client))->none;
+ }
+ DBG(DBG_CONTROL
+ , DBG_log("instantiated \"%s\" for %s" , d->name, ip_str(him)));
+ return d;
}
struct connection *
@@ -1361,77 +1352,77 @@ oppo_instantiate(struct connection *c
, const ip_address *our_client USED_BY_DEBUG
, const ip_address *peer_client)
{
- struct connection *d = instantiate(c, him, 0, his_id);
+ struct connection *d = instantiate(c, him, 0, his_id);
- passert(d->spd.next == NULL);
+ passert(d->spd.next == NULL);
+
+ /* fill in our client side */
+ if (d->spd.this.has_client)
+ {
+ /* there was a client in the abstract connection
+ * so we demand that the required client is within that subnet.
+ */
+ passert(addrinsubnet(our_client, &d->spd.this.client));
+ happy(addrtosubnet(our_client, &d->spd.this.client));
+ /* opportunistic connections do not use port selectors */
+ setportof(0, &d->spd.this.client.addr);
+ }
+ else
+ {
+ /* there was no client in the abstract connection
+ * so we demand that the required client be the host
+ */
+ passert(sameaddr(our_client, &d->spd.this.host_addr));
+ }
- /* fill in our client side */
- if (d->spd.this.has_client)
- {
- /* there was a client in the abstract connection
- * so we demand that the required client is within that subnet.
+ /* fill in peer's client side.
+ * If the client is the peer, excise the client from the connection.
*/
- passert(addrinsubnet(our_client, &d->spd.this.client));
- happy(addrtosubnet(our_client, &d->spd.this.client));
+ passert((d->policy & POLICY_OPPO)
+ && addrinsubnet(peer_client, &d->spd.that.client));
+ happy(addrtosubnet(peer_client, &d->spd.that.client));
/* opportunistic connections do not use port selectors */
- setportof(0, &d->spd.this.client.addr);
- }
- else
- {
- /* there was no client in the abstract connection
- * so we demand that the required client be the host
+ setportof(0, &d->spd.that.client.addr);
+
+ if (sameaddr(peer_client, &d->spd.that.host_addr))
+ d->spd.that.has_client = FALSE;
+
+ passert(d->gw_info == NULL);
+ gw_addref(gw);
+ d->gw_info = gw;
+
+ /* Adjust routing if something is eclipsing c.
+ * It must be a %hold for us (hard to passert this).
+ * If there was another instance eclipsing, we'd be using it.
+ */
+ if (c->spd.routing == RT_ROUTED_ECLIPSED)
+ d->spd.routing = RT_ROUTED_PROSPECTIVE;
+
+ /* Remember if the template is routed:
+ * if so, this instance applies for initiation
+ * even if it is created for responding.
*/
- passert(sameaddr(our_client, &d->spd.this.host_addr));
- }
-
- /* fill in peer's client side.
- * If the client is the peer, excise the client from the connection.
- */
- passert((d->policy & POLICY_OPPO)
- && addrinsubnet(peer_client, &d->spd.that.client));
- happy(addrtosubnet(peer_client, &d->spd.that.client));
- /* opportunistic connections do not use port selectors */
- setportof(0, &d->spd.that.client.addr);
-
- if (sameaddr(peer_client, &d->spd.that.host_addr))
- d->spd.that.has_client = FALSE;
-
- passert(d->gw_info == NULL);
- gw_addref(gw);
- d->gw_info = gw;
-
- /* Adjust routing if something is eclipsing c.
- * It must be a %hold for us (hard to passert this).
- * If there was another instance eclipsing, we'd be using it.
- */
- if (c->spd.routing == RT_ROUTED_ECLIPSED)
- d->spd.routing = RT_ROUTED_PROSPECTIVE;
-
- /* Remember if the template is routed:
- * if so, this instance applies for initiation
- * even if it is created for responding.
- */
- if (routed(c->spd.routing))
- d->instance_initiation_ok = TRUE;
-
- DBG(DBG_CONTROL,
- char topo[CONNECTION_BUF];
-
- (void) format_connection(topo, sizeof(topo), d, &d->spd);
- DBG_log("instantiated \"%s\": %s", d->name, topo);
- );
- return d;
+ if (routed(c->spd.routing))
+ d->instance_initiation_ok = TRUE;
+
+ DBG(DBG_CONTROL,
+ char topo[CONNECTION_BUF];
+
+ (void) format_connection(topo, sizeof(topo), d, &d->spd);
+ DBG_log("instantiated \"%s\": %s", d->name, topo);
+ );
+ return d;
}
/* priority formatting */
void
fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
{
- if (pp == BOTTOM_PRIO)
- snprintf(buf, POLICY_PRIO_BUF, "0");
- else
- snprintf(buf, POLICY_PRIO_BUF, "%lu,%lu"
- , pp>>16, (pp & ~(~(policy_prio_t)0 << 16)) >> 8);
+ if (pp == BOTTOM_PRIO)
+ snprintf(buf, POLICY_PRIO_BUF, "0");
+ else
+ snprintf(buf, POLICY_PRIO_BUF, "%lu,%lu"
+ , pp>>16, (pp & ~(~(policy_prio_t)0 << 16)) >> 8);
}
/* Format any information needed to identify an instance of a connection.
@@ -1442,65 +1433,65 @@ fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
static size_t
fmt_client(const ip_subnet *client, const ip_address *gw, const char *prefix, char buf[ADDRTOT_BUF])
{
- if (subnetisaddr(client, gw))
- {
- buf[0] = '\0'; /* compact denotation for "self" */
- }
- else
- {
- char *ap;
-
- strcpy(buf, prefix);
- ap = buf + strlen(prefix);
- if (subnetisnone(client))
- strcpy(ap, "?"); /* unknown */
+ if (subnetisaddr(client, gw))
+ {
+ buf[0] = '\0'; /* compact denotation for "self" */
+ }
else
- subnettot(client, 0, ap, SUBNETTOT_BUF);
- }
- return strlen(buf);
+ {
+ char *ap;
+
+ strcpy(buf, prefix);
+ ap = buf + strlen(prefix);
+ if (subnetisnone(client))
+ strcpy(ap, "?"); /* unknown */
+ else
+ subnettot(client, 0, ap, SUBNETTOT_BUF);
+ }
+ return strlen(buf);
}
void
fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
{
- char *p = buf;
+ char *p = buf;
- *p = '\0';
+ *p = '\0';
- if (c->kind == CK_INSTANCE)
- {
- if (c->instance_serial != 0)
+ if (c->kind == CK_INSTANCE)
{
- snprintf(p, CONN_INST_BUF, "[%lu]", c->instance_serial);
- p += strlen(p);
- }
+ if (c->instance_serial != 0)
+ {
+ snprintf(p, CONN_INST_BUF, "[%lu]", c->instance_serial);
+ p += strlen(p);
+ }
- if (c->policy & POLICY_OPPO)
- {
- size_t w = fmt_client(&c->spd.this.client, &c->spd.this.host_addr, " ", p);
+ if (c->policy & POLICY_OPPO)
+ {
+ size_t w = fmt_client(&c->spd.this.client, &c->spd.this.host_addr, " ", p);
- p += w;
+ p += w;
- strcpy(p, w == 0? " ..." : "=== ...");
- p += strlen(p);
+ strcpy(p, w == 0? " ..." : "=== ...");
+ p += strlen(p);
- addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
- p += strlen(p);
+ addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
+ p += strlen(p);
- (void) fmt_client(&c->spd.that.client, &c->spd.that.host_addr, "===", p);
- }
- else
- {
- *p++ = ' ';
- addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
+ (void) fmt_client(&c->spd.that.client, &c->spd.that.host_addr, "===", p);
+ }
+ else
+ {
+ *p++ = ' ';
+ addrtot(&c->spd.that.host_addr, 0, p, ADDRTOT_BUF);
#
- if (c->spd.that.host_port != pluto_port)
- {
- p += strlen(p);
- sprintf(p, ":%d", c->spd.that.host_port);
- }
+ if (c->spd.that.host_port != pluto_port)
+ {
+ p += strlen(p);
+ sprintf(p, ":%d", c->spd.that.host_port);
+ }
+ }
}
- }
}
/* Find an existing connection for a trapped outbound packet.
@@ -1520,124 +1511,124 @@ fmt_conn_instance(const struct connection *c, char buf[CONN_INST_BUF])
*/
struct connection *
find_connection_for_clients(struct spd_route **srp,
- const ip_address *our_client,
- const ip_address *peer_client,
- int transport_proto)
+ const ip_address *our_client,
+ const ip_address *peer_client,
+ int transport_proto)
{
- struct connection *c = connections, *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- struct spd_route *sr;
- struct spd_route *best_sr = NULL;
- int our_port = ntohs(portof(our_client));
- int peer_port = ntohs(portof(peer_client));
-
- passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
+ struct connection *c = connections, *best = NULL;
+ policy_prio_t best_prio = BOTTOM_PRIO;
+ struct spd_route *sr;
+ struct spd_route *best_sr = NULL;
+ int our_port = ntohs(portof(our_client));
+ int peer_port = ntohs(portof(peer_client));
+
+ passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
#ifdef DEBUG
- if (DBGP(DBG_CONTROL))
- {
- char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
+ if (DBGP(DBG_CONTROL))
+ {
+ char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
- addrtot(our_client, 0, ocb, sizeof(ocb));
- addrtot(peer_client, 0, pcb, sizeof(pcb));
- DBG_log("find_connection: "
- "looking for policy for connection: %s:%d/%d -> %s:%d/%d"
- , ocb, transport_proto, our_port, pcb, transport_proto, peer_port);
- }
+ addrtot(our_client, 0, ocb, sizeof(ocb));
+ addrtot(peer_client, 0, pcb, sizeof(pcb));
+ DBG_log("find_connection: "
+ "looking for policy for connection: %s:%d/%d -> %s:%d/%d"
+ , ocb, transport_proto, our_port, pcb, transport_proto, peer_port);
+ }
#endif /* DEBUG */
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->kind == CK_GROUP)
- continue;
-
- for (sr = &c->spd; best!=c && sr; sr = sr->next)
+ for (c = connections; c != NULL; c = c->ac_next)
{
- if ((routed(sr->routing) || c->instance_initiation_ok)
- && addrinsubnet(our_client, &sr->this.client)
- && addrinsubnet(peer_client, &sr->that.client)
- && addrinsubnet(peer_client, &sr->that.client)
- && (!sr->this.protocol || transport_proto == sr->this.protocol)
- && (!sr->this.port || our_port == sr->this.port)
- && (!sr->that.port || peer_port == sr->that.port))
- {
- char cib[CONN_INST_BUF];
- char cib2[CONN_INST_BUF];
+ if (c->kind == CK_GROUP)
+ continue;
+
+ for (sr = &c->spd; best!=c && sr; sr = sr->next)
+ {
+ if ((routed(sr->routing) || c->instance_initiation_ok)
+ && addrinsubnet(our_client, &sr->this.client)
+ && addrinsubnet(peer_client, &sr->that.client)
+ && addrinsubnet(peer_client, &sr->that.client)
+ && (!sr->this.protocol || transport_proto == sr->this.protocol)
+ && (!sr->this.port || our_port == sr->this.port)
+ && (!sr->that.port || peer_port == sr->that.port))
+ {
+ char cib[CONN_INST_BUF];
+ char cib2[CONN_INST_BUF];
- policy_prio_t prio = 8 * (c->prio + (c->kind == CK_INSTANCE))
- + 2 * (sr->this.port == our_port)
- + 2 * (sr->that.port == peer_port)
- + (sr->this.protocol == transport_proto);
+ policy_prio_t prio = 8 * (c->prio + (c->kind == CK_INSTANCE))
+ + 2 * (sr->this.port == our_port)
+ + 2 * (sr->that.port == peer_port)
+ + (sr->this.protocol == transport_proto);
#ifdef DEBUG
- if (DBGP(DBG_CONTROL|DBG_CONTROLMORE))
- {
- char c_ocb[SUBNETTOT_BUF], c_pcb[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, c_ocb, sizeof(c_ocb));
- subnettot(&c->spd.that.client, 0, c_pcb, sizeof(c_pcb));
- DBG_log("find_connection: conn \"%s\"%s has compatible peers: %s->%s [pri: %ld]"
- , c->name
- , (fmt_conn_instance(c, cib), cib)
- , c_ocb, c_pcb, prio);
- }
+ if (DBGP(DBG_CONTROL|DBG_CONTROLMORE))
+ {
+ char c_ocb[SUBNETTOT_BUF], c_pcb[SUBNETTOT_BUF];
+
+ subnettot(&c->spd.this.client, 0, c_ocb, sizeof(c_ocb));
+ subnettot(&c->spd.that.client, 0, c_pcb, sizeof(c_pcb));
+ DBG_log("find_connection: conn \"%s\"%s has compatible peers: %s->%s [pri: %ld]"
+ , c->name
+ , (fmt_conn_instance(c, cib), cib)
+ , c_ocb, c_pcb, prio);
+ }
#endif /* DEBUG */
- if (best == NULL)
- {
- best = c;
- best_sr = sr;
- best_prio = prio;
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log("find_connection: "
- "comparing best \"%s\"%s [pri:%ld]{%p} (child %s) to \"%s\"%s [pri:%ld]{%p} (child %s)"
- , best->name
- , (fmt_conn_instance(best, cib), cib)
- , best_prio
- , best
- , (best->policy_next ? best->policy_next->name : "none")
- , c->name
- , (fmt_conn_instance(c, cib2), cib2)
- , prio
- , c
- , (c->policy_next ? c->policy_next->name : "none")));
-
- if (prio > best_prio)
- {
- best = c;
- best_sr = sr;
- best_prio = prio;
+ if (best == NULL)
+ {
+ best = c;
+ best_sr = sr;
+ best_prio = prio;
+ }
+
+ DBG(DBG_CONTROLMORE,
+ DBG_log("find_connection: "
+ "comparing best \"%s\"%s [pri:%ld]{%p} (child %s) to \"%s\"%s [pri:%ld]{%p} (child %s)"
+ , best->name
+ , (fmt_conn_instance(best, cib), cib)
+ , best_prio
+ , best
+ , (best->policy_next ? best->policy_next->name : "none")
+ , c->name
+ , (fmt_conn_instance(c, cib2), cib2)
+ , prio
+ , c
+ , (c->policy_next ? c->policy_next->name : "none")));
+
+ if (prio > best_prio)
+ {
+ best = c;
+ best_sr = sr;
+ best_prio = prio;
+ }
+ }
}
- }
}
- }
- if (best!= NULL && NEVER_NEGOTIATE(best->policy))
- best = NULL;
+ if (best!= NULL && NEVER_NEGOTIATE(best->policy))
+ best = NULL;
- if (srp != NULL && best != NULL)
- *srp = best_sr;
+ if (srp != NULL && best != NULL)
+ *srp = best_sr;
#ifdef DEBUG
- if (DBGP(DBG_CONTROL))
- {
- if (best)
+ if (DBGP(DBG_CONTROL))
{
- char cib[CONN_INST_BUF];
- DBG_log("find_connection: concluding with \"%s\"%s [pri:%ld]{%p} kind=%s"
- , best->name
- , (fmt_conn_instance(best, cib), cib)
- , best_prio
- , best
- , enum_name(&connection_kind_names, best->kind));
- } else {
- DBG_log("find_connection: concluding with empty");
+ if (best)
+ {
+ char cib[CONN_INST_BUF];
+ DBG_log("find_connection: concluding with \"%s\"%s [pri:%ld]{%p} kind=%s"
+ , best->name
+ , (fmt_conn_instance(best, cib), cib)
+ , best_prio
+ , best
+ , enum_name(&connection_kind_names, best->kind));
+ } else {
+ DBG_log("find_connection: concluding with empty");
+ }
}
- }
#endif /* DEBUG */
- return best;
+ return best;
}
/* Find and instantiate a connection for an outgoing Opportunistic connection.
@@ -1664,203 +1655,203 @@ find_connection_for_clients(struct spd_route **srp,
*/
struct connection *
build_outgoing_opportunistic_connection(struct gw_info *gw
- ,const ip_address *our_client
- ,const ip_address *peer_client)
+ ,const ip_address *our_client
+ ,const ip_address *peer_client)
{
- struct iface *p;
- struct connection *best = NULL;
- struct spd_route *sr, *bestsr;
- char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
-
- addrtot(our_client, 0, ocb, sizeof(ocb));
- addrtot(peer_client, 0, pcb, sizeof(pcb));
-
- passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
-
- /* We don't know his ID yet, so gw id must be an ipaddr */
- passert(gw->key != NULL);
- passert(id_is_ipaddr(&gw->gw_id));
-
- /* for each of our addresses... */
- for (p = interfaces; p != NULL; p = p->next)
- {
- /* go through those connections with our address and NO_IP as hosts
- * We cannot know what port the peer would use, so we assume
- * that it is pluto_port (makes debugging easier).
- */
- struct connection *c = find_host_pair_connections(&p->addr
- , pluto_port, (ip_address *)NULL, pluto_port);
+ struct iface *p;
+ struct connection *best = NULL;
+ struct spd_route *sr, *bestsr;
+ char ocb[ADDRTOT_BUF], pcb[ADDRTOT_BUF];
- for (; c != NULL; c = c->hp_next)
+ addrtot(our_client, 0, ocb, sizeof(ocb));
+ addrtot(peer_client, 0, pcb, sizeof(pcb));
+
+ passert(!isanyaddr(our_client) && !isanyaddr(peer_client));
+
+ /* We don't know his ID yet, so gw id must be an ipaddr */
+ passert(gw->key != NULL);
+ passert(id_is_ipaddr(&gw->gw_id));
+
+ /* for each of our addresses... */
+ for (p = interfaces; p != NULL; p = p->next)
{
- DBG(DBG_OPPO,
- DBG_log("checking %s", c->name));
- if (c->kind == CK_GROUP)
- {
- continue;
- }
-
- for (sr = &c->spd; best!=c && sr; sr = sr->next)
- {
- if (routed(sr->routing)
- && addrinsubnet(our_client, &sr->this.client)
- && addrinsubnet(peer_client, &sr->that.client))
+ /* go through those connections with our address and NO_IP as hosts
+ * We cannot know what port the peer would use, so we assume
+ * that it is pluto_port (makes debugging easier).
+ */
+ struct connection *c = find_host_pair_connections(&p->addr
+ , pluto_port, (ip_address *)NULL, pluto_port);
+
+ for (; c != NULL; c = c->hp_next)
{
- if (best == NULL)
- {
- best = c;
- break;
- }
-
- DBG(DBG_OPPO,
- DBG_log("comparing best %s to %s"
- , best->name, c->name));
-
- for (bestsr = &best->spd; best!=c && bestsr; bestsr=bestsr->next)
- {
- if (!subnetinsubnet(&bestsr->this.client, &sr->this.client)
- || (samesubnet(&bestsr->this.client, &sr->this.client)
- && !subnetinsubnet(&bestsr->that.client
- , &sr->that.client)))
+ DBG(DBG_OPPO,
+ DBG_log("checking %s", c->name));
+ if (c->kind == CK_GROUP)
{
- best = c;
+ continue;
+ }
+
+ for (sr = &c->spd; best!=c && sr; sr = sr->next)
+ {
+ if (routed(sr->routing)
+ && addrinsubnet(our_client, &sr->this.client)
+ && addrinsubnet(peer_client, &sr->that.client))
+ {
+ if (best == NULL)
+ {
+ best = c;
+ break;
+ }
+
+ DBG(DBG_OPPO,
+ DBG_log("comparing best %s to %s"
+ , best->name, c->name));
+
+ for (bestsr = &best->spd; best!=c && bestsr; bestsr=bestsr->next)
+ {
+ if (!subnetinsubnet(&bestsr->this.client, &sr->this.client)
+ || (samesubnet(&bestsr->this.client, &sr->this.client)
+ && !subnetinsubnet(&bestsr->that.client
+ , &sr->that.client)))
+ {
+ best = c;
+ }
+ }
+ }
}
- }
}
- }
}
- }
- if (best == NULL
- || NEVER_NEGOTIATE(best->policy)
- || (best->policy & POLICY_OPPO) == LEMPTY
- || best->kind != CK_TEMPLATE)
- return NULL;
- else
- return oppo_instantiate(best, &gw->gw_id.ip_addr, NULL, gw
- , our_client, peer_client);
+ if (best == NULL
+ || NEVER_NEGOTIATE(best->policy)
+ || (best->policy & POLICY_OPPO) == LEMPTY
+ || best->kind != CK_TEMPLATE)
+ return NULL;
+ else
+ return oppo_instantiate(best, &gw->gw_id.ip_addr, NULL, gw
+ , our_client, peer_client);
}
bool
orient(struct connection *c)
{
- struct spd_route *sr;
-
- if (!oriented(*c))
- {
- struct iface *p;
+ struct spd_route *sr;
- for (sr = &c->spd; sr; sr = sr->next)
+ if (!oriented(*c))
{
- /* Note: this loop does not stop when it finds a match:
- * it continues checking to catch any ambiguity.
- */
- for (p = interfaces; p != NULL; p = p->next)
- {
- if (p->ike_float)
- continue;
-
- for (;;)
+ struct iface *p;
+
+ for (sr = &c->spd; sr; sr = sr->next)
{
- /* check if this interface matches this end */
- if (sameaddr(&sr->this.host_addr, &p->addr)
- && (!no_klips || sr->this.host_port == pluto_port))
- {
- if (oriented(*c))
+ /* Note: this loop does not stop when it finds a match:
+ * it continues checking to catch any ambiguity.
+ */
+ for (p = interfaces; p != NULL; p = p->next)
{
- if (c->interface == p)
- loglog(RC_LOG_SERIOUS
- , "both sides of \"%s\" are our interface %s!"
- , c->name, p->rname);
- else
- loglog(RC_LOG_SERIOUS, "two interfaces match \"%s\" (%s, %s)"
- , c->name, c->interface->rname, p->rname);
- c->interface = NULL; /* withdraw orientation */
- return FALSE;
+ if (p->ike_float)
+ continue;
+
+ for (;;)
+ {
+ /* check if this interface matches this end */
+ if (sameaddr(&sr->this.host_addr, &p->addr)
+ && (!no_klips || sr->this.host_port == pluto_port))
+ {
+ if (oriented(*c))
+ {
+ if (c->interface == p)
+ loglog(RC_LOG_SERIOUS
+ , "both sides of \"%s\" are our interface %s!"
+ , c->name, p->rname);
+ else
+ loglog(RC_LOG_SERIOUS, "two interfaces match \"%s\" (%s, %s)"
+ , c->name, c->interface->rname, p->rname);
+ c->interface = NULL; /* withdraw orientation */
+ return FALSE;
+ }
+ c->interface = p;
+ }
+
+ /* done with this interface if it doesn't match that end */
+ if (!(sameaddr(&sr->that.host_addr, &p->addr)
+ && (!no_klips || sr->that.host_port == pluto_port)))
+ break;
+
+ /* swap ends and try again.
+ * It is a little tricky to see that this loop will stop.
+ * Only continue if the far side matches.
+ * If both sides match, there is an error-out.
+ */
+ {
+ struct end t = sr->this;
+
+ sr->this = sr->that;
+ sr->that = t;
+ }
+ }
}
- c->interface = p;
- }
-
- /* done with this interface if it doesn't match that end */
- if (!(sameaddr(&sr->that.host_addr, &p->addr)
- && (!no_klips || sr->that.host_port == pluto_port)))
- break;
-
- /* swap ends and try again.
- * It is a little tricky to see that this loop will stop.
- * Only continue if the far side matches.
- * If both sides match, there is an error-out.
- */
- {
- struct end t = sr->this;
-
- sr->this = sr->that;
- sr->that = t;
- }
}
- }
}
- }
- return oriented(*c);
+ return oriented(*c);
}
void
initiate_connection(const char *name, int whackfd)
{
- struct connection *c = con_by_name(name, TRUE);
+ struct connection *c = con_by_name(name, TRUE);
- if (c != NULL && c->ikev1)
- {
- set_cur_connection(c);
- if (!oriented(*c))
- {
- loglog(RC_ORIENT, "we have no ipsecN interface for either end of this connection");
- }
- else if (NEVER_NEGOTIATE(c->policy))
- {
- loglog(RC_INITSHUNT
- , "cannot initiate an authby=never connection");
- }
- else if (c->kind != CK_PERMANENT && !c->spd.that.allow_any)
- {
- if (isanyaddr(&c->spd.that.host_addr))
- loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address");
- else
- loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards");
- }
- else
+ if (c != NULL && c->ikev1)
{
- /* do we have to prompt for a PIN code? */
- if (c->spd.this.sc != NULL && !c->spd.this.sc->valid && whackfd != NULL_FD)
- {
- scx_get_pin(c->spd.this.sc, whackfd);
- }
- if (c->spd.this.sc != NULL && !c->spd.this.sc->valid)
- {
- loglog(RC_NOVALIDPIN, "cannot initiate connection without valid PIN");
- }
- else
- {
-
- if (c->spd.that.allow_any)
+ set_cur_connection(c);
+ if (!oriented(*c))
+ {
+ loglog(RC_ORIENT, "we have no ipsecN interface for either end of this connection");
+ }
+ else if (NEVER_NEGOTIATE(c->policy))
+ {
+ loglog(RC_INITSHUNT
+ , "cannot initiate an authby=never connection");
+ }
+ else if (c->kind != CK_PERMANENT && !c->spd.that.allow_any)
{
- c = instantiate(c, &c->spd.that.host_addr, c->spd.that.host_port
- , &c->spd.that.id);
+ if (isanyaddr(&c->spd.that.host_addr))
+ loglog(RC_NOPEERIP, "cannot initiate connection without knowing peer IP address");
+ else
+ loglog(RC_WILDCARD, "cannot initiate connection with ID wildcards");
}
+ else
+ {
+ /* do we have to prompt for a PIN code? */
+ if (c->spd.this.sc != NULL && !c->spd.this.sc->valid && whackfd != NULL_FD)
+ {
+ scx_get_pin(c->spd.this.sc, whackfd);
+ }
+ if (c->spd.this.sc != NULL && !c->spd.this.sc->valid)
+ {
+ loglog(RC_NOVALIDPIN, "cannot initiate connection without valid PIN");
+ }
+ else
+ {
- /* We will only request an IPsec SA if policy isn't empty
- * (ignoring Main Mode items).
- * This is a fudge, but not yet important.
- * If we are to proceed asynchronously, whackfd will be NULL_FD.
- */
- c->policy |= POLICY_UP;
- ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY);
- whackfd = NULL_FD; /* protect from close */
- }
+ if (c->spd.that.allow_any)
+ {
+ c = instantiate(c, &c->spd.that.host_addr, c->spd.that.host_port
+ , &c->spd.that.id);
+ }
+
+ /* We will only request an IPsec SA if policy isn't empty
+ * (ignoring Main Mode items).
+ * This is a fudge, but not yet important.
+ * If we are to proceed asynchronously, whackfd will be NULL_FD.
+ */
+ c->policy |= POLICY_UP;
+ ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY);
+ whackfd = NULL_FD; /* protect from close */
+ }
+ }
+ reset_cur_connection();
}
- reset_cur_connection();
- }
- close_any(whackfd);
+ close_any(whackfd);
}
/* (Possibly) Opportunistic Initiation:
@@ -1874,10 +1865,10 @@ initiate_connection(const char *name, int whackfd)
* Most of the code will be restarted if an ADNS request is made
* to discover the gateway. The only difference between the first
* and second entry is whether gateways_from_dns is NULL or not.
- * initiate_opportunistic: initial entrypoint
- * continue_oppo: where we pickup when ADNS result arrives
- * initiate_opportunistic_body: main body shared by above routines
- * cannot_oppo: a helper function to log a diagnostic
+ * initiate_opportunistic: initial entrypoint
+ * continue_oppo: where we pickup when ADNS result arrives
+ * initiate_opportunistic_body: main body shared by above routines
+ * cannot_oppo: a helper function to log a diagnostic
* This structure repeats a lot of code when the ADNS result arrives.
* This seems like a waste, but anything learned the first time through
* may no longer be true!
@@ -1887,174 +1878,174 @@ initiate_connection(const char *name, int whackfd)
*/
enum find_oppo_step {
- fos_start,
- fos_myid_ip_txt,
- fos_myid_hostname_txt,
- fos_myid_ip_key,
- fos_myid_hostname_key,
- fos_our_client,
- fos_our_txt,
+ fos_start,
+ fos_myid_ip_txt,
+ fos_myid_hostname_txt,
+ fos_myid_ip_key,
+ fos_myid_hostname_key,
+ fos_our_client,
+ fos_our_txt,
#ifdef USE_KEYRR
- fos_our_key,
+ fos_our_key,
#endif /* USE_KEYRR */
- fos_his_client,
- fos_done
+ fos_his_client,
+ fos_done
};
#ifdef DEBUG
static const char *const oppo_step_name[] = {
- "fos_start",
- "fos_myid_ip_txt",
- "fos_myid_hostname_txt",
- "fos_myid_ip_key",
- "fos_myid_hostname_key",
- "fos_our_client",
- "fos_our_txt",
+ "fos_start",
+ "fos_myid_ip_txt",
+ "fos_myid_hostname_txt",
+ "fos_myid_ip_key",
+ "fos_myid_hostname_key",
+ "fos_our_client",
+ "fos_our_txt",
#ifdef USE_KEYRR
- "fos_our_key",
+ "fos_our_key",
#endif /* USE_KEYRR */
- "fos_his_client",
- "fos_done"
+ "fos_his_client",
+ "fos_done"
};
#endif /* DEBUG */
struct find_oppo_bundle {
- enum find_oppo_step step;
- err_t want;
- bool failure_ok; /* if true, continue_oppo should not die on DNS failure */
- ip_address our_client; /* not pointer! */
- ip_address peer_client;
- int transport_proto;
- bool held;
- policy_prio_t policy_prio;
- ipsec_spi_t failure_shunt; /* in host order! 0 for delete. */
- int whackfd;
+ enum find_oppo_step step;
+ err_t want;
+ bool failure_ok; /* if true, continue_oppo should not die on DNS failure */
+ ip_address our_client; /* not pointer! */
+ ip_address peer_client;
+ int transport_proto;
+ bool held;
+ policy_prio_t policy_prio;
+ ipsec_spi_t failure_shunt; /* in host order! 0 for delete. */
+ int whackfd;
};
struct find_oppo_continuation {
- struct adns_continuation ac; /* common prefix */
- struct find_oppo_bundle b;
+ struct adns_continuation ac; /* common prefix */
+ struct find_oppo_bundle b;
};
static void
cannot_oppo(struct connection *c
- , struct find_oppo_bundle *b
- , err_t ugh)
+ , struct find_oppo_bundle *b
+ , err_t ugh)
{
- char pcb[ADDRTOT_BUF];
- char ocb[ADDRTOT_BUF];
+ char pcb[ADDRTOT_BUF];
+ char ocb[ADDRTOT_BUF];
- addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
- addrtot(&b->our_client, 0, ocb, sizeof(ocb));
+ addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
+ addrtot(&b->our_client, 0, ocb, sizeof(ocb));
- DBG(DBG_DNS | DBG_OPPO, DBG_log("Can't Opportunistically initiate for %s to %s: %s"
- , ocb, pcb, ugh));
+ DBG(DBG_DNS | DBG_OPPO, DBG_log("Can't Opportunistically initiate for %s to %s: %s"
+ , ocb, pcb, ugh));
- whack_log(RC_OPPOFAILURE
- , "Can't Opportunistically initiate for %s to %s: %s"
- , ocb, pcb, ugh);
+ whack_log(RC_OPPOFAILURE
+ , "Can't Opportunistically initiate for %s to %s: %s"
+ , ocb, pcb, ugh);
- if (c != NULL && c->policy_next != NULL)
- {
- /* there is some policy that comes afterwards */
- struct spd_route *shunt_spd;
- struct connection *nc = c->policy_next;
- struct state *st;
+ if (c != NULL && c->policy_next != NULL)
+ {
+ /* there is some policy that comes afterwards */
+ struct spd_route *shunt_spd;
+ struct connection *nc = c->policy_next;
+ struct state *st;
- passert(c->kind == CK_TEMPLATE);
- passert(c->policy_next->kind == CK_PERMANENT);
+ passert(c->kind == CK_TEMPLATE);
+ passert(c->policy_next->kind == CK_PERMANENT);
- DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt"
- , ocb, pcb, c->policy_next->name));
+ DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt"
+ , ocb, pcb, c->policy_next->name));
- /*
- * okay, here we need add to the "next" policy, which is ought
- * to be an instance.
- * We will add another entry to the spd_route list for the specific
- * situation that we have.
- */
+ /*
+ * okay, here we need add to the "next" policy, which is ought
+ * to be an instance.
+ * We will add another entry to the spd_route list for the specific
+ * situation that we have.
+ */
- shunt_spd = clone_thing(nc->spd, "shunt eroute policy");
+ shunt_spd = clone_thing(nc->spd);
- shunt_spd->next = nc->spd.next;
- nc->spd.next = shunt_spd;
+ shunt_spd->next = nc->spd.next;
+ nc->spd.next = shunt_spd;
- happy(addrtosubnet(&b->peer_client, &shunt_spd->that.client));
+ happy(addrtosubnet(&b->peer_client, &shunt_spd->that.client));
- if (sameaddr(&b->peer_client, &shunt_spd->that.host_addr))
- shunt_spd->that.has_client = FALSE;
+ if (sameaddr(&b->peer_client, &shunt_spd->that.host_addr))
+ shunt_spd->that.has_client = FALSE;
- /*
- * override the tunnel destination with the one from the secondaried
- * policy
- */
- shunt_spd->that.host_addr = nc->spd.that.host_addr;
+ /*
+ * override the tunnel destination with the one from the secondaried
+ * policy
+ */
+ shunt_spd->that.host_addr = nc->spd.that.host_addr;
- /* now, lookup the state, and poke it up.
- */
+ /* now, lookup the state, and poke it up.
+ */
- st = state_with_serialno(nc->newest_ipsec_sa);
+ st = state_with_serialno(nc->newest_ipsec_sa);
- /* XXX what to do if the IPSEC SA has died? */
- passert(st != NULL);
+ /* XXX what to do if the IPSEC SA has died? */
+ passert(st != NULL);
- /* link the new connection instance to the state's list of
- * connections
- */
+ /* link the new connection instance to the state's list of
+ * connections
+ */
- DBG(DBG_OPPO, DBG_log("installing state: %ld for %s to %s"
- , nc->newest_ipsec_sa
- , ocb, pcb));
+ DBG(DBG_OPPO, DBG_log("installing state: %ld for %s to %s"
+ , nc->newest_ipsec_sa
+ , ocb, pcb));
#ifdef DEBUG
- if (DBGP(DBG_OPPO | DBG_CONTROLMORE))
- {
- char state_buf[LOG_WIDTH];
- char state_buf2[LOG_WIDTH];
- time_t n = now();
-
- fmt_state(FALSE, st, n
- , state_buf, sizeof(state_buf)
- , state_buf2, sizeof(state_buf2));
- DBG_log("cannot_oppo, failure SA1: %s", state_buf);
- DBG_log("cannot_oppo, failure SA2: %s", state_buf2);
- }
+ if (DBGP(DBG_OPPO | DBG_CONTROLMORE))
+ {
+ char state_buf[LOG_WIDTH];
+ char state_buf2[LOG_WIDTH];
+ time_t n = now();
+
+ fmt_state(FALSE, st, n
+ , state_buf, sizeof(state_buf)
+ , state_buf2, sizeof(state_buf2));
+ DBG_log("cannot_oppo, failure SA1: %s", state_buf);
+ DBG_log("cannot_oppo, failure SA2: %s", state_buf2);
+ }
#endif /* DEBUG */
- if (!route_and_eroute(c, shunt_spd, st))
- {
- whack_log(RC_OPPOFAILURE
- , "failed to instantiate shunt policy %s for %s to %s"
- , c->name
- , ocb, pcb);
+ if (!route_and_eroute(c, shunt_spd, st))
+ {
+ whack_log(RC_OPPOFAILURE
+ , "failed to instantiate shunt policy %s for %s to %s"
+ , c->name
+ , ocb, pcb);
+ }
+ return;
}
- return;
- }
#ifdef KLIPS
- if (b->held)
- {
- /* Replace HOLD with b->failure_shunt.
- * If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
- */
- if (b->failure_shunt == 0)
+ if (b->held)
{
- DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass"
- , ocb, pcb));
- }
+ /* Replace HOLD with b->failure_shunt.
+ * If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
+ */
+ if (b->failure_shunt == 0)
+ {
+ DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass"
+ , ocb, pcb));
+ }
- (void) replace_bare_shunt(&b->our_client, &b->peer_client
- , b->policy_prio
- , b->failure_shunt
- , b->failure_shunt != 0
- , b->transport_proto
- , ugh);
- }
+ (void) replace_bare_shunt(&b->our_client, &b->peer_client
+ , b->policy_prio
+ , b->failure_shunt
+ , b->failure_shunt != 0
+ , b->transport_proto
+ , ugh);
+ }
#endif
}
static void initiate_opportunistic_body(struct find_oppo_bundle *b
- , struct adns_continuation *ac, err_t ac_ugh); /* forward */
+ , struct adns_continuation *ac, err_t ac_ugh); /* forward */
void
initiate_opportunistic(const ip_address *our_client
@@ -2063,93 +2054,93 @@ initiate_opportunistic(const ip_address *our_client
, bool held
, int whackfd)
{
- struct find_oppo_bundle b;
-
- b.want = (whackfd == NULL_FD ? "whack" : "acquire");
- b.failure_ok = FALSE;
- b.our_client = *our_client;
- b.peer_client = *peer_client;
- b.transport_proto = transport_proto;
- b.held = held;
- b.policy_prio = BOTTOM_PRIO;
- b.failure_shunt = 0;
- b.whackfd = whackfd;
- b.step = fos_start;
- initiate_opportunistic_body(&b, NULL, NULL);
+ struct find_oppo_bundle b;
+
+ b.want = (whackfd == NULL_FD ? "whack" : "acquire");
+ b.failure_ok = FALSE;
+ b.our_client = *our_client;
+ b.peer_client = *peer_client;
+ b.transport_proto = transport_proto;
+ b.held = held;
+ b.policy_prio = BOTTOM_PRIO;
+ b.failure_shunt = 0;
+ b.whackfd = whackfd;
+ b.step = fos_start;
+ initiate_opportunistic_body(&b, NULL, NULL);
}
static void
continue_oppo(struct adns_continuation *acr, err_t ugh)
{
- struct find_oppo_continuation *cr = (void *)acr; /* inherit, damn you! */
- struct connection *c;
- bool was_held = cr->b.held;
- int whackfd = cr->b.whackfd;
+ struct find_oppo_continuation *cr = (void *)acr; /* inherit, damn you! */
+ struct connection *c;
+ bool was_held = cr->b.held;
+ int whackfd = cr->b.whackfd;
- /* note: cr->id has no resources; cr->sgw_id is id_none:
- * neither need freeing.
- */
- whack_log_fd = whackfd;
+ /* note: cr->id has no resources; cr->sgw_id is ID_ANY:
+ * neither need freeing.
+ */
+ whack_log_fd = whackfd;
#ifdef KLIPS
- /* Discover and record whether %hold has gone away.
- * This could have happened while we were awaiting DNS.
- * We must check BEFORE any call to cannot_oppo.
- */
- if (was_held)
- cr->b.held = has_bare_hold(&cr->b.our_client, &cr->b.peer_client
- , cr->b.transport_proto);
+ /* Discover and record whether %hold has gone away.
+ * This could have happened while we were awaiting DNS.
+ * We must check BEFORE any call to cannot_oppo.
+ */
+ if (was_held)
+ cr->b.held = has_bare_hold(&cr->b.our_client, &cr->b.peer_client
+ , cr->b.transport_proto);
#endif
#ifdef DEBUG
- /* if we're going to ignore the error, at least note it in debugging log */
- if (cr->b.failure_ok && ugh != NULL)
- {
- DBG(DBG_CONTROL | DBG_DNS,
- {
+ /* if we're going to ignore the error, at least note it in debugging log */
+ if (cr->b.failure_ok && ugh != NULL)
+ {
+ DBG(DBG_CONTROL | DBG_DNS,
+ {
+ char ocb[ADDRTOT_BUF];
+ char pcb[ADDRTOT_BUF];
+
+ addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
+ addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
+ DBG_log("continuing from failed DNS lookup for %s, %s to %s: %s"
+ , cr->b.want, ocb, pcb, ugh);
+ });
+ }
+#endif
+
+ if (!cr->b.failure_ok && ugh != NULL)
+ {
+ c = find_connection_for_clients(NULL, &cr->b.our_client, &cr->b.peer_client
+ , cr->b.transport_proto);
+ cannot_oppo(c, &cr->b
+ , builddiag("%s: %s", cr->b.want, ugh));
+ }
+ else if (was_held && !cr->b.held)
+ {
+ /* was_held indicates we were started due to a %trap firing
+ * (as opposed to a "whack --oppohere --oppothere").
+ * Since the %hold has gone, we can assume that somebody else
+ * has beaten us to the punch. We can go home. But lets log it.
+ */
char ocb[ADDRTOT_BUF];
char pcb[ADDRTOT_BUF];
addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
- DBG_log("continuing from failed DNS lookup for %s, %s to %s: %s"
- , cr->b.want, ocb, pcb, ugh);
- });
- }
-#endif
- if (!cr->b.failure_ok && ugh != NULL)
- {
- c = find_connection_for_clients(NULL, &cr->b.our_client, &cr->b.peer_client
- , cr->b.transport_proto);
- cannot_oppo(c, &cr->b
- , builddiag("%s: %s", cr->b.want, ugh));
- }
- else if (was_held && !cr->b.held)
- {
- /* was_held indicates we were started due to a %trap firing
- * (as opposed to a "whack --oppohere --oppothere").
- * Since the %hold has gone, we can assume that somebody else
- * has beaten us to the punch. We can go home. But lets log it.
- */
- char ocb[ADDRTOT_BUF];
- char pcb[ADDRTOT_BUF];
+ loglog(RC_COMMENT
+ , "%%hold otherwise handled during DNS lookup for Opportunistic Initiation for %s to %s"
+ , ocb, pcb);
+ }
+ else
+ {
+ initiate_opportunistic_body(&cr->b, &cr->ac, ugh);
+ whackfd = NULL_FD; /* was handed off */
+ }
- addrtot(&cr->b.our_client, 0, ocb, sizeof(ocb));
- addrtot(&cr->b.peer_client, 0, pcb, sizeof(pcb));
-
- loglog(RC_COMMENT
- , "%%hold otherwise handled during DNS lookup for Opportunistic Initiation for %s to %s"
- , ocb, pcb);
- }
- else
- {
- initiate_opportunistic_body(&cr->b, &cr->ac, ugh);
- whackfd = NULL_FD; /* was handed off */
- }
-
- whack_log_fd = NULL_FD;
- close_any(whackfd);
+ whack_log_fd = NULL_FD;
+ close_any(whackfd);
}
#ifdef USE_KEYRR
@@ -2158,110 +2149,112 @@ check_key_recs(enum myid_state try_state
, const struct connection *c
, struct adns_continuation *ac)
{
- /* Check if KEY lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- enum myid_state old_myid_state = myid_state;
- const struct RSA_private_key *our_RSA_pri;
- err_t ugh = NULL;
-
- myid_state = try_state;
-
- if (old_myid_state != myid_state
- && old_myid_state == MYID_SPECIFIED)
- {
- ugh = "%myid was specified while we were guessing";
- }
- else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
+ /* Check if KEY lookup yielded good results.
+ * Looking up based on our ID. Used if
+ * client is ourself, or if TXT had no public key.
+ * Note: if c is different this time, there is
+ * a chance that we did the wrong query.
+ * If so, treat as a kind of failure.
*/
- pubkey_list_t *kr;
+ enum myid_state old_myid_state = myid_state;
+ private_key_t *private;
+ err_t ugh = NULL;
- ugh = "no KEY RR found for us";
- for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
+ myid_state = try_state;
+
+ if (old_myid_state != myid_state && old_myid_state == MYID_SPECIFIED)
{
- ugh = "all our KEY RRs have the wrong public key";
- if (kr->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
+ ugh = "%myid was specified while we were guessing";
+ }
+ else if ((private = get_private_key(c)) == NULL)
+ {
+ ugh = "we don't know our own RSA key";
}
- }
- if (ugh != NULL)
- myid_state = old_myid_state;
- return ugh;
+ else if (!same_id(&ac->id, &c->spd.this.id))
+ {
+ ugh = "our ID changed underfoot";
+ }
+ else
+ {
+ /* Similar to code in RSA_check_signature
+ * for checking the other side.
+ */
+ pubkey_list_t *kr;
+
+ ugh = "no KEY RR found for us";
+ for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
+ {
+ ugh = "all our KEY RRs have the wrong public key";
+ if (kr->key->alg == PUBKEY_ALG_RSA
+ && private->belongs_to(private, &kr->key->public_key))
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
+ if (ugh != NULL)
+ myid_state = old_myid_state;
+ return ugh;
}
#endif /* USE_KEYRR */
-static err_t
-check_txt_recs(enum myid_state try_state
-, const struct connection *c
-, struct adns_continuation *ac)
+static err_t check_txt_recs(enum myid_state try_state,
+ const struct connection *c,
+ struct adns_continuation *ac)
{
- /* Check if TXT lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- enum myid_state old_myid_state = myid_state;
- const struct RSA_private_key *our_RSA_pri;
- err_t ugh = NULL;
-
- myid_state = try_state;
-
- if (old_myid_state != myid_state
- && old_myid_state == MYID_SPECIFIED)
- {
- ugh = "%myid was specified while we were guessing";
- }
- else if ((our_RSA_pri = get_RSA_private_key(c)) == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
+ /* Check if TXT lookup yielded good results.
+ * Looking up based on our ID. Used if
+ * client is ourself, or if TXT had no public key.
+ * Note: if c is different this time, there is
+ * a chance that we did the wrong query.
+ * If so, treat as a kind of failure.
*/
- struct gw_info *gwp;
+ enum myid_state old_myid_state = myid_state;
+ private_key_t *private;
+ err_t ugh = NULL;
+
+ myid_state = try_state;
- ugh = "no TXT RR found for us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ if (old_myid_state != myid_state
+ && old_myid_state == MYID_SPECIFIED)
{
- ugh = "all our TXT RRs have the wrong public key";
- if (gwp->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
+ ugh = "%myid was specified while we were guessing";
+ }
+ else if ((private = get_private_key(c)) == NULL)
+ {
+ ugh = "we don't know our own RSA key";
}
- }
- if (ugh != NULL)
- myid_state = old_myid_state;
- return ugh;
+ else if (!same_id(&ac->id, &c->spd.this.id))
+ {
+ ugh = "our ID changed underfoot";
+ }
+ else
+ {
+ /* Similar to code in RSA_check_signature
+ * for checking the other side.
+ */
+ struct gw_info *gwp;
+
+ ugh = "no TXT RR found for us";
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ public_key_t *pub_key = gwp->key->public_key;
+
+ ugh = "all our TXT RRs have the wrong public key";
+ if (pub_key->get_type(pub_key) == KEY_RSA &&
+ private->belongs_to(private, pub_key))
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
+ if (ugh != NULL)
+ {
+ myid_state = old_myid_state;
+ }
+ return ugh;
}
@@ -2271,776 +2264,775 @@ initiate_opportunistic_body(struct find_oppo_bundle *b
, struct adns_continuation *ac
, err_t ac_ugh)
{
- struct connection *c;
- struct spd_route *sr;
+ struct connection *c;
+ struct spd_route *sr;
- /* What connection shall we use?
- * First try for one that explicitly handles the clients.
- */
- DBG(DBG_CONTROL,
- {
- char ours[ADDRTOT_BUF];
- char his[ADDRTOT_BUF];
- int ourport;
- int hisport;
-
- addrtot(&b->our_client, 0, ours, sizeof(ours));
- addrtot(&b->peer_client, 0, his, sizeof(his));
- ourport = ntohs(portof(&b->our_client));
- hisport = ntohs(portof(&b->peer_client));
- DBG_log("initiate on demand from %s:%d to %s:%d proto=%d state: %s because: %s"
- , ours, ourport, his, hisport, b->transport_proto
- , oppo_step_name[b->step], b->want);
- });
- if (isanyaddr(&b->our_client) || isanyaddr(&b->peer_client))
- {
- cannot_oppo(NULL, b, "impossible IP address");
- }
- else if ((c = find_connection_for_clients(&sr
- , &b->our_client
- , &b->peer_client
- , b->transport_proto)) == NULL)
- {
- /* No connection explicitly handles the clients and there
- * are no Opportunistic connections -- whine and give up.
- * The failure policy cannot be gotten from a connection; we pick %pass.
- */
- cannot_oppo(NULL, b, "no routed Opportunistic template covers this pair");
- }
- else if (c->kind != CK_TEMPLATE)
- {
- /* We've found a connection that can serve.
- * Do we have to initiate it?
- * Not if there is currently an IPSEC SA.
- * But if there is an IPSEC SA, then KLIPS would not
- * have generated the acquire. So we assume that there isn't one.
- * This may be redundant if a non-opportunistic
- * negotiation is already being attempted.
+ /* What connection shall we use?
+ * First try for one that explicitly handles the clients.
*/
-
- /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
-
- if(c->kind == CK_INSTANCE)
+ DBG(DBG_CONTROL,
+ {
+ char ours[ADDRTOT_BUF];
+ char his[ADDRTOT_BUF];
+ int ourport;
+ int hisport;
+
+ addrtot(&b->our_client, 0, ours, sizeof(ours));
+ addrtot(&b->peer_client, 0, his, sizeof(his));
+ ourport = ntohs(portof(&b->our_client));
+ hisport = ntohs(portof(&b->peer_client));
+ DBG_log("initiate on demand from %s:%d to %s:%d proto=%d state: %s because: %s"
+ , ours, ourport, his, hisport, b->transport_proto
+ , oppo_step_name[b->step], b->want);
+ });
+ if (isanyaddr(&b->our_client) || isanyaddr(&b->peer_client))
{
- char cib[CONN_INST_BUF];
- /* there is already an instance being negotiated, no nothing */
- DBG(DBG_CONTROL, DBG_log("found existing instance \"%s\"%s, rekeying it"
- , c->name
- , (fmt_conn_instance(c, cib), cib)));
- /* XXX-mcr - return; */
+ cannot_oppo(NULL, b, "impossible IP address");
}
-
- /* otherwise, there is some kind of static conn that can handle
- * this connection, so we initiate it */
-
-#ifdef KLIPS
- if (b->held)
+ else if ((c = find_connection_for_clients(&sr
+ , &b->our_client
+ , &b->peer_client
+ , b->transport_proto)) == NULL)
{
- /* what should we do on failure? */
- (void) assign_hold(c, sr, b->transport_proto, &b->our_client, &b->peer_client);
+ /* No connection explicitly handles the clients and there
+ * are no Opportunistic connections -- whine and give up.
+ * The failure policy cannot be gotten from a connection; we pick %pass.
+ */
+ cannot_oppo(NULL, b, "no routed Opportunistic template covers this pair");
}
-#endif
- ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
- b->whackfd = NULL_FD; /* protect from close */
- }
- else
- {
- /* We are handling an opportunistic situation.
- * This involves several DNS lookup steps that require suspension.
- * Note: many facts might change while we're suspended.
- * Here be dragons.
- *
- * The first chunk of code handles the result of the previous
- * DNS query (if any). It also selects the kind of the next step.
- * The second chunk initiates the next DNS query (if any).
- */
- enum find_oppo_step next_step = fos_myid_ip_txt;
- err_t ugh = ac_ugh;
- char mycredentialstr[BUF_LEN];
- char cib[CONN_INST_BUF];
-
- DBG(DBG_CONTROL, DBG_log("creating new instance from \"%s\"%s"
- , c->name
- , (fmt_conn_instance(c, cib), cib)));
-
-
- idtoa(&sr->this.id, mycredentialstr, sizeof(mycredentialstr));
-
- passert(c->policy & POLICY_OPPO); /* can't initiate Road Warrior connections */
-
- /* handle any DNS answer; select next step */
-
- switch (b->step)
+ else if (c->kind != CK_TEMPLATE)
{
- case fos_start:
- /* just starting out: select first query step */
- next_step = fos_myid_ip_txt;
- break;
-
- case fos_myid_ip_txt: /* TXT for our default IP address as %myid */
- ugh = check_txt_recs(MYID_IP, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our IP (%s:TXT) as identity: %s"
- , myid_str[MYID_IP]
- , ugh));
- if (!logged_myid_ip_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our IP (%s:TXT) as identity: %s"
- , myid_str[MYID_IP]
- , ugh);
- logged_myid_ip_txt_warning = TRUE;
- }
-
- next_step = fos_myid_hostname_txt;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_ip_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our IP (%s:TXT) as identity!"
- , myid_str[MYID_IP]);
- logged_myid_ip_txt_warning = TRUE;
- }
+ /* We've found a connection that can serve.
+ * Do we have to initiate it?
+ * Not if there is currently an IPSEC SA.
+ * But if there is an IPSEC SA, then KLIPS would not
+ * have generated the acquire. So we assume that there isn't one.
+ * This may be redundant if a non-opportunistic
+ * negotiation is already being attempted.
+ */
- next_step = fos_our_client;
- }
- break;
-
- case fos_myid_hostname_txt: /* TXT for our hostname as %myid */
- ugh = check_txt_recs(MYID_HOSTNAME, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our hostname as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:TXT) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh));
- if (!logged_myid_fqdn_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our hostname (%s:TXT) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh);
- logged_myid_fqdn_txt_warning = TRUE;
- }
-#ifdef USE_KEYRR
- next_step = fos_myid_ip_key;
- ugh = NULL; /* failure can be recovered from */
-#endif
- }
- else
- {
- /* we can use our hostname as OE identity for initiation */
- if (!logged_myid_fqdn_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our hostname (%s:TXT) as identity!"
- , myid_str[MYID_HOSTNAME]);
- logged_myid_fqdn_txt_warning = TRUE;
- }
- next_step = fos_our_client;
- }
- break;
+ /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
-#ifdef USE_KEYRR
- case fos_myid_ip_key: /* KEY for our default IP address as %myid */
- ugh = check_key_recs(MYID_IP, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our IP (%s:KEY) as identity: %s"
- , myid_str[MYID_IP]
- , ugh));
- if (!logged_myid_ip_key_warning)
+ if(c->kind == CK_INSTANCE)
{
- loglog(RC_LOG_SERIOUS
- , "can not use our IP (%s:KEY) as identity: %s"
- , myid_str[MYID_IP]
- , ugh);
- logged_myid_ip_key_warning = TRUE;
+ char cib[CONN_INST_BUF];
+ /* there is already an instance being negotiated, no nothing */
+ DBG(DBG_CONTROL, DBG_log("found existing instance \"%s\"%s, rekeying it"
+ , c->name
+ , (fmt_conn_instance(c, cib), cib)));
+ /* XXX-mcr - return; */
}
- next_step = fos_myid_hostname_key;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_ip_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "using our IP (%s:KEY) as identity!"
- , myid_str[MYID_IP]);
- logged_myid_ip_key_warning = TRUE;
- }
- next_step = fos_our_client;
- }
- break;
-
- case fos_myid_hostname_key: /* KEY for our hostname as %myid */
- ugh = check_key_recs(MYID_HOSTNAME, c, ac);
- if (ugh != NULL)
- {
- /* cannot use our IP as OE identitiy for initiation */
- DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:KEY) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh));
- if (!logged_myid_fqdn_key_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "can not use our hostname (%s:KEY) as identity: %s"
- , myid_str[MYID_HOSTNAME]
- , ugh);
- logged_myid_fqdn_key_warning = TRUE;
- }
+ /* otherwise, there is some kind of static conn that can handle
+ * this connection, so we initiate it */
- next_step = fos_myid_hostname_key;
- ugh = NULL; /* failure can be recovered from */
- }
- else
- {
- /* we can use our IP as OE identity for initiation */
- if (!logged_myid_fqdn_key_warning)
+#ifdef KLIPS
+ if (b->held)
{
- loglog(RC_LOG_SERIOUS
- , "using our hostname (%s:KEY) as identity!"
- , myid_str[MYID_HOSTNAME]);
- logged_myid_fqdn_key_warning = TRUE;
+ /* what should we do on failure? */
+ (void) assign_hold(c, sr, b->transport_proto, &b->our_client, &b->peer_client);
}
- next_step = fos_our_client;
- }
- break;
#endif
-
- case fos_our_client: /* TXT for our client */
- {
- /* Our client is not us: we must check the TXT records.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
+ ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
+ b->whackfd = NULL_FD; /* protect from close */
+ }
+ else
+ {
+ /* We are handling an opportunistic situation.
+ * This involves several DNS lookup steps that require suspension.
+ * Note: many facts might change while we're suspended.
+ * Here be dragons.
+ *
+ * The first chunk of code handles the result of the previous
+ * DNS query (if any). It also selects the kind of the next step.
+ * The second chunk initiates the next DNS query (if any).
*/
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
+ enum find_oppo_step next_step = fos_myid_ip_txt;
+ err_t ugh = ac_ugh;
+ char mycredentialstr[BUF_LEN];
+ char cib[CONN_INST_BUF];
- next_step = fos_his_client; /* normal situation */
+ DBG(DBG_CONTROL, DBG_log("creating new instance from \"%s\"%s"
+ , c->name
+ , (fmt_conn_instance(c, cib), cib)));
+
- passert(sr != NULL);
+ idtoa(&sr->this.id, mycredentialstr, sizeof(mycredentialstr));
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (sameaddr(&sr->this.host_addr, &b->our_client))
- {
- /* this wasn't true when we started -- bail */
- ugh = "our IP address changed underfoot";
- }
- else if (!same_id(&ac->sgw_id, &sr->this.id))
- {
- /* this wasn't true when we started -- bail */
- ugh = "our ID changed underfoot";
- }
- else
+ passert(c->policy & POLICY_OPPO); /* can't initiate Road Warrior connections */
+
+ /* handle any DNS answer; select next step */
+
+ switch (b->step)
{
- /* Similar to code in quick_inI1_outR1_tail
- * for checking the other side.
- */
- struct gw_info *gwp;
-
- ugh = "no TXT RR for our client delegates us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- passert(same_id(&gwp->gw_id, &sr->this.id));
-
- ugh = "TXT RR for our client has wrong key";
- /* If there is a key from the TXT record,
- * we count it as a win if we match the key.
- * If there was no key, we have a tentative win:
- * we need to check our KEY record to be sure.
- */
- if (!gwp->gw_key_present)
+ case fos_start:
+ /* just starting out: select first query step */
+ next_step = fos_myid_ip_txt;
+ break;
+
+ case fos_myid_ip_txt: /* TXT for our default IP address as %myid */
+ ugh = check_txt_recs(MYID_IP, c, ac);
+ if (ugh != NULL)
{
- /* Success, but the TXT had no key
- * so we must check our our own KEY records.
- */
- next_step = fos_our_txt;
- ugh = NULL; /* good! */
- break;
+ /* cannot use our IP as OE identitiy for initiation */
+ DBG(DBG_OPPO, DBG_log("can not use our IP (%s:TXT) as identity: %s"
+ , myid_str[MYID_IP]
+ , ugh));
+ if (!logged_myid_ip_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "can not use our IP (%s:TXT) as identity: %s"
+ , myid_str[MYID_IP]
+ , ugh);
+ logged_myid_ip_txt_warning = TRUE;
+ }
+
+ next_step = fos_myid_hostname_txt;
+ ugh = NULL; /* failure can be recovered from */
}
- if (same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
+ else
{
- ugh = NULL; /* good! */
- break;
+ /* we can use our IP as OE identity for initiation */
+ if (!logged_myid_ip_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "using our IP (%s:TXT) as identity!"
+ , myid_str[MYID_IP]);
+ logged_myid_ip_txt_warning = TRUE;
+ }
+
+ next_step = fos_our_client;
}
- }
- }
- }
- break;
-
- case fos_our_txt: /* TXT for us */
- {
- /* Check if TXT lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
-
- next_step = fos_his_client; /* unless we decide to look for KEY RR */
+ break;
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- struct gw_info *gwp;
-
- ugh = "no TXT RR for us";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- passert(same_id(&gwp->gw_id, &sr->this.id));
-
- ugh = "TXT RR for us has wrong key";
- if (gwp->gw_key_present
- && same_RSA_public_key(&our_RSA_pri->pub, &gwp->key->u.rsa))
+ case fos_myid_hostname_txt: /* TXT for our hostname as %myid */
+ ugh = check_txt_recs(MYID_HOSTNAME, c, ac);
+ if (ugh != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("initiate on demand found TXT with right public key at: %s"
- , mycredentialstr));
- ugh = NULL;
- break;
- }
- }
+ /* cannot use our hostname as OE identitiy for initiation */
+ DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:TXT) as identity: %s"
+ , myid_str[MYID_HOSTNAME]
+ , ugh));
+ if (!logged_myid_fqdn_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "can not use our hostname (%s:TXT) as identity: %s"
+ , myid_str[MYID_HOSTNAME]
+ , ugh);
+ logged_myid_fqdn_txt_warning = TRUE;
+ }
#ifdef USE_KEYRR
- if (ugh != NULL)
- {
- /* if no TXT with right key, try KEY */
- DBG(DBG_CONTROL,
- DBG_log("will try for KEY RR since initiate on demand found %s: %s"
- , ugh, mycredentialstr));
- next_step = fos_our_key;
- ugh = NULL;
- }
+ next_step = fos_myid_ip_key;
+ ugh = NULL; /* failure can be recovered from */
#endif
- }
- }
- break;
+ }
+ else
+ {
+ /* we can use our hostname as OE identity for initiation */
+ if (!logged_myid_fqdn_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "using our hostname (%s:TXT) as identity!"
+ , myid_str[MYID_HOSTNAME]);
+ logged_myid_fqdn_txt_warning = TRUE;
+ }
+ next_step = fos_our_client;
+ }
+ break;
#ifdef USE_KEYRR
- case fos_our_key: /* KEY for us */
- {
- /* Check if KEY lookup yielded good results.
- * Looking up based on our ID. Used if
- * client is ourself, or if TXT had no public key.
- * Note: if c is different this time, there is
- * a chance that we did the wrong query.
- * If so, treat as a kind of failure.
- */
- const struct RSA_private_key *our_RSA_pri = get_RSA_private_key(c);
+ case fos_myid_ip_key: /* KEY for our default IP address as %myid */
+ ugh = check_key_recs(MYID_IP, c, ac);
+ if (ugh != NULL)
+ {
+ /* cannot use our IP as OE identitiy for initiation */
+ DBG(DBG_OPPO, DBG_log("can not use our IP (%s:KEY) as identity: %s"
+ , myid_str[MYID_IP]
+ , ugh));
+ if (!logged_myid_ip_key_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "can not use our IP (%s:KEY) as identity: %s"
+ , myid_str[MYID_IP]
+ , ugh);
+ logged_myid_ip_key_warning = TRUE;
+ }
+
+ next_step = fos_myid_hostname_key;
+ ugh = NULL; /* failure can be recovered from */
+ }
+ else
+ {
+ /* we can use our IP as OE identity for initiation */
+ if (!logged_myid_ip_key_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "using our IP (%s:KEY) as identity!"
+ , myid_str[MYID_IP]);
+ logged_myid_ip_key_warning = TRUE;
+ }
+ next_step = fos_our_client;
+ }
+ break;
- next_step = fos_his_client; /* always */
+ case fos_myid_hostname_key: /* KEY for our hostname as %myid */
+ ugh = check_key_recs(MYID_HOSTNAME, c, ac);
+ if (ugh != NULL)
+ {
+ /* cannot use our IP as OE identitiy for initiation */
+ DBG(DBG_OPPO, DBG_log("can not use our hostname (%s:KEY) as identity: %s"
+ , myid_str[MYID_HOSTNAME]
+ , ugh));
+ if (!logged_myid_fqdn_key_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "can not use our hostname (%s:KEY) as identity: %s"
+ , myid_str[MYID_HOSTNAME]
+ , ugh);
+ logged_myid_fqdn_key_warning = TRUE;
+ }
+
+ next_step = fos_myid_hostname_key;
+ ugh = NULL; /* failure can be recovered from */
+ }
+ else
+ {
+ /* we can use our IP as OE identity for initiation */
+ if (!logged_myid_fqdn_key_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "using our hostname (%s:KEY) as identity!"
+ , myid_str[MYID_HOSTNAME]);
+ logged_myid_fqdn_key_warning = TRUE;
+ }
+ next_step = fos_our_client;
+ }
+ break;
+#endif
- if (our_RSA_pri == NULL)
- {
- ugh = "we don't know our own RSA key";
- }
- else if (!same_id(&ac->id, &c->spd.this.id))
- {
- ugh = "our ID changed underfoot";
- }
- else
- {
- /* Similar to code in RSA_check_signature
- * for checking the other side.
- */
- pubkey_list_t *kr;
-
- ugh = "no KEY RR found for us (and no good TXT RR)";
- for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
- {
- ugh = "all our KEY RRs have the wrong public key (and no good TXT RR)";
- if (kr->key->alg == PUBKEY_ALG_RSA
- && same_RSA_public_key(&our_RSA_pri->pub, &kr->key->u.rsa))
+ case fos_our_client: /* TXT for our client */
{
- /* do this only once a day */
- if (!logged_txt_warning)
- {
- loglog(RC_LOG_SERIOUS
- , "found KEY RR but not TXT RR for %s. See http://www.freeswan.org/err/txt-change.html."
- , mycredentialstr);
- logged_txt_warning = TRUE;
- }
- ugh = NULL; /* good! */
- break;
+ /* Our client is not us: we must check the TXT records.
+ * Note: if c is different this time, there is
+ * a chance that we did the wrong query.
+ * If so, treat as a kind of failure.
+ */
+ private_key_t *private = get_private_key(c);
+
+ next_step = fos_his_client; /* normal situation */
+
+ passert(sr != NULL);
+
+ if (private == NULL)
+ {
+ ugh = "we don't know our own RSA key";
+ }
+ else if (sameaddr(&sr->this.host_addr, &b->our_client))
+ {
+ /* this wasn't true when we started -- bail */
+ ugh = "our IP address changed underfoot";
+ }
+ else if (!same_id(&ac->sgw_id, &sr->this.id))
+ {
+ /* this wasn't true when we started -- bail */
+ ugh = "our ID changed underfoot";
+ }
+ else
+ {
+ /* Similar to code in quick_inI1_outR1_tail
+ * for checking the other side.
+ */
+ struct gw_info *gwp;
+
+ ugh = "no TXT RR for our client delegates us";
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ passert(same_id(&gwp->gw_id, &sr->this.id));
+
+ ugh = "TXT RR for our client has wrong key";
+ /* If there is a key from the TXT record,
+ * we count it as a win if we match the key.
+ * If there was no key, we have a tentative win:
+ * we need to check our KEY record to be sure.
+ */
+ if (!gwp->gw_key_present)
+ {
+ /* Success, but the TXT had no key
+ * so we must check our our own KEY records.
+ */
+ next_step = fos_our_txt;
+ ugh = NULL; /* good! */
+ break;
+ }
+ if (private->belongs_to(private, gwp->key->public_key))
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
}
- }
- }
- }
- break;
-#endif /* USE_KEYRR */
+ break;
- case fos_his_client: /* TXT for his client */
- {
- /* We've finished last DNS queries: TXT for his client.
- * Using the information, try to instantiate a connection
- * and start negotiating.
- * We now know the peer. The chosing of "c" ignored this,
- * so we will disregard its current value.
- * !!! We need to randomize the entry in gw that we choose.
- */
- next_step = fos_done; /* no more queries */
+ case fos_our_txt: /* TXT for us */
+ {
+ /* Check if TXT lookup yielded good results.
+ * Looking up based on our ID. Used if
+ * client is ourself, or if TXT had no public key.
+ * Note: if c is different this time, there is
+ * a chance that we did the wrong query.
+ * If so, treat as a kind of failure.
+ */
+ private_key_t *private = get_private_key(c);
+
+ next_step = fos_his_client; /* unless we decide to look for KEY RR */
+
+ if (private == NULL)
+ {
+ ugh = "we don't know our own RSA key";
+ }
+ else if (!same_id(&ac->id, &c->spd.this.id))
+ {
+ ugh = "our ID changed underfoot";
+ }
+ else
+ {
+ /* Similar to code in RSA_check_signature
+ * for checking the other side.
+ */
+ struct gw_info *gwp;
+
+ ugh = "no TXT RR for us";
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ passert(same_id(&gwp->gw_id, &sr->this.id));
+
+ ugh = "TXT RR for us has wrong key";
+ if (gwp->gw_key_present &&
+ private->belongs_to(private, gwp->key->public_key))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("initiate on demand found TXT with right public key at: %s"
+ , mycredentialstr));
+ ugh = NULL;
+ break;
+ }
+ }
+#ifdef USE_KEYRR
+ if (ugh != NULL)
+ {
+ /* if no TXT with right key, try KEY */
+ DBG(DBG_CONTROL,
+ DBG_log("will try for KEY RR since initiate on demand found %s: %s"
+ , ugh, mycredentialstr));
+ next_step = fos_our_key;
+ ugh = NULL;
+ }
+#endif
+ }
+ }
+ break;
- c = build_outgoing_opportunistic_connection(ac->gateways_from_dns
- , &b->our_client
- , &b->peer_client);
+#ifdef USE_KEYRR
+ case fos_our_key: /* KEY for us */
+ {
+ /* Check if KEY lookup yielded good results.
+ * Looking up based on our ID. Used if
+ * client is ourself, or if TXT had no public key.
+ * Note: if c is different this time, there is
+ * a chance that we did the wrong query.
+ * If so, treat as a kind of failure.
+ */
+ private_key_t *private = get_private_key(c);
+
+ next_step = fos_his_client; /* always */
+
+ if (private == NULL)
+ {
+ ugh = "we don't know our own RSA key";
+ }
+ else if (!same_id(&ac->id, &c->spd.this.id))
+ {
+ ugh = "our ID changed underfoot";
+ }
+ else
+ {
+ /* Similar to code in RSA_check_signature
+ * for checking the other side.
+ */
+ pubkey_list_t *kr;
+
+ ugh = "no KEY RR found for us (and no good TXT RR)";
+ for (kr = ac->keys_from_dns; kr != NULL; kr = kr->next)
+ {
+ ugh = "all our KEY RRs have the wrong public key (and no good TXT RR)";
+ if (kr->key->alg == PUBKEY_ALG_RSA
+ && private->belongs_to(private, kr->key->public_key))
+ {
+ /* do this only once a day */
+ if (!logged_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "found KEY RR but not TXT RR for %s. See http://www.freeswan.org/err/txt-change.html."
+ , mycredentialstr);
+ logged_txt_warning = TRUE;
+ }
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
+ }
+ break;
+#endif /* USE_KEYRR */
- if (c == NULL)
- {
- /* We cannot seem to instantiate a suitable connection:
- * complain clearly.
- */
- char ocb[ADDRTOT_BUF]
- , pcb[ADDRTOT_BUF]
- , pb[ADDRTOT_BUF];
-
- addrtot(&b->our_client, 0, ocb, sizeof(ocb));
- addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
- passert(id_is_ipaddr(&ac->gateways_from_dns->gw_id));
- addrtot(&ac->gateways_from_dns->gw_id.ip_addr, 0, pb, sizeof(pb));
- loglog(RC_OPPOFAILURE
- , "no suitable connection for opportunism"
- " between %s and %s with %s as peer"
- , ocb, pcb, pb);
+ case fos_his_client: /* TXT for his client */
+ {
+ /* We've finished last DNS queries: TXT for his client.
+ * Using the information, try to instantiate a connection
+ * and start negotiating.
+ * We now know the peer. The chosing of "c" ignored this,
+ * so we will disregard its current value.
+ * !!! We need to randomize the entry in gw that we choose.
+ */
+ next_step = fos_done; /* no more queries */
+
+ c = build_outgoing_opportunistic_connection(ac->gateways_from_dns
+ , &b->our_client
+ , &b->peer_client);
+
+ if (c == NULL)
+ {
+ /* We cannot seem to instantiate a suitable connection:
+ * complain clearly.
+ */
+ char ocb[ADDRTOT_BUF]
+ , pcb[ADDRTOT_BUF]
+ , pb[ADDRTOT_BUF];
+
+ addrtot(&b->our_client, 0, ocb, sizeof(ocb));
+ addrtot(&b->peer_client, 0, pcb, sizeof(pcb));
+ passert(id_is_ipaddr(&ac->gateways_from_dns->gw_id));
+ addrtot(&ac->gateways_from_dns->gw_id.ip_addr, 0, pb, sizeof(pb));
+ loglog(RC_OPPOFAILURE
+ , "no suitable connection for opportunism"
+ " between %s and %s with %s as peer"
+ , ocb, pcb, pb);
#ifdef KLIPS
- if (b->held)
- {
- /* Replace HOLD with PASS.
- * The type of replacement *ought* to be
- * specified by policy.
- */
- (void) replace_bare_shunt(&b->our_client, &b->peer_client
- , BOTTOM_PRIO
- , SPI_PASS /* fail into PASS */
- , TRUE, b->transport_proto
- , "no suitable connection");
- }
+ if (b->held)
+ {
+ /* Replace HOLD with PASS.
+ * The type of replacement *ought* to be
+ * specified by policy.
+ */
+ (void) replace_bare_shunt(&b->our_client, &b->peer_client
+ , BOTTOM_PRIO
+ , SPI_PASS /* fail into PASS */
+ , TRUE, b->transport_proto
+ , "no suitable connection");
+ }
#endif
- }
- else
- {
- /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
- passert(c->kind == CK_INSTANCE);
- passert(c->gw_info != NULL);
- passert(HAS_IPSEC_POLICY(c->policy));
- passert(LHAS(LELEM(RT_UNROUTED) | LELEM(RT_ROUTED_PROSPECTIVE), c->spd.routing));
+ }
+ else
+ {
+ /* If we are to proceed asynchronously, b->whackfd will be NULL_FD. */
+ passert(c->kind == CK_INSTANCE);
+ passert(c->gw_info != NULL);
+ passert(HAS_IPSEC_POLICY(c->policy));
+ passert(LHAS(LELEM(RT_UNROUTED) | LELEM(RT_ROUTED_PROSPECTIVE), c->spd.routing));
#ifdef KLIPS
- if (b->held)
- {
- /* what should we do on failure? */
- (void) assign_hold(c, &c->spd
- , b->transport_proto
- , &b->our_client, &b->peer_client);
- }
+ if (b->held)
+ {
+ /* what should we do on failure? */
+ (void) assign_hold(c, &c->spd
+ , b->transport_proto
+ , &b->our_client, &b->peer_client);
+ }
#endif
- c->gw_info->key->last_tried_time = now();
- ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
- b->whackfd = NULL_FD; /* protect from close */
- }
- }
- break;
+ c->gw_info->key->last_tried_time = now();
+ ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
+ b->whackfd = NULL_FD; /* protect from close */
+ }
+ }
+ break;
- default:
- bad_case(b->step);
- }
+ default:
+ bad_case(b->step);
+ }
- /* the second chunk: initiate the next DNS query (if any) */
- DBG(DBG_CONTROL,
- {
- char ours[ADDRTOT_BUF];
- char his[ADDRTOT_BUF];
+ /* the second chunk: initiate the next DNS query (if any) */
+ DBG(DBG_CONTROL,
+ {
+ char ours[ADDRTOT_BUF];
+ char his[ADDRTOT_BUF];
- addrtot(&b->our_client, 0, ours, sizeof(ours));
- addrtot(&b->peer_client, 0, his, sizeof(his));
- DBG_log("initiate on demand from %s to %s new state: %s with ugh: %s"
- , ours, his, oppo_step_name[b->step], ugh ? ugh : "ok");
- });
+ addrtot(&b->our_client, 0, ours, sizeof(ours));
+ addrtot(&b->peer_client, 0, his, sizeof(his));
+ DBG_log("initiate on demand from %s to %s new state: %s with ugh: %s"
+ , ours, his, oppo_step_name[b->step], ugh ? ugh : "ok");
+ });
- if (ugh != NULL)
- {
- b->policy_prio = c->prio;
- b->failure_shunt = shunt_policy_spi(c, FALSE);
- cannot_oppo(c, b, ugh);
- }
- else if (next_step == fos_done)
- {
- /* nothing to do */
- }
- else
- {
- /* set up the next query */
- struct find_oppo_continuation *cr = alloc_thing(struct find_oppo_continuation
- , "opportunistic continuation");
- struct id id;
-
- b->policy_prio = c->prio;
- b->failure_shunt = shunt_policy_spi(c, FALSE);
- cr->b = *b; /* copy; start hand off of whackfd */
- cr->b.failure_ok = FALSE;
- cr->b.step = next_step;
-
- for (sr = &c->spd
- ; sr!=NULL && !sameaddr(&sr->this.host_addr, &b->our_client)
- ; sr = sr->next)
- ;
-
- if (sr == NULL)
- sr = &c->spd;
-
- /* If a %hold shunt has replaced the eroute for this template,
- * record this fact.
- */
- if (b->held
- && sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr))
- {
- sr->routing = RT_ROUTED_ECLIPSED;
- eclipse_count++;
- }
-
- /* Switch to issue next query.
- * A case may turn out to be unnecessary. If so, it falls
- * through to the next case.
- * Figuring out what %myid can stand for must be done before
- * our client credentials are looked up: we must know what
- * the client credentials may use to identify us.
- * On the other hand, our own credentials should be looked
- * up after our clients in case our credentials are not
- * needed at all.
- * XXX this is a wasted effort if we don't have credentials
- * BUT they are not needed.
- */
- switch (next_step)
- {
- case fos_myid_ip_txt:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
+ if (ugh != NULL)
{
- cr->b.failure_ok = TRUE;
- cr->b.want = b->want = "TXT record for IP address as %myid";
- ugh = start_adns_query(&myids[MYID_IP]
- , &myids[MYID_IP]
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
+ b->policy_prio = c->prio;
+ b->failure_shunt = shunt_policy_spi(c, FALSE);
+ cannot_oppo(c, b, ugh);
}
- cr->b.step = fos_myid_hostname_txt;
- /* fall through */
-
- case fos_myid_hostname_txt:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
+ else if (next_step == fos_done)
+ {
+ /* nothing to do */
+ }
+ else
{
+ /* set up the next query */
+ struct find_oppo_continuation *cr = malloc_thing(struct find_oppo_continuation);
+ struct id id;
+
+ b->policy_prio = c->prio;
+ b->failure_shunt = shunt_policy_spi(c, FALSE);
+ cr->b = *b; /* copy; start hand off of whackfd */
+ cr->b.failure_ok = FALSE;
+ cr->b.step = next_step;
+
+ for (sr = &c->spd
+ ; sr!=NULL && !sameaddr(&sr->this.host_addr, &b->our_client)
+ ; sr = sr->next)
+ ;
+
+ if (sr == NULL)
+ sr = &c->spd;
+
+ /* If a %hold shunt has replaced the eroute for this template,
+ * record this fact.
+ */
+ if (b->held
+ && sr->routing == RT_ROUTED_PROSPECTIVE && eclipsable(sr))
+ {
+ sr->routing = RT_ROUTED_ECLIPSED;
+ eclipse_count++;
+ }
+
+ /* Switch to issue next query.
+ * A case may turn out to be unnecessary. If so, it falls
+ * through to the next case.
+ * Figuring out what %myid can stand for must be done before
+ * our client credentials are looked up: we must know what
+ * the client credentials may use to identify us.
+ * On the other hand, our own credentials should be looked
+ * up after our clients in case our credentials are not
+ * needed at all.
+ * XXX this is a wasted effort if we don't have credentials
+ * BUT they are not needed.
+ */
+ switch (next_step)
+ {
+ case fos_myid_ip_txt:
+ if (c->spd.this.id.kind == ID_MYID
+ && myid_state != MYID_SPECIFIED)
+ {
+ cr->b.failure_ok = TRUE;
+ cr->b.want = b->want = "TXT record for IP address as %myid";
+ ugh = start_adns_query(&myids[MYID_IP]
+ , &myids[MYID_IP]
+ , T_TXT
+ , continue_oppo
+ , &cr->ac);
+ break;
+ }
+ cr->b.step = fos_myid_hostname_txt;
+ /* fall through */
+
+ case fos_myid_hostname_txt:
+ if (c->spd.this.id.kind == ID_MYID
+ && myid_state != MYID_SPECIFIED)
+ {
#ifdef USE_KEYRR
- cr->b.failure_ok = TRUE;
+ cr->b.failure_ok = TRUE;
#else
- cr->b.failure_ok = FALSE;
+ cr->b.failure_ok = FALSE;
#endif
- cr->b.want = b->want = "TXT record for hostname as %myid";
- ugh = start_adns_query(&myids[MYID_HOSTNAME]
- , &myids[MYID_HOSTNAME]
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
- }
+ cr->b.want = b->want = "TXT record for hostname as %myid";
+ ugh = start_adns_query(&myids[MYID_HOSTNAME]
+ , &myids[MYID_HOSTNAME]
+ , T_TXT
+ , continue_oppo
+ , &cr->ac);
+ break;
+ }
#ifdef USE_KEYRR
- cr->b.step = fos_myid_ip_key;
- /* fall through */
-
- case fos_myid_ip_key:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
- cr->b.failure_ok = TRUE;
- cr->b.want = b->want = "KEY record for IP address as %myid (no good TXT)";
- ugh = start_adns_query(&myids[MYID_IP]
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
- }
- cr->b.step = fos_myid_hostname_key;
- /* fall through */
-
- case fos_myid_hostname_key:
- if (c->spd.this.id.kind == ID_MYID
- && myid_state != MYID_SPECIFIED)
- {
- cr->b.failure_ok = FALSE; /* last attempt! */
- cr->b.want = b->want = "KEY record for hostname as %myid (no good TXT)";
- ugh = start_adns_query(&myids[MYID_HOSTNAME]
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
- }
+ cr->b.step = fos_myid_ip_key;
+ /* fall through */
+
+ case fos_myid_ip_key:
+ if (c->spd.this.id.kind == ID_MYID
+ && myid_state != MYID_SPECIFIED)
+ {
+ cr->b.failure_ok = TRUE;
+ cr->b.want = b->want = "KEY record for IP address as %myid (no good TXT)";
+ ugh = start_adns_query(&myids[MYID_IP]
+ , (const struct id *) NULL /* security gateway meaningless */
+ , T_KEY
+ , continue_oppo
+ , &cr->ac);
+ break;
+ }
+ cr->b.step = fos_myid_hostname_key;
+ /* fall through */
+
+ case fos_myid_hostname_key:
+ if (c->spd.this.id.kind == ID_MYID
+ && myid_state != MYID_SPECIFIED)
+ {
+ cr->b.failure_ok = FALSE; /* last attempt! */
+ cr->b.want = b->want = "KEY record for hostname as %myid (no good TXT)";
+ ugh = start_adns_query(&myids[MYID_HOSTNAME]
+ , (const struct id *) NULL /* security gateway meaningless */
+ , T_KEY
+ , continue_oppo
+ , &cr->ac);
+ break;
+ }
#endif
- cr->b.step = fos_our_client;
- /* fall through */
-
- case fos_our_client: /* TXT for our client */
- if (!sameaddr(&c->spd.this.host_addr, &b->our_client))
- {
- /* Check that at least one TXT(reverse(b->our_client)) is workable.
- * Note: {unshare|free}_id_content not needed for id: ephemeral.
- */
- cr->b.want = b->want = "our client's TXT record";
- iptoid(&b->our_client, &id);
- ugh = start_adns_query(&id
- , &c->spd.this.id /* we are the security gateway */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
- }
- cr->b.step = fos_our_txt;
- /* fall through */
-
- case fos_our_txt: /* TXT for us */
- cr->b.failure_ok = b->failure_ok = TRUE;
- cr->b.want = b->want = "our TXT record";
- ugh = start_adns_query(&sr->this.id
- , &sr->this.id /* we are the security gateway XXX - maybe ignore? mcr */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
+ cr->b.step = fos_our_client;
+ /* fall through */
+
+ case fos_our_client: /* TXT for our client */
+ if (!sameaddr(&c->spd.this.host_addr, &b->our_client))
+ {
+ /* Check that at least one TXT(reverse(b->our_client)) is workable.
+ * Note: {unshare|free}_id_content not needed for id: ephemeral.
+ */
+ cr->b.want = b->want = "our client's TXT record";
+ iptoid(&b->our_client, &id);
+ ugh = start_adns_query(&id
+ , &c->spd.this.id /* we are the security gateway */
+ , T_TXT
+ , continue_oppo
+ , &cr->ac);
+ break;
+ }
+ cr->b.step = fos_our_txt;
+ /* fall through */
+
+ case fos_our_txt: /* TXT for us */
+ cr->b.failure_ok = b->failure_ok = TRUE;
+ cr->b.want = b->want = "our TXT record";
+ ugh = start_adns_query(&sr->this.id
+ , &sr->this.id /* we are the security gateway XXX - maybe ignore? mcr */
+ , T_TXT
+ , continue_oppo
+ , &cr->ac);
+ break;
#ifdef USE_KEYRR
- case fos_our_key: /* KEY for us */
- cr->b.want = b->want = "our KEY record";
- cr->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&sr->this.id
- , (const struct id *) NULL /* security gateway meaningless */
- , T_KEY
- , continue_oppo
- , &cr->ac);
- break;
+ case fos_our_key: /* KEY for us */
+ cr->b.want = b->want = "our KEY record";
+ cr->b.failure_ok = b->failure_ok = FALSE;
+ ugh = start_adns_query(&sr->this.id
+ , (const struct id *) NULL /* security gateway meaningless */
+ , T_KEY
+ , continue_oppo
+ , &cr->ac);
+ break;
#endif /* USE_KEYRR */
- case fos_his_client: /* TXT for his client */
- /* note: {unshare|free}_id_content not needed for id: ephemeral */
- cr->b.want = b->want = "target's TXT record";
- cr->b.failure_ok = b->failure_ok = FALSE;
- iptoid(&b->peer_client, &id);
- ugh = start_adns_query(&id
- , (const struct id *) NULL /* security gateway unconstrained */
- , T_TXT
- , continue_oppo
- , &cr->ac);
- break;
-
- default:
- bad_case(next_step);
- }
+ case fos_his_client: /* TXT for his client */
+ /* note: {unshare|free}_id_content not needed for id: ephemeral */
+ cr->b.want = b->want = "target's TXT record";
+ cr->b.failure_ok = b->failure_ok = FALSE;
+ iptoid(&b->peer_client, &id);
+ ugh = start_adns_query(&id
+ , (const struct id *) NULL /* security gateway unconstrained */
+ , T_TXT
+ , continue_oppo
+ , &cr->ac);
+ break;
+
+ default:
+ bad_case(next_step);
+ }
- if (ugh == NULL)
- b->whackfd = NULL_FD; /* complete hand-off */
- else
- cannot_oppo(c, b, ugh);
+ if (ugh == NULL)
+ b->whackfd = NULL_FD; /* complete hand-off */
+ else
+ cannot_oppo(c, b, ugh);
+ }
}
- }
- close_any(b->whackfd);
+ close_any(b->whackfd);
}
void
terminate_connection(const char *nm)
{
- /* Loop because more than one may match (master and instances)
- * But at least one is required (enforced by con_by_name).
- */
- struct connection *c = con_by_name(nm, TRUE);
-
- if (c == NULL || !c->ikev1)
- return;
+ /* Loop because more than one may match (master and instances)
+ * But at least one is required (enforced by con_by_name).
+ */
+ struct connection *c = con_by_name(nm, TRUE);
- do
- {
- struct connection *n = c->ac_next; /* grab this before c might disappear */
+ if (c == NULL || !c->ikev1)
+ return;
- if (streq(c->name, nm)
- && c->kind >= CK_PERMANENT
- && !NEVER_NEGOTIATE(c->policy))
+ do
{
- set_cur_connection(c);
- plog("terminating SAs using this connection");
- c->policy &= ~POLICY_UP;
- flush_pending_by_connection(c);
- delete_states_by_connection(c, FALSE);
- if (c->kind == CK_INSTANCE)
- delete_connection(c, FALSE);
- reset_cur_connection();
- }
- c = n;
- } while (c != NULL);
+ struct connection *n = c->ac_next; /* grab this before c might disappear */
+
+ if (streq(c->name, nm)
+ && c->kind >= CK_PERMANENT
+ && !NEVER_NEGOTIATE(c->policy))
+ {
+ set_cur_connection(c);
+ plog("terminating SAs using this connection");
+ c->policy &= ~POLICY_UP;
+ flush_pending_by_connection(c);
+ delete_states_by_connection(c, FALSE);
+ if (c->kind == CK_INSTANCE)
+ delete_connection(c, FALSE);
+ reset_cur_connection();
+ }
+ c = n;
+ } while (c != NULL);
}
/* an ISAKMP SA has been established.
* Note the serial number, and release any connections with
* the same peer ID but different peer IP address.
*/
-bool uniqueIDs = FALSE; /* --uniqueids? */
+bool uniqueIDs = FALSE; /* --uniqueids? */
void
ISAKMP_SA_established(struct connection *c, so_serial_t serial)
{
- c->newest_isakmp_sa = serial;
-
- /* the connection is now oriented so that we are able to determine
- * whether we are a mode config server with a virtual IP to send.
- */
- if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
- c->spd.that.modecfg = TRUE;
-
- if (uniqueIDs)
- {
- /* for all connections: if the same Phase 1 IDs are used
- * for a different IP address, unorient that connection.
- */
- struct connection *d;
+ c->newest_isakmp_sa = serial;
- for (d = connections; d != NULL; )
+ /* the connection is now oriented so that we are able to determine
+ * whether we are a mode config server with a virtual IP to send.
+ */
+ if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
+ c->spd.that.modecfg = TRUE;
+
+ if (uniqueIDs)
{
- struct connection *next = d->ac_next; /* might move underneath us */
-
- if (d->kind >= CK_PERMANENT
- && same_id(&c->spd.this.id, &d->spd.this.id)
- && same_id(&c->spd.that.id, &d->spd.that.id)
- && !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr))
- {
- release_connection(d, FALSE);
- }
- d = next;
+ /* for all connections: if the same Phase 1 IDs are used
+ * for a different IP address, unorient that connection.
+ */
+ struct connection *d;
+
+ for (d = connections; d != NULL; )
+ {
+ struct connection *next = d->ac_next; /* might move underneath us */
+
+ if (d->kind >= CK_PERMANENT
+ && same_id(&c->spd.this.id, &d->spd.this.id)
+ && same_id(&c->spd.that.id, &d->spd.that.id)
+ && !sameaddr(&c->spd.that.host_addr, &d->spd.that.host_addr))
+ {
+ release_connection(d, FALSE);
+ }
+ d = next;
+ }
}
- }
}
/* Find the connection to connection c's peer's client with the
@@ -3056,108 +3048,108 @@ ISAKMP_SA_established(struct connection *c, so_serial_t serial)
*/
struct connection *
route_owner(struct connection *c
- , struct spd_route **srp
- , struct connection **erop
- , struct spd_route **esrp)
+ , struct spd_route **srp
+ , struct connection **erop
+ , struct spd_route **esrp)
{
- struct connection *d
- , *best_ro = c
- , *best_ero = c;
- struct spd_route *srd, *src;
- struct spd_route *best_sr, *best_esr;
- enum routing_t best_routing, best_erouting;
-
- passert(oriented(*c));
- best_sr = NULL;
- best_esr = NULL;
- best_routing = c->spd.routing;
- best_erouting = best_routing;
-
- for (d = connections; d != NULL; d = d->ac_next)
- {
- for (srd = &d->spd; srd; srd = srd->next)
+ struct connection *d
+ , *best_ro = c
+ , *best_ero = c;
+ struct spd_route *srd, *src;
+ struct spd_route *best_sr, *best_esr;
+ enum routing_t best_routing, best_erouting;
+
+ passert(oriented(*c));
+ best_sr = NULL;
+ best_esr = NULL;
+ best_routing = c->spd.routing;
+ best_erouting = best_routing;
+
+ for (d = connections; d != NULL; d = d->ac_next)
{
- if (srd->routing == RT_UNROUTED)
- continue;
-
- for (src = &c->spd; src; src=src->next)
- {
- if (!samesubnet(&src->that.client, &srd->that.client))
- continue;
- if (src->that.protocol != srd->that.protocol)
- continue;
- if (src->that.port != srd->that.port)
- continue;
- passert(oriented(*d));
- if (srd->routing > best_routing)
+ for (srd = &d->spd; srd; srd = srd->next)
{
- best_ro = d;
- best_sr = srd;
- best_routing = srd->routing;
- }
+ if (srd->routing == RT_UNROUTED)
+ continue;
- if (!samesubnet(&src->this.client, &srd->this.client))
- continue;
- if (src->this.protocol != srd->this.protocol)
- continue;
- if (src->this.port != srd->this.port)
- continue;
- if (srd->routing > best_erouting)
- {
- best_ero = d;
- best_esr = srd;
- best_erouting = srd->routing;
+ for (src = &c->spd; src; src=src->next)
+ {
+ if (!samesubnet(&src->that.client, &srd->that.client))
+ continue;
+ if (src->that.protocol != srd->that.protocol)
+ continue;
+ if (src->that.port != srd->that.port)
+ continue;
+ passert(oriented(*d));
+ if (srd->routing > best_routing)
+ {
+ best_ro = d;
+ best_sr = srd;
+ best_routing = srd->routing;
+ }
+
+ if (!samesubnet(&src->this.client, &srd->this.client))
+ continue;
+ if (src->this.protocol != srd->this.protocol)
+ continue;
+ if (src->this.port != srd->this.port)
+ continue;
+ if (srd->routing > best_erouting)
+ {
+ best_ero = d;
+ best_esr = srd;
+ best_erouting = srd->routing;
+ }
+ }
}
- }
}
- }
- DBG(DBG_CONTROL,
+ DBG(DBG_CONTROL,
+ {
+ char cib[CONN_INST_BUF];
+ err_t m = builddiag("route owner of \"%s\"%s %s:"
+ , c->name
+ , (fmt_conn_instance(c, cib), cib)
+ , enum_name(&routing_story, c->spd.routing));
+
+ if (!routed(best_ro->spd.routing))
+ m = builddiag("%s NULL", m);
+ else if (best_ro == c)
+ m = builddiag("%s self", m);
+ else
+ m = builddiag("%s \"%s\"%s %s", m
+ , best_ro->name
+ , (fmt_conn_instance(best_ro, cib), cib)
+ , enum_name(&routing_story, best_ro->spd.routing));
+
+ if (erop != NULL)
+ {
+ m = builddiag("%s; eroute owner:", m);
+ if (!erouted(best_ero->spd.routing))
+ m = builddiag("%s NULL", m);
+ else if (best_ero == c)
+ m = builddiag("%s self", m);
+ else
+ m = builddiag("%s \"%s\"%s %s", m
+ , best_ero->name
+ , (fmt_conn_instance(best_ero, cib), cib)
+ , enum_name(&routing_story, best_ero->spd.routing));
+ }
+
+ DBG_log("%s", m);
+ });
+
+ if (erop != NULL)
+ *erop = erouted(best_erouting)? best_ero : NULL;
+
+ if (srp != NULL )
{
- char cib[CONN_INST_BUF];
- err_t m = builddiag("route owner of \"%s\"%s %s:"
- , c->name
- , (fmt_conn_instance(c, cib), cib)
- , enum_name(&routing_story, c->spd.routing));
-
- if (!routed(best_ro->spd.routing))
- m = builddiag("%s NULL", m);
- else if (best_ro == c)
- m = builddiag("%s self", m);
- else
- m = builddiag("%s \"%s\"%s %s", m
- , best_ro->name
- , (fmt_conn_instance(best_ro, cib), cib)
- , enum_name(&routing_story, best_ro->spd.routing));
-
- if (erop != NULL)
- {
- m = builddiag("%s; eroute owner:", m);
- if (!erouted(best_ero->spd.routing))
- m = builddiag("%s NULL", m);
- else if (best_ero == c)
- m = builddiag("%s self", m);
- else
- m = builddiag("%s \"%s\"%s %s", m
- , best_ero->name
- , (fmt_conn_instance(best_ero, cib), cib)
- , enum_name(&routing_story, best_ero->spd.routing));
- }
-
- DBG_log("%s", m);
- });
-
- if (erop != NULL)
- *erop = erouted(best_erouting)? best_ero : NULL;
-
- if (srp != NULL )
- {
- *srp = best_sr;
- if (esrp != NULL )
- *esrp = best_esr;
- }
-
- return routed(best_routing)? best_ro : NULL;
+ *srp = best_sr;
+ if (esrp != NULL )
+ *esrp = best_esr;
+ }
+
+ return routed(best_routing)? best_ro : NULL;
}
/* Find a connection that owns the shunt eroute between subnets.
@@ -3167,20 +3159,20 @@ route_owner(struct connection *c
struct connection *
shunt_owner(const ip_subnet *ours, const ip_subnet *his)
{
- struct connection *c;
- struct spd_route *sr;
+ struct connection *c;
+ struct spd_route *sr;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- for (sr = &c->spd; sr; sr = sr->next)
+ for (c = connections; c != NULL; c = c->ac_next)
{
- if (shunt_erouted(sr->routing)
- && samesubnet(ours, &sr->this.client)
- && samesubnet(his, &sr->that.client))
- return c;
+ for (sr = &c->spd; sr; sr = sr->next)
+ {
+ if (shunt_erouted(sr->routing)
+ && samesubnet(ours, &sr->this.client)
+ && samesubnet(his, &sr->that.client))
+ return c;
+ }
}
- }
- return NULL;
+ return NULL;
}
/* Find some connection with this pair of hosts.
@@ -3191,25 +3183,25 @@ struct connection *
find_host_connection(const ip_address *me, u_int16_t my_port
, const ip_address *him, u_int16_t his_port, lset_t policy)
{
- struct connection *c = find_host_pair_connections(me, my_port, him, his_port);
-
- if (policy != LEMPTY)
- {
- lset_t auth_requested = policy & POLICY_ID_AUTH_MASK;
+ struct connection *c = find_host_pair_connections(me, my_port, him, his_port);
- /* if we have requirements for the policy,
- * choose the first matching connection.
- */
- while (c != NULL)
+ if (policy != LEMPTY)
{
- if (c->policy & auth_requested)
- {
- break;
- }
- c = c->hp_next;
+ lset_t auth_requested = policy & POLICY_ID_AUTH_MASK;
+
+ /* if we have requirements for the policy,
+ * choose the first matching connection.
+ */
+ while (c != NULL)
+ {
+ if (c->policy & auth_requested)
+ {
+ break;
+ }
+ c = c->hp_next;
+ }
}
- }
- return c;
+ return c;
}
/* given an up-until-now satisfactory connection, find the best connection
@@ -3266,187 +3258,197 @@ find_host_connection(const ip_address *me, u_int16_t my_port
*
* In the Initiator case, the particular connection might have been
* specified by whatever provoked Pluto to initiate. For example:
- * whack --initiate connection-name
+ * whack --initiate connection-name
* The advantages of switching connections when we're the Initiator seem
* less important than the disadvantages, so after FreeS/WAN 1.9, we
* don't do this.
*/
-#define PRIO_NO_MATCH_FOUND 2048
+#define PRIO_NO_MATCH_FOUND 2048
struct connection *
refine_host_connection(const struct state *st, const struct id *peer_id
, chunk_t peer_ca)
{
- struct connection *c = st->st_connection;
- struct connection *d;
- struct connection *best_found = NULL;
- u_int16_t auth = st->st_oakley.auth;
- lset_t auth_policy = POLICY_PSK;
- const chunk_t *psk = NULL;
- bool wcpip; /* wildcard Peer IP? */
- int best_prio = PRIO_NO_MATCH_FOUND;
- int wildcards, our_pathlen, peer_pathlen;
-
- if (same_id(&c->spd.that.id, peer_id)
- && trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen)
- && peer_pathlen == 0
- && match_requested_ca(c->requested_ca, c->spd.this.ca, &our_pathlen)
- && our_pathlen == 0)
- {
- DBG(DBG_CONTROL,
- DBG_log("current connection is a full match"
- " -- no need to look further");
- )
- return c;
- }
-
- switch (auth)
- {
- case OAKLEY_PRESHARED_KEY:
- auth_policy = POLICY_PSK;
- psk = get_preshared_secret(c);
- /* It should be virtually impossible to fail to find PSK:
- * we just used it to decode the current message!
- */
- if (psk == NULL)
- return NULL; /* cannot determine PSK! */
- break;
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- auth_policy = POLICY_XAUTH_PSK;
- psk = get_preshared_secret(c);
- if (psk == NULL)
- return NULL; /* cannot determine PSK! */
- break;
- case OAKLEY_RSA_SIG:
- auth_policy = POLICY_RSASIG;
- break;
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- auth_policy = POLICY_XAUTH_RSASIG;
- break;
- default:
- bad_case(auth);
- }
-
- /* The current connection won't do: search for one that will.
- * First search for one with the same pair of hosts.
- * If that fails, search for a suitable Road Warrior or Opportunistic
- * connection (i.e. wildcard peer IP).
- * We need to match:
- * - peer_id (slightly complicated by instantiation)
- * - if PSK auth, the key must not change (we used it to decode message)
- * - policy-as-used must be acceptable to new connection
- */
- d = c->host_pair->connections;
- for (wcpip = FALSE; ; wcpip = TRUE)
- {
- for (; d != NULL; d = d->hp_next)
+ struct connection *c = st->st_connection;
+ struct connection *d;
+ struct connection *best_found = NULL;
+ u_int16_t auth = st->st_oakley.auth;
+ lset_t auth_policy = POLICY_PSK;
+ const chunk_t *psk = NULL;
+ bool wcpip; /* wildcard Peer IP? */
+ int best_prio = PRIO_NO_MATCH_FOUND;
+ int wildcards, our_pathlen, peer_pathlen;
+
+ if (same_id(&c->spd.that.id, peer_id)
+ && trusted_ca(peer_ca, c->spd.that.ca, &peer_pathlen)
+ && peer_pathlen == 0
+ && match_requested_ca(c->requested_ca, c->spd.this.ca, &our_pathlen)
+ && our_pathlen == 0)
{
- const char *match_name[] = {"no", "ok"};
-
- bool matching_id = match_id(peer_id
- , &d->spd.that.id, &wildcards);
- bool matching_auth = (d->policy & auth_policy) != LEMPTY;
-
- bool matching_trust = trusted_ca(peer_ca
- , d->spd.that.ca, &peer_pathlen);
- bool matching_request = match_requested_ca(c->requested_ca
- , d->spd.this.ca, &our_pathlen);
- bool match = matching_id && matching_auth && matching_trust;
-
- int prio = (MAX_WILDCARDS + 1) * !matching_request + wildcards;
-
- prio = (MAX_CA_PATH_LEN + 1) * prio + peer_pathlen;
- prio = (MAX_CA_PATH_LEN + 1) * prio + our_pathlen;
-
- DBG(DBG_CONTROLMORE,
- DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s, prio: %4d)"
- , d->name
- , match ? "full":" no"
- , match_name[matching_id]
- , match_name[matching_auth]
- , match_name[matching_trust]
- , match_name[matching_request]
- , match ? prio:PRIO_NO_MATCH_FOUND)
- )
-
- /* do we have a match? */
- if (!match)
- continue;
-
- /* ignore group connections */
- if (d->policy & POLICY_GROUP)
- continue;
-
- if (c->spd.that.host_port != d->spd.that.host_port
- && d->kind == CK_INSTANCE)
- {
- continue;
- }
-
- switch (auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- /* secret must match the one we already used */
- {
- const chunk_t *dpsk = get_preshared_secret(d);
-
- if (dpsk == NULL)
- continue; /* no secret */
+ DBG(DBG_CONTROL,
+ DBG_log("current connection is a full match"
+ " -- no need to look further");
+ )
+ return c;
+ }
- if (psk != dpsk)
- if (psk->len != dpsk->len
- || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0)
- continue; /* different secret */
+ switch (auth)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ auth_policy = POLICY_PSK;
+ psk = get_preshared_secret(c);
+ /* It should be virtually impossible to fail to find PSK:
+ * we just used it to decode the current message!
+ */
+ if (psk == NULL)
+ {
+ return NULL; /* cannot determine PSK! */
}
break;
-
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- /*
- * We must at least be able to find our private key
- .*/
- if (d->spd.this.sc == NULL /* no smartcard */
- && get_RSA_private_key(d) == NULL) /* no private key */
- continue;
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ auth_policy = POLICY_XAUTH_PSK;
+ psk = get_preshared_secret(c);
+ if (psk == NULL)
+ {
+ return NULL; /* cannot determine PSK! */
+ }
break;
-
- default:
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ auth_policy = POLICY_PUBKEY;
+ break;
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ auth_policy = POLICY_XAUTH_RSASIG;
+ break;
+ default:
bad_case(auth);
- }
-
- /* d has passed all the tests.
- * We'll go with it if the Peer ID was an exact match.
- */
- if (prio == 0)
- {
- return d;
- }
-
- /* We'll remember it as best_found in case an exact
- * match doesn't come along.
- */
- if (prio < best_prio)
- {
- best_found = d;
- best_prio = prio;
- }
}
- if (wcpip)
- return best_found; /* been around twice already */
- /* Starting second time around.
- * We're willing to settle for a connection that needs Peer IP
- * instantiated: Road Warrior or Opportunistic.
- * Look on list of connections for host pair with wildcard Peer IP
+ /* The current connection won't do: search for one that will.
+ * First search for one with the same pair of hosts.
+ * If that fails, search for a suitable Road Warrior or Opportunistic
+ * connection (i.e. wildcard peer IP).
+ * We need to match:
+ * - peer_id (slightly complicated by instantiation)
+ * - if PSK auth, the key must not change (we used it to decode message)
+ * - policy-as-used must be acceptable to new connection
*/
- d = find_host_pair_connections(&c->spd.this.host_addr, c->spd.this.host_port
- , (ip_address *)NULL, c->spd.that.host_port);
- }
+ d = c->host_pair->connections;
+ for (wcpip = FALSE; ; wcpip = TRUE)
+ {
+ for (; d != NULL; d = d->hp_next)
+ {
+ const char *match_name[] = {"no", "ok"};
+
+ bool matching_id = match_id(peer_id
+ , &d->spd.that.id, &wildcards);
+ bool matching_auth = (d->policy & auth_policy) != LEMPTY;
+
+ bool matching_trust = trusted_ca(peer_ca
+ , d->spd.that.ca, &peer_pathlen);
+ bool matching_request = match_requested_ca(c->requested_ca
+ , d->spd.this.ca, &our_pathlen);
+ bool match = matching_id && matching_auth && matching_trust;
+
+ int prio = (MAX_WILDCARDS + 1) * !matching_request + wildcards;
+
+ prio = (MAX_CA_PATH_LEN + 1) * prio + peer_pathlen;
+ prio = (MAX_CA_PATH_LEN + 1) * prio + our_pathlen;
+
+ DBG(DBG_CONTROLMORE,
+ DBG_log("%s: %s match (id: %s, auth: %s, trust: %s, request: %s, prio: %4d)"
+ , d->name
+ , match ? "full":" no"
+ , match_name[matching_id]
+ , match_name[matching_auth]
+ , match_name[matching_trust]
+ , match_name[matching_request]
+ , match ? prio:PRIO_NO_MATCH_FOUND)
+ )
+
+ /* do we have a match? */
+ if (!match)
+ continue;
+
+ /* ignore group connections */
+ if (d->policy & POLICY_GROUP)
+ continue;
+
+ if (c->spd.that.host_port != d->spd.that.host_port
+ && d->kind == CK_INSTANCE)
+ {
+ continue;
+ }
+
+ switch (auth)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ /* secret must match the one we already used */
+ {
+ const chunk_t *dpsk = get_preshared_secret(d);
+
+ if (dpsk == NULL)
+ continue; /* no secret */
+
+ if (psk != dpsk)
+ if (psk->len != dpsk->len
+ || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0)
+ continue; /* different secret */
+ }
+ break;
+
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ /*
+ * We must at least be able to find our private key
+ .*/
+ if (d->spd.this.sc == NULL /* no smartcard */
+ && get_private_key(d) == NULL) /* no private key */
+ continue;
+ break;
+
+ default:
+ bad_case(auth);
+ }
+
+ /* d has passed all the tests.
+ * We'll go with it if the Peer ID was an exact match.
+ */
+ if (prio == 0)
+ {
+ return d;
+ }
+
+ /* We'll remember it as best_found in case an exact
+ * match doesn't come along.
+ */
+ if (prio < best_prio)
+ {
+ best_found = d;
+ best_prio = prio;
+ }
+ }
+ if (wcpip)
+ return best_found; /* been around twice already */
+
+ /* Starting second time around.
+ * We're willing to settle for a connection that needs Peer IP
+ * instantiated: Road Warrior or Opportunistic.
+ * Look on list of connections for host pair with wildcard Peer IP
+ */
+ d = find_host_pair_connections(&c->spd.this.host_addr, c->spd.this.host_port
+ , (ip_address *)NULL, c->spd.that.host_port);
+ }
}
/**
@@ -3456,35 +3458,35 @@ refine_host_connection(const struct state *st, const struct id *peer_id
static bool
is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id)
{
- struct connection *d;
+ struct connection *d;
- for (d = connections; d != NULL; d = d->ac_next)
- {
- switch (d->kind)
+ for (d = connections; d != NULL; d = d->ac_next)
{
- case CK_PERMANENT:
- case CK_INSTANCE:
- if ((subnetinsubnet(peer_net,&d->spd.that.client) ||
- subnetinsubnet(&d->spd.that.client,peer_net))
- && !same_id(&d->spd.that.id, peer_id))
- {
- char buf[BUF_LEN];
- char client[SUBNETTOT_BUF];
-
- subnettot(peer_net, 0, client, sizeof(client));
- idtoa(&d->spd.that.id, buf, sizeof(buf));
- plog("Virtual IP %s is already used by '%s'", client, buf);
- idtoa(peer_id, buf, sizeof(buf));
- plog("Your ID is '%s'", buf);
- return TRUE; /* already used by another one */
- }
- break;
- case CK_GOING_AWAY:
- default:
- break;
+ switch (d->kind)
+ {
+ case CK_PERMANENT:
+ case CK_INSTANCE:
+ if ((subnetinsubnet(peer_net,&d->spd.that.client) ||
+ subnetinsubnet(&d->spd.that.client,peer_net))
+ && !same_id(&d->spd.that.id, peer_id))
+ {
+ char buf[BUF_LEN];
+ char client[SUBNETTOT_BUF];
+
+ subnettot(peer_net, 0, client, sizeof(client));
+ idtoa(&d->spd.that.id, buf, sizeof(buf));
+ plog("Virtual IP %s is already used by '%s'", client, buf);
+ idtoa(peer_id, buf, sizeof(buf));
+ plog("Your ID is '%s'", buf);
+ return TRUE; /* already used by another one */
+ }
+ break;
+ case CK_GOING_AWAY:
+ default:
+ break;
+ }
}
- }
- return FALSE; /* you can safely use it */
+ return FALSE; /* you can safely use it */
}
/* find_client_connection: given a connection suitable for ISAKMP
@@ -3512,9 +3514,9 @@ is_virtual_net_used(const ip_subnet *peer_net, const struct id *peer_id)
* instantiation. They are the IDs that have been authenticated.
*/
-#define PATH_WEIGHT 1
-#define WILD_WEIGHT (MAX_CA_PATH_LEN+1)
-#define PRIO_WEIGHT (MAX_WILDCARDS+1)*WILD_WEIGHT
+#define PATH_WEIGHT 1
+#define WILD_WEIGHT (MAX_CA_PATH_LEN+1)
+#define PRIO_WEIGHT (MAX_WILDCARDS+1)*WILD_WEIGHT
/* fc_try: a helper function for find_client_connection */
static struct connection *
@@ -3530,121 +3532,121 @@ fc_try(const struct connection *c
, chunk_t peer_ca
, const ietfAttrList_t *peer_list)
{
- struct connection *d;
- struct connection *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- int wildcards, pathlen;
-
- const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr);
-
- for (d = hp->connections; d != NULL; d = d->hp_next)
- {
- struct spd_route *sr;
+ struct connection *d;
+ struct connection *best = NULL;
+ policy_prio_t best_prio = BOTTOM_PRIO;
+ int wildcards, pathlen;
- if (d->policy & POLICY_GROUP)
- continue;
-
- if (!(same_id(&c->spd.this.id, &d->spd.this.id)
- && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
- && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
- && group_membership(peer_list, d->name, d->spd.that.groups)))
- continue;
-
- /* compare protocol and ports */
- if (d->spd.this.protocol != our_protocol
- || d->spd.this.port != our_port
- || d->spd.that.protocol != peer_protocol
- || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
- continue;
-
- /* non-Opportunistic case:
- * our_client must match.
- *
- * So must peer_client, but the testing is complicated
- * by the fact that the peer might be a wildcard
- * and if so, the default value of that.client
- * won't match the default peer_net. The appropriate test:
- *
- * If d has a peer client, it must match peer_net.
- * If d has no peer client, peer_net must just have peer itself.
- */
+ const bool peer_net_is_host = subnetisaddr(peer_net, &c->spd.that.host_addr);
- for (sr = &d->spd; best != d && sr != NULL; sr = sr->next)
+ for (d = hp->connections; d != NULL; d = d->hp_next)
{
- policy_prio_t prio;
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
- char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
+ struct spd_route *sr;
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
- subnettot(&sr->this.client, 0, s3, sizeof(s3));
- subnettot(&sr->that.client, 0, d3, sizeof(d3));
- DBG_log(" fc_try trying "
- "%s:%s:%d/%d -> %s:%d/%d vs %s:%s:%d/%d -> %s:%d/%d"
- , c->name, s1, c->spd.this.protocol, c->spd.this.port
- , d1, c->spd.that.protocol, c->spd.that.port
- , d->name, s3, sr->this.protocol, sr->this.port
- , d3, sr->that.protocol, sr->that.port);
- }
-#endif /* DEBUG */
+ if (d->policy & POLICY_GROUP)
+ continue;
- if (!samesubnet(&sr->this.client, our_net))
- continue;
+ if (!(same_id(&c->spd.this.id, &d->spd.this.id)
+ && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
+ && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
+ && group_membership(peer_list, d->name, d->spd.that.groups)))
+ continue;
- if (sr->that.has_client)
- {
- if (sr->that.has_client_wildcard)
- {
- if (!subnetinsubnet(peer_net, &sr->that.client))
+ /* compare protocol and ports */
+ if (d->spd.this.protocol != our_protocol
+ || d->spd.this.port != our_port
+ || d->spd.that.protocol != peer_protocol
+ || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
continue;
- }
- else
+
+ /* non-Opportunistic case:
+ * our_client must match.
+ *
+ * So must peer_client, but the testing is complicated
+ * by the fact that the peer might be a wildcard
+ * and if so, the default value of that.client
+ * won't match the default peer_net. The appropriate test:
+ *
+ * If d has a peer client, it must match peer_net.
+ * If d has no peer client, peer_net must just have peer itself.
+ */
+
+ for (sr = &d->spd; best != d && sr != NULL; sr = sr->next)
{
- if (!samesubnet(&sr->that.client, peer_net) && !is_virtual_connection(d))
- continue;
- if (is_virtual_connection(d)
- && (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr)
- || is_virtual_net_used(peer_net, peer_id?peer_id:&c->spd.that.id)))
- continue;
+ policy_prio_t prio;
+#ifdef DEBUG
+ if (DBGP(DBG_CONTROLMORE))
+ {
+ char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
+ char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
+
+ subnettot(our_net, 0, s1, sizeof(s1));
+ subnettot(peer_net, 0, d1, sizeof(d1));
+ subnettot(&sr->this.client, 0, s3, sizeof(s3));
+ subnettot(&sr->that.client, 0, d3, sizeof(d3));
+ DBG_log(" fc_try trying "
+ "%s:%s:%d/%d -> %s:%d/%d vs %s:%s:%d/%d -> %s:%d/%d"
+ , c->name, s1, c->spd.this.protocol, c->spd.this.port
+ , d1, c->spd.that.protocol, c->spd.that.port
+ , d->name, s3, sr->this.protocol, sr->this.port
+ , d3, sr->that.protocol, sr->that.port);
+ }
+#endif /* DEBUG */
+
+ if (!samesubnet(&sr->this.client, our_net))
+ continue;
+
+ if (sr->that.has_client)
+ {
+ if (sr->that.has_client_wildcard)
+ {
+ if (!subnetinsubnet(peer_net, &sr->that.client))
+ continue;
+ }
+ else
+ {
+ if (!samesubnet(&sr->that.client, peer_net) && !is_virtual_connection(d))
+ continue;
+ if (is_virtual_connection(d)
+ && (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr)
+ || is_virtual_net_used(peer_net, peer_id?peer_id:&c->spd.that.id)))
+ continue;
+ }
+ }
+ else
+ {
+ if (!peer_net_is_host)
+ continue;
+ }
+
+ /* We've run the gauntlet -- success:
+ * We've got an exact match of subnets.
+ * The connection is feasible, but we continue looking for the best.
+ * The highest priority wins, implementing eroute-like rule.
+ * - a routed connection is preferrred
+ * - given that, the smallest number of ID wildcards are preferred
+ * - given that, the shortest CA pathlength is preferred
+ */
+ prio = PRIO_WEIGHT * routed(sr->routing)
+ + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
+ + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen)
+ + 1;
+ if (prio > best_prio)
+ {
+ best = d;
+ best_prio = prio;
+ }
}
- }
- else
- {
- if (!peer_net_is_host)
- continue;
- }
-
- /* We've run the gauntlet -- success:
- * We've got an exact match of subnets.
- * The connection is feasible, but we continue looking for the best.
- * The highest priority wins, implementing eroute-like rule.
- * - a routed connection is preferrred
- * - given that, the smallest number of ID wildcards are preferred
- * - given that, the shortest CA pathlength is preferred
- */
- prio = PRIO_WEIGHT * routed(sr->routing)
- + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
- + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen)
- + 1;
- if (prio > best_prio)
- {
- best = d;
- best_prio = prio;
- }
}
- }
- if (best != NULL && NEVER_NEGOTIATE(best->policy))
- best = NULL;
+ if (best != NULL && NEVER_NEGOTIATE(best->policy))
+ best = NULL;
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try concluding with %s [%ld]"
- , (best ? best->name : "none"), best_prio)
- )
- return best;
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" fc_try concluding with %s [%ld]"
+ , (best ? best->name : "none"), best_prio)
+ )
+ return best;
}
static struct connection *
@@ -3659,92 +3661,92 @@ fc_try_oppo(const struct connection *c
, chunk_t peer_ca
, const ietfAttrList_t *peer_list)
{
- struct connection *d;
- struct connection *best = NULL;
- policy_prio_t best_prio = BOTTOM_PRIO;
- int wildcards, pathlen;
+ struct connection *d;
+ struct connection *best = NULL;
+ policy_prio_t best_prio = BOTTOM_PRIO;
+ int wildcards, pathlen;
- for (d = hp->connections; d != NULL; d = d->hp_next)
- {
- struct spd_route *sr;
- policy_prio_t prio;
-
- if (d->policy & POLICY_GROUP)
- continue;
-
- if (!(same_id(&c->spd.this.id, &d->spd.this.id)
- && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
- && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
- && group_membership(peer_list, d->name, d->spd.that.groups)))
- continue;
-
- /* compare protocol and ports */
- if (d->spd.this.protocol != our_protocol
- || d->spd.this.port != our_port
- || d->spd.that.protocol != peer_protocol
- || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
- continue;
-
- /* Opportunistic case:
- * our_net must be inside d->spd.this.client
- * and peer_net must be inside d->spd.that.client
- * Note: this host_pair chain also has shunt
- * eroute conns (clear, drop), but they won't
- * be marked as opportunistic.
- */
- for (sr = &d->spd; sr != NULL; sr = sr->next)
+ for (d = hp->connections; d != NULL; d = d->hp_next)
{
-#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
- char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
+ struct spd_route *sr;
+ policy_prio_t prio;
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
- subnettot(&sr->this.client, 0, s3, sizeof(s3));
- subnettot(&sr->that.client, 0, d3, sizeof(d3));
- DBG_log(" fc_try_oppo trying %s:%s -> %s vs %s:%s -> %s"
- , c->name, s1, d1, d->name, s3, d3);
- }
+ if (d->policy & POLICY_GROUP)
+ continue;
+
+ if (!(same_id(&c->spd.this.id, &d->spd.this.id)
+ && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
+ && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
+ && group_membership(peer_list, d->name, d->spd.that.groups)))
+ continue;
+
+ /* compare protocol and ports */
+ if (d->spd.this.protocol != our_protocol
+ || d->spd.this.port != our_port
+ || d->spd.that.protocol != peer_protocol
+ || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
+ continue;
+
+ /* Opportunistic case:
+ * our_net must be inside d->spd.this.client
+ * and peer_net must be inside d->spd.that.client
+ * Note: this host_pair chain also has shunt
+ * eroute conns (clear, drop), but they won't
+ * be marked as opportunistic.
+ */
+ for (sr = &d->spd; sr != NULL; sr = sr->next)
+ {
+#ifdef DEBUG
+ if (DBGP(DBG_CONTROLMORE))
+ {
+ char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
+ char s3[SUBNETTOT_BUF],d3[SUBNETTOT_BUF];
+
+ subnettot(our_net, 0, s1, sizeof(s1));
+ subnettot(peer_net, 0, d1, sizeof(d1));
+ subnettot(&sr->this.client, 0, s3, sizeof(s3));
+ subnettot(&sr->that.client, 0, d3, sizeof(d3));
+ DBG_log(" fc_try_oppo trying %s:%s -> %s vs %s:%s -> %s"
+ , c->name, s1, d1, d->name, s3, d3);
+ }
#endif /* DEBUG */
- if (!subnetinsubnet(our_net, &sr->this.client)
- || !subnetinsubnet(peer_net, &sr->that.client))
- continue;
-
- /* The connection is feasible, but we continue looking for the best.
- * The highest priority wins, implementing eroute-like rule.
- * - our smallest client subnet is preferred (longest mask)
- * - given that, his smallest client subnet is preferred
- * - given that, a routed connection is preferrred
- * - given that, the smallest number of ID wildcards are preferred
- * - given that, the shortest CA pathlength is preferred
- */
- prio = PRIO_WEIGHT * (d->prio + routed(sr->routing))
- + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
- + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen);
- if (prio > best_prio)
- {
- best = d;
- best_prio = prio;
- }
+ if (!subnetinsubnet(our_net, &sr->this.client)
+ || !subnetinsubnet(peer_net, &sr->that.client))
+ continue;
+
+ /* The connection is feasible, but we continue looking for the best.
+ * The highest priority wins, implementing eroute-like rule.
+ * - our smallest client subnet is preferred (longest mask)
+ * - given that, his smallest client subnet is preferred
+ * - given that, a routed connection is preferrred
+ * - given that, the smallest number of ID wildcards are preferred
+ * - given that, the shortest CA pathlength is preferred
+ */
+ prio = PRIO_WEIGHT * (d->prio + routed(sr->routing))
+ + WILD_WEIGHT * (MAX_WILDCARDS - wildcards)
+ + PATH_WEIGHT * (MAX_CA_PATH_LEN - pathlen);
+ if (prio > best_prio)
+ {
+ best = d;
+ best_prio = prio;
+ }
+ }
+ }
+
+ /* if the best wasn't opportunistic, we fail: it must be a shunt */
+ if (best != NULL
+ && (NEVER_NEGOTIATE(best->policy)
+ || (best->policy & POLICY_OPPO) == LEMPTY))
+ {
+ best = NULL;
}
- }
-
- /* if the best wasn't opportunistic, we fail: it must be a shunt */
- if (best != NULL
- && (NEVER_NEGOTIATE(best->policy)
- || (best->policy & POLICY_OPPO) == LEMPTY))
- {
- best = NULL;
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try_oppo concluding with %s [%ld]"
- , (best ? best->name : "none"), best_prio)
- )
- return best;
+
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" fc_try_oppo concluding with %s [%ld]"
+ , (best ? best->name : "none"), best_prio)
+ )
+ return best;
}
@@ -3754,28 +3756,28 @@ fc_try_oppo(const struct connection *c
chunk_t
get_peer_ca_and_groups(struct connection *c, const ietfAttrList_t **peer_list)
{
- struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
-
- *peer_list = NULL;
+ struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
- if (p1st != NULL
- && p1st->st_peer_pubkey != NULL
- && p1st->st_peer_pubkey->issuer.ptr != NULL)
- {
- x509acert_t *ac = get_x509acert(p1st->st_peer_pubkey->issuer
- , p1st->st_peer_pubkey->serial);;
+ *peer_list = NULL;
- if (ac != NULL && verify_x509acert(ac, strict_crl_policy))
- *peer_list = ac->groups;
- else
+ if (p1st != NULL
+ && p1st->st_peer_pubkey != NULL
+ && p1st->st_peer_pubkey->issuer.ptr != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("no valid attribute cert found")
- )
+ x509acert_t *ac = get_x509acert(p1st->st_peer_pubkey->issuer
+ , p1st->st_peer_pubkey->serial);;
+
+ if (ac != NULL && verify_x509acert(ac, strict_crl_policy))
+ *peer_list = ac->groups;
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("no valid attribute cert found")
+ )
+ }
+ return p1st->st_peer_pubkey->issuer;
}
- return p1st->st_peer_pubkey->issuer;
- }
- return empty_chunk;
+ return chunk_empty;
}
struct connection *
@@ -3784,325 +3786,325 @@ find_client_connection(struct connection *c
, const u_int8_t our_protocol, const u_int16_t our_port
, const u_int8_t peer_protocol, const u_int16_t peer_port)
{
- struct connection *d;
- struct spd_route *sr;
+ struct connection *d;
+ struct spd_route *sr;
- const ietfAttrList_t *peer_list = NULL;
- chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_list);
+ const ietfAttrList_t *peer_list = NULL;
+ chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_list);
#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
-
- subnettot(our_net, 0, s1, sizeof(s1));
- subnettot(peer_net, 0, d1, sizeof(d1));
-
- DBG_log("find_client_connection starting with %s"
- , (c ? c->name : "(none)"));
- DBG_log(" looking for %s:%d/%d -> %s:%d/%d"
- , s1, our_protocol, our_port
- , d1, peer_protocol, peer_port);
- }
-#endif /* DEBUG */
+ if (DBGP(DBG_CONTROLMORE))
+ {
+ char s1[SUBNETTOT_BUF],d1[SUBNETTOT_BUF];
- /* give priority to current connection
- * but even greater priority to a routed concrete connection
- */
- {
- struct connection *unrouted = NULL;
- int srnum = -1;
+ subnettot(our_net, 0, s1, sizeof(s1));
+ subnettot(peer_net, 0, d1, sizeof(d1));
+
+ DBG_log("find_client_connection starting with %s"
+ , (c ? c->name : "(none)"));
+ DBG_log(" looking for %s:%d/%d -> %s:%d/%d"
+ , s1, our_protocol, our_port
+ , d1, peer_protocol, peer_port);
+ }
+#endif /* DEBUG */
- for (sr = &c->spd; unrouted == NULL && sr != NULL; sr = sr->next)
+ /* give priority to current connection
+ * but even greater priority to a routed concrete connection
+ */
{
- srnum++;
+ struct connection *unrouted = NULL;
+ int srnum = -1;
+
+ for (sr = &c->spd; unrouted == NULL && sr != NULL; sr = sr->next)
+ {
+ srnum++;
#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
-
- subnettot(&sr->this.client, 0, s2, sizeof(s2));
- subnettot(&sr->that.client, 0, d2, sizeof(d2));
- DBG_log(" concrete checking against sr#%d %s -> %s"
- , srnum, s2, d2);
- }
+ if (DBGP(DBG_CONTROLMORE))
+ {
+ char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
+
+ subnettot(&sr->this.client, 0, s2, sizeof(s2));
+ subnettot(&sr->that.client, 0, d2, sizeof(d2));
+ DBG_log(" concrete checking against sr#%d %s -> %s"
+ , srnum, s2, d2);
+ }
#endif /* DEBUG */
- if (samesubnet(&sr->this.client, our_net)
- && samesubnet(&sr->that.client, peer_net)
- && sr->this.protocol == our_protocol
- && sr->this.port == our_port
- && sr->that.protocol == peer_protocol
- && sr->that.port == peer_port
- && group_membership(peer_list, c->name, sr->that.groups))
- {
- passert(oriented(*c));
- if (routed(sr->routing))
- return c;
-
- unrouted = c;
- }
- }
+ if (samesubnet(&sr->this.client, our_net)
+ && samesubnet(&sr->that.client, peer_net)
+ && sr->this.protocol == our_protocol
+ && sr->this.port == our_port
+ && sr->that.protocol == peer_protocol
+ && sr->that.port == peer_port
+ && group_membership(peer_list, c->name, sr->that.groups))
+ {
+ passert(oriented(*c));
+ if (routed(sr->routing))
+ return c;
- /* exact match? */
- d = fc_try(c, c->host_pair, NULL, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
+ unrouted = c;
+ }
+ }
- DBG(DBG_CONTROLMORE,
- DBG_log(" fc_try %s gives %s"
- , c->name
- , (d ? d->name : "none"))
- )
+ /* exact match? */
+ d = fc_try(c, c->host_pair, NULL, our_net, peer_net
+ , our_protocol, our_port, peer_protocol, peer_port
+ , peer_ca, peer_list);
- if (d == NULL)
- d = unrouted;
- }
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" fc_try %s gives %s"
+ , c->name
+ , (d ? d->name : "none"))
+ )
- if (d == NULL)
- {
- /* look for an abstract connection to match */
- struct spd_route *sr;
- struct host_pair *hp = NULL;
+ if (d == NULL)
+ d = unrouted;
+ }
- for (sr = &c->spd; hp==NULL && sr != NULL; sr = sr->next)
+ if (d == NULL)
{
- hp = find_host_pair(&sr->this.host_addr
- , sr->this.host_port
- , NULL
- , sr->that.host_port);
+ /* look for an abstract connection to match */
+ struct spd_route *sr;
+ struct host_pair *hp = NULL;
+
+ for (sr = &c->spd; hp==NULL && sr != NULL; sr = sr->next)
+ {
+ hp = find_host_pair(&sr->this.host_addr
+ , sr->this.host_port
+ , NULL
+ , sr->that.host_port);
#ifdef DEBUG
- if (DBGP(DBG_CONTROLMORE))
- {
- char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
+ if (DBGP(DBG_CONTROLMORE))
+ {
+ char s2[SUBNETTOT_BUF],d2[SUBNETTOT_BUF];
- subnettot(&sr->this.client, 0, s2, sizeof(s2));
- subnettot(&sr->that.client, 0, d2, sizeof(d2));
+ subnettot(&sr->this.client, 0, s2, sizeof(s2));
+ subnettot(&sr->that.client, 0, d2, sizeof(d2));
- DBG_log(" checking hostpair %s -> %s is %s"
- , s2, d2
- , (hp ? "found" : "not found"));
- }
+ DBG_log(" checking hostpair %s -> %s is %s"
+ , s2, d2
+ , (hp ? "found" : "not found"));
+ }
#endif /* DEBUG */
- }
+ }
- if (hp != NULL)
- {
- /* RW match with actual peer_id or abstract peer_id? */
- d = fc_try(c, hp, NULL, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
-
- if (d == NULL
- && subnetishost(our_net)
- && subnetishost(peer_net))
- {
- /* Opportunistic match?
- * Always use abstract peer_id.
- * Note that later instantiation will result in the same peer_id.
- */
- d = fc_try_oppo(c, hp, our_net, peer_net
- , our_protocol, our_port, peer_protocol, peer_port
- , peer_ca, peer_list);
- }
+ if (hp != NULL)
+ {
+ /* RW match with actual peer_id or abstract peer_id? */
+ d = fc_try(c, hp, NULL, our_net, peer_net
+ , our_protocol, our_port, peer_protocol, peer_port
+ , peer_ca, peer_list);
+
+ if (d == NULL
+ && subnetishost(our_net)
+ && subnetishost(peer_net))
+ {
+ /* Opportunistic match?
+ * Always use abstract peer_id.
+ * Note that later instantiation will result in the same peer_id.
+ */
+ d = fc_try_oppo(c, hp, our_net, peer_net
+ , our_protocol, our_port, peer_protocol, peer_port
+ , peer_ca, peer_list);
+ }
+ }
}
- }
- DBG(DBG_CONTROLMORE,
- DBG_log(" concluding with d = %s"
- , (d ? d->name : "none"))
- )
- return d;
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" concluding with d = %s"
+ , (d ? d->name : "none"))
+ )
+ return d;
}
int
connection_compare(const struct connection *ca
, const struct connection *cb)
{
- int ret;
-
- /* DBG_log("comparing %s to %s", ca->name, cb->name); */
-
- ret = strcasecmp(ca->name, cb->name);
- if (ret != 0)
- return ret;
-
- ret = ca->kind - cb->kind; /* note: enum connection_kind behaves like int */
- if (ret != 0)
- return ret;
-
- /* same name, and same type */
- switch (ca->kind)
- {
- case CK_INSTANCE:
- return ca->instance_serial < cb->instance_serial ? -1
- : ca->instance_serial > cb->instance_serial ? 1
- : 0;
-
- default:
- return ca->prio < cb->prio ? -1
- : ca->prio > cb->prio ? 1
- : 0;
- }
+ int ret;
+
+ /* DBG_log("comparing %s to %s", ca->name, cb->name); */
+
+ ret = strcasecmp(ca->name, cb->name);
+ if (ret != 0)
+ return ret;
+
+ ret = ca->kind - cb->kind; /* note: enum connection_kind behaves like int */
+ if (ret != 0)
+ return ret;
+
+ /* same name, and same type */
+ switch (ca->kind)
+ {
+ case CK_INSTANCE:
+ return ca->instance_serial < cb->instance_serial ? -1
+ : ca->instance_serial > cb->instance_serial ? 1
+ : 0;
+
+ default:
+ return ca->prio < cb->prio ? -1
+ : ca->prio > cb->prio ? 1
+ : 0;
+ }
}
static int
connection_compare_qsort(const void *a, const void *b)
{
- return connection_compare(*(const struct connection *const *)a
- , *(const struct connection *const *)b);
+ return connection_compare(*(const struct connection *const *)a
+ , *(const struct connection *const *)b);
}
void
show_connections_status(bool all, const char *name)
{
- struct connection *c;
- int count, i;
- struct connection **array;
-
- /* make an array of connections, and sort it */
- count = 0;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->ikev1 && (name == NULL || streq(c->name, name)))
- count++;
- }
- array = alloc_bytes(sizeof(struct connection *)*count, "connection array");
-
- count=0;
- for (c = connections; c != NULL; c = c->ac_next)
- {
- if (c->ikev1 && (name == NULL || streq(c->name, name)))
- array[count++]=c;
- }
-
- /* sort it! */
- qsort(array, count, sizeof(struct connection *), connection_compare_qsort);
-
- for (i = 0; i < count; i++)
- {
- const char *ifn;
- char instance[1 + 10 + 1];
- char prio[POLICY_PRIO_BUF];
-
- c = array[i];
-
- ifn = oriented(*c)? c->interface->rname : "";
-
- instance[0] = '\0';
- if (c->kind == CK_INSTANCE && c->instance_serial != 0)
- snprintf(instance, sizeof(instance), "[%lu]", c->instance_serial);
-
- /* show topology */
+ struct connection *c;
+ int count, i;
+ struct connection **array;
+
+ /* make an array of connections, and sort it */
+ count = 0;
+ for (c = connections; c != NULL; c = c->ac_next)
{
- char topo[CONNECTION_BUF];
- struct spd_route *sr = &c->spd;
- int num=0;
-
- while (sr != NULL)
- {
- (void) format_connection(topo, sizeof(topo), c, sr);
- whack_log(RC_COMMENT, "\"%s\"%s: %s; %s; eroute owner: #%lu"
- , c->name, instance, topo
- , enum_name(&routing_story, sr->routing)
- , sr->eroute_owner);
- sr = sr->next;
- num++;
- }
+ if (c->ikev1 && (name == NULL || streq(c->name, name)))
+ count++;
}
+ array = malloc(sizeof(struct connection *)*count);
- if (all)
+ count=0;
+ for (c = connections; c != NULL; c = c->ac_next)
{
- /* show CAs if defined */
- if (c->spd.this.ca.ptr != NULL || c->spd.that.ca.ptr != NULL)
- {
- char this_ca[BUF_LEN], that_ca[BUF_LEN];
-
- dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any");
- dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any");
-
- whack_log(RC_COMMENT
- , "\"%s\"%s: CAs: '%s'...'%s'"
- , c->name
- , instance
- , this_ca
- , that_ca);
- }
-
- /* show group attributes if defined */
- if (c->spd.that.groups != NULL)
- {
- char buf[BUF_LEN];
-
- format_groups(c->spd.that.groups, buf, BUF_LEN);
- whack_log(RC_COMMENT
- , "\"%s\"%s: groups: %s"
- , c->name
- , instance
- , buf);
- }
-
- whack_log(RC_COMMENT
- , "\"%s\"%s: ike_life: %lus; ipsec_life: %lus;"
- " rekey_margin: %lus; rekey_fuzz: %lu%%; keyingtries: %lu"
- , c->name
- , instance
- , (unsigned long) c->sa_ike_life_seconds
- , (unsigned long) c->sa_ipsec_life_seconds
- , (unsigned long) c->sa_rekey_margin
- , (unsigned long) c->sa_rekey_fuzz
- , (unsigned long) c->sa_keying_tries);
-
- /* show DPD parameters if defined */
-
- if (c->dpd_action != DPD_ACTION_NONE)
- whack_log(RC_COMMENT
- , "\"%s\"%s: dpd_action: %s;"
- " dpd_delay: %lus; dpd_timeout: %lus;"
- , c->name
- , instance
- , enum_show(&dpd_action_names, c->dpd_action)
- , (unsigned long) c->dpd_delay
- , (unsigned long) c->dpd_timeout);
-
- if (c->policy_next)
- {
- whack_log(RC_COMMENT
- , "\"%s\"%s: policy_next: %s"
- , c->name, instance, c->policy_next->name);
- }
-
- /* Note: we display key_from_DNS_on_demand as if policy [lr]KOD */
- fmt_policy_prio(c->prio, prio);
- whack_log(RC_COMMENT
- , "\"%s\"%s: policy: %s%s%s; prio: %s; interface: %s; "
- , c->name
- , instance
- , prettypolicy(c->policy)
- , c->spd.this.key_from_DNS_on_demand? "+lKOD" : ""
- , c->spd.that.key_from_DNS_on_demand? "+rKOD" : ""
- , prio
- , ifn);
+ if (c->ikev1 && (name == NULL || streq(c->name, name)))
+ array[count++]=c;
}
- whack_log(RC_COMMENT
- , "\"%s\"%s: newest ISAKMP SA: #%ld; newest IPsec SA: #%ld; "
- , c->name
- , instance
- , c->newest_isakmp_sa
- , c->newest_ipsec_sa);
-
- if (all)
+ /* sort it! */
+ qsort(array, count, sizeof(struct connection *), connection_compare_qsort);
+
+ for (i = 0; i < count; i++)
{
- ike_alg_show_connection(c, instance);
- kernel_alg_show_connection(c, instance);
+ const char *ifn;
+ char instance[1 + 10 + 1];
+ char prio[POLICY_PRIO_BUF];
+
+ c = array[i];
+
+ ifn = oriented(*c)? c->interface->rname : "";
+
+ instance[0] = '\0';
+ if (c->kind == CK_INSTANCE && c->instance_serial != 0)
+ snprintf(instance, sizeof(instance), "[%lu]", c->instance_serial);
+
+ /* show topology */
+ {
+ char topo[CONNECTION_BUF];
+ struct spd_route *sr = &c->spd;
+ int num=0;
+
+ while (sr != NULL)
+ {
+ (void) format_connection(topo, sizeof(topo), c, sr);
+ whack_log(RC_COMMENT, "\"%s\"%s: %s; %s; eroute owner: #%lu"
+ , c->name, instance, topo
+ , enum_name(&routing_story, sr->routing)
+ , sr->eroute_owner);
+ sr = sr->next;
+ num++;
+ }
+ }
+
+ if (all)
+ {
+ /* show CAs if defined */
+ if (c->spd.this.ca.ptr != NULL || c->spd.that.ca.ptr != NULL)
+ {
+ char this_ca[BUF_LEN], that_ca[BUF_LEN];
+
+ dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any");
+ dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any");
+
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: CAs: '%s'...'%s'"
+ , c->name
+ , instance
+ , this_ca
+ , that_ca);
+ }
+
+ /* show group attributes if defined */
+ if (c->spd.that.groups != NULL)
+ {
+ char buf[BUF_LEN];
+
+ format_groups(c->spd.that.groups, buf, BUF_LEN);
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: groups: %s"
+ , c->name
+ , instance
+ , buf);
+ }
+
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: ike_life: %lus; ipsec_life: %lus;"
+ " rekey_margin: %lus; rekey_fuzz: %lu%%; keyingtries: %lu"
+ , c->name
+ , instance
+ , (unsigned long) c->sa_ike_life_seconds
+ , (unsigned long) c->sa_ipsec_life_seconds
+ , (unsigned long) c->sa_rekey_margin
+ , (unsigned long) c->sa_rekey_fuzz
+ , (unsigned long) c->sa_keying_tries);
+
+ /* show DPD parameters if defined */
+
+ if (c->dpd_action != DPD_ACTION_NONE)
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: dpd_action: %N;"
+ " dpd_delay: %lus; dpd_timeout: %lus;"
+ , c->name
+ , instance
+ , dpd_action_names, c->dpd_action
+ , (unsigned long) c->dpd_delay
+ , (unsigned long) c->dpd_timeout);
+
+ if (c->policy_next)
+ {
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: policy_next: %s"
+ , c->name, instance, c->policy_next->name);
+ }
+
+ /* Note: we display key_from_DNS_on_demand as if policy [lr]KOD */
+ fmt_policy_prio(c->prio, prio);
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: policy: %s%s%s; prio: %s; interface: %s; "
+ , c->name
+ , instance
+ , prettypolicy(c->policy)
+ , c->spd.this.key_from_DNS_on_demand? "+lKOD" : ""
+ , c->spd.that.key_from_DNS_on_demand? "+rKOD" : ""
+ , prio
+ , ifn);
+ }
+
+ whack_log(RC_COMMENT
+ , "\"%s\"%s: newest ISAKMP SA: #%ld; newest IPsec SA: #%ld; "
+ , c->name
+ , instance
+ , c->newest_isakmp_sa
+ , c->newest_ipsec_sa);
+
+ if (all)
+ {
+ ike_alg_show_connection(c, instance);
+ kernel_alg_show_connection(c, instance);
+ }
}
- }
- if (count > 0)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
+ if (count > 0)
+ whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
- pfree(array);
+ free(array);
}
/* struct pending, the structure representing Quick Mode
@@ -4111,14 +4113,14 @@ show_connections_status(bool all, const char *name)
*/
struct pending {
- int whack_sock;
- struct state *isakmp_sa;
- struct connection *connection;
- lset_t policy;
- unsigned long try;
- so_serial_t replacing;
-
- struct pending *next;
+ int whack_sock;
+ struct state *isakmp_sa;
+ struct connection *connection;
+ lset_t policy;
+ unsigned long try;
+ so_serial_t replacing;
+
+ struct pending *next;
};
/* queue a Quick Mode negotiation pending completion of a suitable Main Mode */
@@ -4130,36 +4132,36 @@ add_pending(int whack_sock
, unsigned long try
, so_serial_t replacing)
{
- bool already_queued = FALSE;
- struct pending *p = c->host_pair->pending;
+ bool already_queued = FALSE;
+ struct pending *p = c->host_pair->pending;
- while (p != NULL)
- {
- if (streq(c->name, p->connection->name))
+ while (p != NULL)
{
- already_queued = TRUE;
- break;
+ if (streq(c->name, p->connection->name))
+ {
+ already_queued = TRUE;
+ break;
+ }
+ p = p->next;
}
- p = p->next;
- }
- DBG(DBG_CONTROL,
- DBG_log("Queuing pending Quick Mode with %s \"%s\"%s"
- , ip_str(&c->spd.that.host_addr)
- , c->name
- , already_queued? " already done" : "")
- )
- if (already_queued)
- return;
-
- p = alloc_thing(struct pending, "struct pending");
- p->whack_sock = whack_sock;
- p->isakmp_sa = isakmp_sa;
- p->connection = c;
- p->policy = policy;
- p->try = try;
- p->replacing = replacing;
- p->next = c->host_pair->pending;
- c->host_pair->pending = p;
+ DBG(DBG_CONTROL,
+ DBG_log("Queuing pending Quick Mode with %s \"%s\"%s"
+ , ip_str(&c->spd.that.host_addr)
+ , c->name
+ , already_queued? " already done" : "")
+ )
+ if (already_queued)
+ return;
+
+ p = malloc_thing(struct pending);
+ p->whack_sock = whack_sock;
+ p->isakmp_sa = isakmp_sa;
+ p->connection = c;
+ p->policy = policy;
+ p->try = try;
+ p->replacing = replacing;
+ p->next = c->host_pair->pending;
+ c->host_pair->pending = p;
}
/* Release all the whacks awaiting the completion of this state.
@@ -4169,157 +4171,157 @@ add_pending(int whack_sock
void
release_pending_whacks(struct state *st, err_t story)
{
- struct pending *p;
- struct stat stst;
+ struct pending *p;
+ struct stat stst;
- if (st->st_whack_sock == NULL_FD || fstat(st->st_whack_sock, &stst) != 0)
- zero(&stst); /* resulting st_dev/st_ino ought to be distinct */
+ if (st->st_whack_sock == NULL_FD || fstat(st->st_whack_sock, &stst) != 0)
+ zero(&stst); /* resulting st_dev/st_ino ought to be distinct */
- release_whack(st);
+ release_whack(st);
- for (p = st->st_connection->host_pair->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == st && p->whack_sock != NULL_FD)
+ for (p = st->st_connection->host_pair->pending; p != NULL; p = p->next)
{
- struct stat pst;
+ if (p->isakmp_sa == st && p->whack_sock != NULL_FD)
+ {
+ struct stat pst;
- if (fstat(p->whack_sock, &pst) == 0
- && (stst.st_dev != pst.st_dev || stst.st_ino != pst.st_ino))
- {
- passert(whack_log_fd == NULL_FD);
- whack_log_fd = p->whack_sock;
- whack_log(RC_COMMENT
- , "%s for ISAKMP SA, but releasing whack for pending IPSEC SA"
- , story);
- whack_log_fd = NULL_FD;
- }
- close(p->whack_sock);
- p->whack_sock = NULL_FD;
+ if (fstat(p->whack_sock, &pst) == 0
+ && (stst.st_dev != pst.st_dev || stst.st_ino != pst.st_ino))
+ {
+ passert(whack_log_fd == NULL_FD);
+ whack_log_fd = p->whack_sock;
+ whack_log(RC_COMMENT
+ , "%s for ISAKMP SA, but releasing whack for pending IPSEC SA"
+ , story);
+ whack_log_fd = NULL_FD;
+ }
+ close(p->whack_sock);
+ p->whack_sock = NULL_FD;
+ }
}
- }
}
static void
delete_pending(struct pending **pp)
{
- struct pending *p = *pp;
+ struct pending *p = *pp;
- *pp = p->next;
- if (p->connection != NULL)
- connection_discard(p->connection);
- close_any(p->whack_sock);
- pfree(p);
+ *pp = p->next;
+ if (p->connection != NULL)
+ connection_discard(p->connection);
+ close_any(p->whack_sock);
+ free(p);
}
void
unpend(struct state *st)
{
- struct pending **pp
- , *p;
+ struct pending **pp
+ , *p;
- for (pp = &st->st_connection->host_pair->pending; (p = *pp) != NULL; )
- {
- if (p->isakmp_sa == st)
- {
- DBG(DBG_CONTROL, DBG_log("unqueuing pending Quick Mode with %s \"%s\""
- , ip_str(&p->connection->spd.that.host_addr)
- , p->connection->name));
- (void) quick_outI1(p->whack_sock, st, p->connection, p->policy
- , p->try, p->replacing);
- p->whack_sock = NULL_FD; /* ownership transferred */
- p->connection = NULL; /* ownership transferred */
- delete_pending(pp);
- }
- else
+ for (pp = &st->st_connection->host_pair->pending; (p = *pp) != NULL; )
{
- pp = &p->next;
+ if (p->isakmp_sa == st)
+ {
+ DBG(DBG_CONTROL, DBG_log("unqueuing pending Quick Mode with %s \"%s\""
+ , ip_str(&p->connection->spd.that.host_addr)
+ , p->connection->name));
+ (void) quick_outI1(p->whack_sock, st, p->connection, p->policy
+ , p->try, p->replacing);
+ p->whack_sock = NULL_FD; /* ownership transferred */
+ p->connection = NULL; /* ownership transferred */
+ delete_pending(pp);
+ }
+ else
+ {
+ pp = &p->next;
+ }
}
- }
}
/* a Main Mode negotiation has been replaced; update any pending */
void
update_pending(struct state *os, struct state *ns)
{
- struct pending *p;
+ struct pending *p;
- for (p = os->st_connection->host_pair->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == os)
- p->isakmp_sa = ns;
- if (p->connection->spd.this.host_port != ns->st_connection->spd.this.host_port)
+ for (p = os->st_connection->host_pair->pending; p != NULL; p = p->next)
{
- p->connection->spd.this.host_port = ns->st_connection->spd.this.host_port;
- p->connection->spd.that.host_port = ns->st_connection->spd.that.host_port;
+ if (p->isakmp_sa == os)
+ p->isakmp_sa = ns;
+ if (p->connection->spd.this.host_port != ns->st_connection->spd.this.host_port)
+ {
+ p->connection->spd.this.host_port = ns->st_connection->spd.this.host_port;
+ p->connection->spd.that.host_port = ns->st_connection->spd.that.host_port;
+ }
}
- }
}
/* a Main Mode negotiation has failed; discard any pending */
void
flush_pending_by_state(struct state *st)
{
- struct host_pair *hp = st->st_connection->host_pair;
-
- if (hp != NULL)
- {
- struct pending **pp
- , *p;
+ struct host_pair *hp = st->st_connection->host_pair;
- for (pp = &hp->pending; (p = *pp) != NULL; )
+ if (hp != NULL)
{
- if (p->isakmp_sa == st)
- delete_pending(pp);
- else
- pp = &p->next;
+ struct pending **pp
+ , *p;
+
+ for (pp = &hp->pending; (p = *pp) != NULL; )
+ {
+ if (p->isakmp_sa == st)
+ delete_pending(pp);
+ else
+ pp = &p->next;
+ }
}
- }
}
/* a connection has been deleted; discard any related pending */
static void
flush_pending_by_connection(struct connection *c)
{
- if (c->host_pair != NULL)
- {
- struct pending **pp
- , *p;
-
- for (pp = &c->host_pair->pending; (p = *pp) != NULL; )
+ if (c->host_pair != NULL)
{
- if (p->connection == c)
- {
- p->connection = NULL; /* prevent delete_pending from releasing */
- delete_pending(pp);
- }
- else
- {
- pp = &p->next;
- }
+ struct pending **pp
+ , *p;
+
+ for (pp = &c->host_pair->pending; (p = *pp) != NULL; )
+ {
+ if (p->connection == c)
+ {
+ p->connection = NULL; /* prevent delete_pending from releasing */
+ delete_pending(pp);
+ }
+ else
+ {
+ pp = &p->next;
+ }
+ }
}
- }
}
void
show_pending_phase2(const struct host_pair *hp, const struct state *st)
{
- const struct pending *p;
+ const struct pending *p;
- for (p = hp->pending; p != NULL; p = p->next)
- {
- if (p->isakmp_sa == st)
+ for (p = hp->pending; p != NULL; p = p->next)
{
- /* connection-name state-number [replacing state-number] */
- char cip[CONN_INST_BUF];
-
- fmt_conn_instance(p->connection, cip);
- whack_log(RC_COMMENT, "#%lu: pending Phase 2 for \"%s\"%s replacing #%lu"
- , p->isakmp_sa->st_serialno
- , p->connection->name
- , cip
- , p->replacing);
+ if (p->isakmp_sa == st)
+ {
+ /* connection-name state-number [replacing state-number] */
+ char cip[CONN_INST_BUF];
+
+ fmt_conn_instance(p->connection, cip);
+ whack_log(RC_COMMENT, "#%lu: pending Phase 2 for \"%s\"%s replacing #%lu"
+ , p->isakmp_sa->st_serialno
+ , p->connection->name
+ , cip
+ , p->replacing);
+ }
}
- }
}
/* Delete a connection if it is an instance and it is no longer in use.
@@ -4329,18 +4331,18 @@ show_pending_phase2(const struct host_pair *hp, const struct state *st)
void
connection_discard(struct connection *c)
{
- if (c->kind == CK_INSTANCE)
- {
- /* see if it is being used by a pending */
- struct pending *p;
+ if (c->kind == CK_INSTANCE)
+ {
+ /* see if it is being used by a pending */
+ struct pending *p;
- for (p = c->host_pair->pending; p != NULL; p = p->next)
- if (p->connection == c)
- return; /* in use, so we're done */
+ for (p = c->host_pair->pending; p != NULL; p = p->next)
+ if (p->connection == c)
+ return; /* in use, so we're done */
- if (!states_use_connection(c))
- delete_connection(c, FALSE);
- }
+ if (!states_use_connection(c))
+ delete_connection(c, FALSE);
+ }
}
@@ -4354,32 +4356,32 @@ long eclipse_count = 0;
struct connection *
eclipsed(struct connection *c, struct spd_route **esrp)
{
- struct connection *ue;
- struct spd_route *sr1 = &c->spd;
+ struct connection *ue;
+ struct spd_route *sr1 = &c->spd;
- ue = NULL;
+ ue = NULL;
- while (sr1 != NULL && ue != NULL)
- {
- for (ue = connections; ue != NULL; ue = ue->ac_next)
+ while (sr1 != NULL && ue != NULL)
{
- struct spd_route *srue = &ue->spd;
-
- while (srue != NULL
- && srue->routing == RT_ROUTED_ECLIPSED
- && !(samesubnet(&sr1->this.client, &srue->this.client)
- && samesubnet(&sr1->that.client, &srue->that.client)))
- {
- srue = srue->next;
- }
- if (srue != NULL && srue->routing==RT_ROUTED_ECLIPSED)
- {
- *esrp = srue;
- break;
- }
+ for (ue = connections; ue != NULL; ue = ue->ac_next)
+ {
+ struct spd_route *srue = &ue->spd;
+
+ while (srue != NULL
+ && srue->routing == RT_ROUTED_ECLIPSED
+ && !(samesubnet(&sr1->this.client, &srue->this.client)
+ && samesubnet(&sr1->that.client, &srue->that.client)))
+ {
+ srue = srue->next;
+ }
+ if (srue != NULL && srue->routing==RT_ROUTED_ECLIPSED)
+ {
+ *esrp = srue;
+ break;
+ }
+ }
}
- }
- return ue;
+ return ue;
}
/*
diff --git a/src/pluto/connections.h b/src/pluto/connections.h
index b11565296..16cbbfd72 100644
--- a/src/pluto/connections.h
+++ b/src/pluto/connections.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: connections.h 4024 2008-05-29 07:49:47Z andreas $
*/
#ifndef _CONNECTIONS_H
@@ -118,135 +116,135 @@
* - display format: n,m
*/
typedef unsigned long policy_prio_t;
-#define BOTTOM_PRIO ((policy_prio_t)0) /* smaller than any real prio */
+#define BOTTOM_PRIO ((policy_prio_t)0) /* smaller than any real prio */
#define set_policy_prio(c) { (c)->prio = \
- ((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
- | ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
- | (policy_prio_t)1; }
-#define POLICY_PRIO_BUF (3+1+3+1)
+ ((policy_prio_t)(c)->spd.this.client.maskbits << 16) \
+ | ((policy_prio_t)(c)->spd.that.client.maskbits << 8) \
+ | (policy_prio_t)1; }
+#define POLICY_PRIO_BUF (3+1+3+1)
extern void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF]);
struct virtual_t;
struct end {
- struct id id;
- ip_address
- host_addr,
- host_nexthop,
- host_srcip;
- ip_subnet client;
-
- bool key_from_DNS_on_demand;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_id_wildcards;
- bool has_natip;
- char *updown;
- u_int16_t host_port; /* host order */
- u_int16_t port; /* host order */
- u_int8_t protocol;
- cert_t cert; /* end certificate */
- chunk_t ca; /* CA distinguished name */
- struct ietfAttrList *groups;/* access control groups */
- smartcard_t *sc; /* smartcard reader and key info */
- struct virtual_t *virt;
- bool modecfg; /* this end: request local address from server */
- /* that end: give local addresses to clients */
- bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
- /* rules if client behind host is a subnet */
- bool allow_any; /* IP address is subject to change */
- certpolicy_t sendcert; /* whether or not to send the certificate */
+ struct id id;
+ ip_address
+ host_addr,
+ host_nexthop,
+ host_srcip;
+ ip_subnet client;
+
+ bool key_from_DNS_on_demand;
+ bool has_client;
+ bool has_client_wildcard;
+ bool has_port_wildcard;
+ bool has_id_wildcards;
+ bool has_natip;
+ char *updown;
+ u_int16_t host_port; /* host order */
+ u_int16_t port; /* host order */
+ u_int8_t protocol;
+ cert_t cert; /* end certificate */
+ chunk_t ca; /* CA distinguished name */
+ struct ietfAttrList *groups;/* access control groups */
+ smartcard_t *sc; /* smartcard reader and key info */
+ struct virtual_t *virt;
+ bool modecfg; /* this end: request local address from server */
+ /* that end: give local addresses to clients */
+ bool hostaccess; /* allow access to host via iptables INPUT/OUTPUT */
+ /* rules if client behind host is a subnet */
+ bool allow_any; /* IP address is subject to change */
+ certpolicy_t sendcert; /* whether or not to send the certificate */
};
struct spd_route {
- struct spd_route *next;
- struct end this;
- struct end that;
- so_serial_t eroute_owner;
- enum routing_t routing; /* level of routing in place */
- uint32_t reqid;
+ struct spd_route *next;
+ struct end this;
+ struct end that;
+ so_serial_t eroute_owner;
+ enum routing_t routing; /* level of routing in place */
+ uint32_t reqid;
};
struct connection {
- char *name;
- bool ikev1;
+ char *name;
+ bool ikev1;
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_rekey_fuzz;
- unsigned long sa_keying_tries;
+ lset_t policy;
+ time_t sa_ike_life_seconds;
+ time_t sa_ipsec_life_seconds;
+ time_t sa_rekey_margin;
+ unsigned long sa_rekey_fuzz;
+ unsigned long sa_keying_tries;
- /* RFC 3706 DPD */
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
+ /* RFC 3706 DPD */
+ time_t dpd_delay;
+ time_t dpd_timeout;
+ dpd_action_t dpd_action;
- char *log_file_name; /* name of log file */
- FILE *log_file; /* possibly open FILE */
- TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
- bool log_file_err; /* only bitch once */
+ char *log_file_name; /* name of log file */
+ FILE *log_file; /* possibly open FILE */
+ TAILQ_ENTRY(connection) log_link; /* linked list of open conns */
+ bool log_file_err; /* only bitch once */
- struct spd_route spd;
+ struct spd_route spd;
- /* internal fields: */
+ /* internal fields: */
- unsigned long instance_serial;
- policy_prio_t prio;
- bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
- enum connection_kind kind;
- const struct iface *interface; /* filled in iff oriented */
+ unsigned long instance_serial;
+ policy_prio_t prio;
+ bool instance_initiation_ok; /* this is an instance of a policy that mandates initiate */
+ enum connection_kind kind;
+ const struct iface *interface; /* filled in iff oriented */
- so_serial_t /* state object serial number */
- newest_isakmp_sa,
- newest_ipsec_sa;
+ so_serial_t /* state object serial number */
+ newest_isakmp_sa,
+ newest_ipsec_sa;
#ifdef DEBUG
- lset_t extra_debugging;
+ lset_t extra_debugging;
#endif
- /* note: if the client is the gateway, the following must be equal */
- sa_family_t addr_family; /* between gateways */
- sa_family_t tunnel_addr_family; /* between clients */
+ /* note: if the client is the gateway, the following must be equal */
+ sa_family_t addr_family; /* between gateways */
+ sa_family_t tunnel_addr_family; /* between clients */
- struct connection *policy_next; /* if multiple policies,
- next one to apply */
+ struct connection *policy_next; /* if multiple policies,
+ next one to apply */
- struct gw_info *gw_info;
- struct alg_info_esp *alg_info_esp;
- struct alg_info_ike *alg_info_ike;
+ struct gw_info *gw_info;
+ struct alg_info_esp *alg_info_esp;
+ struct alg_info_ike *alg_info_ike;
- struct host_pair *host_pair;
- struct connection *hp_next; /* host pair list link */
+ struct host_pair *host_pair;
+ struct connection *hp_next; /* host pair list link */
- struct connection *ac_next; /* all connections list link */
+ struct connection *ac_next; /* all connections list link */
- generalName_t *requested_ca; /* collected certificate requests */
- bool got_certrequest;
+ generalName_t *requested_ca; /* collected certificate requests */
+ bool got_certrequest;
};
#define oriented(c) ((c).interface != NULL)
extern bool orient(struct connection *c);
extern bool same_peer_ids(const struct connection *c
- , const struct connection *d, const struct id *his_id);
+ , const struct connection *d, const struct id *his_id);
/* Format the topology of a connection end, leaving out defaults.
* Largest left end looks like: client === host : port [ host_id ] --- hop
* Note: if that==NULL, skip nexthop
*/
-#define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10)
+#define END_BUF (SUBNETTOT_BUF + ADDRTOT_BUF + IDTOA_BUF + ADDRTOT_BUF + 10)
extern size_t format_end(char *buf, size_t buf_len
- , const struct end *this, const struct end *that
- , bool is_left, lset_t policy);
+ , const struct end *this, const struct end *that
+ , bool is_left, lset_t policy);
extern void add_connection(const whack_message_t *wm);
extern void initiate_connection(const char *name, int whackfd);
extern void initiate_opportunistic(const ip_address *our_client
- , const ip_address *peer_client, int transport_proto, bool held, int whackfd);
+ , const ip_address *peer_client, int transport_proto, bool held, int whackfd);
extern void terminate_connection(const char *nm);
extern void release_connection(struct connection *c, bool relations);
extern void delete_connection(struct connection *c, bool relations);
@@ -257,87 +255,87 @@ extern void remove_group_instance(const struct connection *group, const char *na
extern void release_dead_interfaces(void);
extern void check_orientations(void);
extern struct connection *route_owner(struct connection *c
- , struct spd_route **srp
- , struct connection **erop
- , struct spd_route **esrp);
+ , struct spd_route **srp
+ , struct connection **erop
+ , struct spd_route **esrp);
extern struct connection *shunt_owner(const ip_subnet *ours
- , const ip_subnet *his);
+ , const ip_subnet *his);
-extern bool uniqueIDs; /* --uniqueids? */
+extern bool uniqueIDs; /* --uniqueids? */
extern void ISAKMP_SA_established(struct connection *c, so_serial_t serial);
#define his_id_was_instantiated(c) ((c)->kind == CK_INSTANCE \
- && (id_is_ipaddr(&(c)->spd.that.id)? \
- sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
+ && (id_is_ipaddr(&(c)->spd.that.id)? \
+ sameaddr(&(c)->spd.that.id.ip_addr, &(c)->spd.that.host_addr) : TRUE))
-struct state; /* forward declaration of tag (defined in state.h) */
+struct state; /* forward declaration of tag (defined in state.h) */
extern struct connection
- *con_by_name(const char *nm, bool strict),
- *find_host_connection(const ip_address *me, u_int16_t my_port
- , const ip_address *him, u_int16_t his_port, lset_t policy),
- *refine_host_connection(const struct state *st, const struct id *id
- , chunk_t peer_ca),
- *find_client_connection(struct connection *c
- , const ip_subnet *our_net
- , const ip_subnet *peer_net
- , const u_int8_t our_protocol
- , const u_int16_t out_port
- , const u_int8_t peer_protocol
- , const u_int16_t peer_port),
- *find_connection_by_reqid(uint32_t reqid);
+ *con_by_name(const char *nm, bool strict),
+ *find_host_connection(const ip_address *me, u_int16_t my_port
+ , const ip_address *him, u_int16_t his_port, lset_t policy),
+ *refine_host_connection(const struct state *st, const struct id *id
+ , chunk_t peer_ca),
+ *find_client_connection(struct connection *c
+ , const ip_subnet *our_net
+ , const ip_subnet *peer_net
+ , const u_int8_t our_protocol
+ , const u_int16_t out_port
+ , const u_int8_t peer_protocol
+ , const u_int16_t peer_port),
+ *find_connection_by_reqid(uint32_t reqid);
extern struct connection *
find_connection_for_clients(struct spd_route **srp
- , const ip_address *our_client
- , const ip_address *peer_client
- , int transport_proto);
+ , const ip_address *our_client
+ , const ip_address *peer_client
+ , int transport_proto);
extern chunk_t get_peer_ca_and_groups(struct connection *c
- , const ietfAttrList_t **peer_list);
-
+ , const ietfAttrList_t **peer_list);
+
/* instantiating routines
* Note: connection_discard() is in state.h because all its work
* is looking through state objects.
*/
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
-struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
+struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
+struct alg_info; /* forward declaration of tag (defined in alg_info.h) */
extern struct connection *rw_instantiate(struct connection *c
- , const ip_address *him
- , u_int16_t his_port
- , const ip_subnet *his_net
- , const struct id *his_id);
+ , const ip_address *him
+ , u_int16_t his_port
+ , const ip_subnet *his_net
+ , const struct id *his_id);
extern struct connection *oppo_instantiate(struct connection *c
- , const ip_address *him
- , const struct id *his_id
- , struct gw_info *gw
- , const ip_address *our_client
- , const ip_address *peer_client);
+ , const ip_address *him
+ , const struct id *his_id
+ , struct gw_info *gw
+ , const ip_address *our_client
+ , const ip_address *peer_client);
extern struct connection
*build_outgoing_opportunistic_connection(struct gw_info *gw
- , const ip_address *our_client
- , const ip_address *peer_client);
+ , const ip_address *our_client
+ , const ip_address *peer_client);
/* worst case: "[" serial "] " myclient "=== ..." peer "===" hisclient '\0' */
#define CONN_INST_BUF \
- (2 + 10 + 1 + SUBNETTOT_BUF + 7 + ADDRTOT_BUF + 3 + SUBNETTOT_BUF + 1)
+ (2 + 10 + 1 + SUBNETTOT_BUF + 7 + ADDRTOT_BUF + 3 + SUBNETTOT_BUF + 1)
extern void fmt_conn_instance(const struct connection *c
- , char buf[CONN_INST_BUF]);
+ , char buf[CONN_INST_BUF]);
/* operations on "pending", the structure representing Quick Mode
* negotiations delayed until a Keying Channel has been negotiated.
*/
-struct pending; /* forward declaration (opaque outside connections.c) */
+struct pending; /* forward declaration (opaque outside connections.c) */
extern void add_pending(int whack_sock
- , struct state *isakmp_sa
- , struct connection *c
- , lset_t policy
- , unsigned long try
- , so_serial_t replacing);
+ , struct state *isakmp_sa
+ , struct connection *c
+ , lset_t policy
+ , unsigned long try
+ , so_serial_t replacing);
extern void release_pending_whacks(struct state *st, err_t story);
extern void unpend(struct state *st);
@@ -360,9 +358,9 @@ extern struct connection *eclipsed(struct connection *c, struct spd_route **);
extern void show_connections_status(bool all, const char *name);
extern int connection_compare(const struct connection *ca
- , const struct connection *cb);
+ , const struct connection *cb);
extern void update_host_pair(const char *why, struct connection *c
- , const ip_address *myaddr, u_int16_t myport
- , const ip_address *hisaddr, u_int16_t hisport);
+ , const ip_address *myaddr, u_int16_t myport
+ , const ip_address *hisaddr, u_int16_t hisport);
#endif /* _CONNECTIONS_H */
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
index 50a75c0aa..adcd77131 100644
--- a/src/pluto/constants.c
+++ b/src/pluto/constants.c
@@ -1,5 +1,6 @@
/* tables of names for values defined in constants.h
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: constants.c 4612 2008-11-11 06:37:37Z andreas $
*/
/*
@@ -25,7 +24,6 @@
#include <netinet/in.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "constants.h"
#include "defs.h"
@@ -36,42 +34,36 @@
const char compile_time_interop_options[] = ""
#ifdef THREADS
- " THREADS"
-#endif
-#ifdef LIBCURL
- " LIBCURL"
-#endif
-#ifdef LIBLDAP
- " LIBLDAP"
+ " THREADS"
#endif
#ifdef SMARTCARD
- " SMARTCARD"
+ " SMARTCARD"
#endif
#ifdef VENDORID
- " VENDORID"
+ " VENDORID"
#endif
#ifdef CISCO_QUIRKS
- " CISCO_QUIRKS"
+ " CISCO_QUIRKS"
#endif
#ifdef USE_KEYRR
- " KEYRR"
+ " KEYRR"
#endif
- ;
+ ;
/* version */
static const char *const version_name[] = {
- "ISAKMP Version 1.0",
+ "ISAKMP Version 1.0",
};
enum_names version_names =
- { ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
- ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
- version_name, NULL };
+ { ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
+ ISAKMP_MAJOR_VERSION<<ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION,
+ version_name, NULL };
/* RFC 2459 CRL reason codes */
-static const char *const crl_reason_name[] = {
+ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
"unspecified",
"key compromise",
"ca compromise",
@@ -81,26 +73,20 @@ static const char *const crl_reason_name[] = {
"certificate hold",
"reason #7",
"remove from crl"
- };
-
-enum_names crl_reason_names =
- { REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL, crl_reason_name, NULL};
+);
/* RFC 3706 Dead Peer Detection */
-static const char *const dpd_action_name[] = {
+ENUM(dpd_action_names, DPD_ACTION_NONE, DPD_ACTION_RESTART,
"none",
"clear",
"hold",
"restart"
- };
-
-enum_names dpd_action_names =
- { DPD_ACTION_NONE, DPD_ACTION_RESTART, dpd_action_name, NULL};
-
+);
+
/* Timer events */
-static const char *const timer_event_name[] = {
+ENUM(timer_event_names, EVENT_NULL, EVENT_LOG_DAILY,
"EVENT_NULL",
"EVENT_REINIT_SECRET",
"EVENT_SHUNT_SCAN",
@@ -113,16 +99,13 @@ static const char *const timer_event_name[] = {
"EVENT_DPD",
"EVENT_DPD_TIMEOUT",
"EVENT_LOG_DAILY"
- };
-
-enum_names timer_event_names =
- { EVENT_NULL, EVENT_LOG_DAILY, timer_event_name, NULL };
+);
/* Domain of Interpretation */
static const char *const doi_name[] = {
- "ISAKMP_DOI_ISAKMP",
- "ISAKMP_DOI_IPSEC",
+ "ISAKMP_DOI_ISAKMP",
+ "ISAKMP_DOI_IPSEC",
};
enum_names doi_names = { ISAKMP_DOI_ISAKMP, ISAKMP_DOI_IPSEC, doi_name, NULL };
@@ -155,7 +138,7 @@ const char *const debug_bit_names[] = {
"impair-bust-mr2",
NULL
- };
+};
#endif
/* State of exchanges */
@@ -197,78 +180,78 @@ static const char *const state_name[] = {
"STATE_MODE_CFG_R4",
"STATE_IKE_ROOF"
- };
+};
enum_names state_names =
- { STATE_MAIN_R0, STATE_IKE_ROOF-1, state_name, NULL };
+ { STATE_MAIN_R0, STATE_IKE_ROOF-1, state_name, NULL };
/* story for state */
const char *const state_story[] = {
- "expecting MI1", /* STATE_MAIN_R0 */
- "sent MI1, expecting MR1", /* STATE_MAIN_I1 */
- "sent MR1, expecting MI2", /* STATE_MAIN_R1 */
- "sent MI2, expecting MR2", /* STATE_MAIN_I2 */
- "sent MR2, expecting MI3", /* STATE_MAIN_R2 */
- "sent MI3, expecting MR3", /* STATE_MAIN_I3 */
- "sent MR3, ISAKMP SA established", /* STATE_MAIN_R3 */
- "ISAKMP SA established", /* STATE_MAIN_I4 */
-
- "expecting QI1", /* STATE_QUICK_R0 */
- "sent QI1, expecting QR1", /* STATE_QUICK_I1 */
- "sent QR1, inbound IPsec SA installed, expecting QI2", /* STATE_QUICK_R1 */
- "sent QI2, IPsec SA established", /* STATE_QUICK_I2 */
- "IPsec SA established", /* STATE_QUICK_R2 */
-
- "got Informational Message in clear", /* STATE_INFO */
- "got encrypted Informational Message", /* STATE_INFO_PROTECTED */
-
- "expecting XAUTH request", /* STATE_XAUTH_I0 */
- "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
- "sent XAUTH reply, expecting status", /* STATE_XAUTH_I1 */
- "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
- "sent XAUTH ack, established", /* STATE_XAUTH_I2 */
- "received XAUTH ack, established", /* STATE_XAUTH_R3 */
-
- "expecting ModeCfg request", /* STATE_MODE_CFG_R0 */
+ "expecting MI1", /* STATE_MAIN_R0 */
+ "sent MI1, expecting MR1", /* STATE_MAIN_I1 */
+ "sent MR1, expecting MI2", /* STATE_MAIN_R1 */
+ "sent MI2, expecting MR2", /* STATE_MAIN_I2 */
+ "sent MR2, expecting MI3", /* STATE_MAIN_R2 */
+ "sent MI3, expecting MR3", /* STATE_MAIN_I3 */
+ "sent MR3, ISAKMP SA established", /* STATE_MAIN_R3 */
+ "ISAKMP SA established", /* STATE_MAIN_I4 */
+
+ "expecting QI1", /* STATE_QUICK_R0 */
+ "sent QI1, expecting QR1", /* STATE_QUICK_I1 */
+ "sent QR1, inbound IPsec SA installed, expecting QI2", /* STATE_QUICK_R1 */
+ "sent QI2, IPsec SA established", /* STATE_QUICK_I2 */
+ "IPsec SA established", /* STATE_QUICK_R2 */
+
+ "got Informational Message in clear", /* STATE_INFO */
+ "got encrypted Informational Message", /* STATE_INFO_PROTECTED */
+
+ "expecting XAUTH request", /* STATE_XAUTH_I0 */
+ "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
+ "sent XAUTH reply, expecting status", /* STATE_XAUTH_I1 */
+ "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
+ "sent XAUTH ack, established", /* STATE_XAUTH_I2 */
+ "received XAUTH ack, established", /* STATE_XAUTH_R3 */
+
+ "expecting ModeCfg request", /* STATE_MODE_CFG_R0 */
"sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
- "sent ModeCfg reply, established", /* STATE_MODE_CFG_R1 */
- "received ModeCfg reply, established", /* STATE_MODE_CFG_I2 */
+ "sent ModeCfg reply, established", /* STATE_MODE_CFG_R1 */
+ "received ModeCfg reply, established", /* STATE_MODE_CFG_I2 */
- "expecting ModeCfg set", /* STATE_MODE_CFG_I0 */
- "sent ModeCfg set, expecting ack", /* STATE_MODE_CFG_R3 */
- "sent ModeCfg ack, established", /* STATE_MODE_CFG_I3 */
- "received ModeCfg ack, established", /* STATE_MODE_CFG_R4 */
- };
+ "expecting ModeCfg set", /* STATE_MODE_CFG_I0 */
+ "sent ModeCfg set, expecting ack", /* STATE_MODE_CFG_R3 */
+ "sent ModeCfg ack, established", /* STATE_MODE_CFG_I3 */
+ "received ModeCfg ack, established", /* STATE_MODE_CFG_R4 */
+};
/* kind of struct connection */
static const char *const connection_kind_name[] = {
- "CK_GROUP", /* policy group: instantiates to template */
- "CK_TEMPLATE", /* abstract connection, with wildcard */
- "CK_PERMANENT", /* normal connection */
- "CK_INSTANCE", /* instance of template, created for a particular attempt */
- "CK_GOING_AWAY" /* instance being deleted -- don't delete again */
+ "CK_GROUP", /* policy group: instantiates to template */
+ "CK_TEMPLATE", /* abstract connection, with wildcard */
+ "CK_PERMANENT", /* normal connection */
+ "CK_INSTANCE", /* instance of template, created for a particular attempt */
+ "CK_GOING_AWAY" /* instance being deleted -- don't delete again */
};
enum_names connection_kind_names =
- { CK_GROUP, CK_GOING_AWAY, connection_kind_name, NULL };
+ { CK_GROUP, CK_GOING_AWAY, connection_kind_name, NULL };
/* routing status names */
static const char *const routing_story_strings[] = {
- "unrouted", /* RT_UNROUTED: unrouted */
- "unrouted HOLD", /* RT_UNROUTED_HOLD: unrouted, but HOLD shunt installed */
- "eroute eclipsed", /* RT_ROUTED_ECLIPSED: RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
- "prospective erouted", /* RT_ROUTED_PROSPECTIVE: routed, and prospective shunt installed */
- "erouted HOLD", /* RT_ROUTED_HOLD: routed, and HOLD shunt installed */
- "fail erouted", /* RT_ROUTED_FAILURE: routed, and failure-context shunt eroute installed */
- "erouted", /* RT_ROUTED_TUNNEL: routed, and erouted to an IPSEC SA group */
- "keyed, unrouted", /* RT_UNROUTED_KEYED: was routed+keyed, but it got turned into an outer policy */
- };
+ "unrouted", /* RT_UNROUTED: unrouted */
+ "unrouted HOLD", /* RT_UNROUTED_HOLD: unrouted, but HOLD shunt installed */
+ "eroute eclipsed", /* RT_ROUTED_ECLIPSED: RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
+ "prospective erouted", /* RT_ROUTED_PROSPECTIVE: routed, and prospective shunt installed */
+ "erouted HOLD", /* RT_ROUTED_HOLD: routed, and HOLD shunt installed */
+ "fail erouted", /* RT_ROUTED_FAILURE: routed, and failure-context shunt eroute installed */
+ "erouted", /* RT_ROUTED_TUNNEL: routed, and erouted to an IPSEC SA group */
+ "keyed, unrouted", /* RT_UNROUTED_KEYED: was routed+keyed, but it got turned into an outer policy */
+};
enum_names routing_story =
- { RT_UNROUTED, RT_ROUTED_TUNNEL, routing_story_strings, NULL};
+ { RT_UNROUTED, RT_ROUTED_TUNNEL, routing_story_strings, NULL};
/* Payload types (RFC 2408 "ISAKMP" section 3.1) */
@@ -296,16 +279,18 @@ const char *const payload_name[] = {
"ISAKMP_NEXT_NAT-D",
"ISAKMP_NEXT_NAT-OA",
NULL
- };
+};
-const char *const payload_name_nat_d[] = { "ISAKMP_NEXT_NAT-D",
- "ISAKMP_NEXT_NAT-OA", NULL };
+const char *const payload_name_nat_d[] = {
+ "ISAKMP_NEXT_NAT-D",
+ "ISAKMP_NEXT_NAT-OA", NULL
+};
static enum_names payload_names_nat_d =
{ ISAKMP_NEXT_NATD_DRAFTS, ISAKMP_NEXT_NATOA_DRAFTS, payload_name_nat_d, NULL };
-
+
enum_names payload_names =
- { ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_nat_d };
+ { ISAKMP_NEXT_NONE, ISAKMP_NEXT_NATOA_RFC, payload_name, &payload_names_nat_d };
/* Exchange types (note: two discontinuous ranges) */
@@ -317,26 +302,26 @@ static const char *const exchange_name[] = {
"ISAKMP_XCHG_AGGR",
"ISAKMP_XCHG_INFO",
"ISAKMP_XCHG_MODE_CFG",
- };
+};
static const char *const exchange_name2[] = {
"ISAKMP_XCHG_QUICK",
"ISAKMP_XCHG_NGRP",
"ISAKMP_XCHG_ACK_INFO",
- };
+};
static enum_names exchange_desc2 =
- { ISAKMP_XCHG_QUICK, ISAKMP_XCHG_ACK_INFO, exchange_name2, NULL };
+ { ISAKMP_XCHG_QUICK, ISAKMP_XCHG_ACK_INFO, exchange_name2, NULL };
enum_names exchange_names =
- { ISAKMP_XCHG_NONE, ISAKMP_XCHG_MODE_CFG, exchange_name, &exchange_desc2 };
+ { ISAKMP_XCHG_NONE, ISAKMP_XCHG_MODE_CFG, exchange_name, &exchange_desc2 };
/* Flag BITS */
const char *const flag_bit_names[] = {
"ISAKMP_FLAG_ENCRYPTION",
"ISAKMP_FLAG_COMMIT",
NULL
- };
+};
/* Situation BITS definition for IPsec DOI */
@@ -345,7 +330,7 @@ const char *const sit_bit_names[] = {
"SIT_SECRECY",
"SIT_INTEGRITY",
NULL
- };
+};
/* Protocol IDs (RFC 2407 "IPsec DOI" section 4.4.1) */
@@ -354,78 +339,74 @@ static const char *const protocol_name[] = {
"PROTO_IPSEC_AH",
"PROTO_IPSEC_ESP",
"PROTO_IPCOMP",
- };
+};
enum_names protocol_names =
- { PROTO_ISAKMP, PROTO_IPCOMP, protocol_name, NULL };
+ { PROTO_ISAKMP, PROTO_IPCOMP, protocol_name, NULL };
/* IPsec ISAKMP transform values */
static const char *const isakmp_transform_name[] = {
"KEY_IKE",
- };
+};
enum_names isakmp_transformid_names =
- { KEY_IKE, KEY_IKE, isakmp_transform_name, NULL };
+ { KEY_IKE, KEY_IKE, isakmp_transform_name, NULL };
/* IPsec AH transform values */
static const char *const ah_transform_name[] = {
- "AH_MD5",
- "AH_SHA",
- "AH_DES",
- "AH_SHA2_256",
- "AH_SHA2_384",
- "AH_SHA2_512",
- "AH_RIPEMD",
- "AH_AES_XCBC_MAC",
- "AH_RSA"
- };
+ "HMAC_MD5",
+ "HMAC_SHA1",
+ "DES_MAC",
+ "HMAC_SHA2_256",
+ "HMAC_SHA2_384",
+ "HMAC_SHA2_512",
+ "HMAC_RIPEMD",
+ "AES_XCBC_96",
+ "SIG_RSA"
+};
enum_names ah_transformid_names =
- { AH_MD5, AH_RSA, ah_transform_name, NULL };
+ { AH_MD5, AH_RSA, ah_transform_name, NULL };
/* IPsec ESP transform values */
static const char *const esp_transform_name[] = {
- "ESP_DES_IV64",
- "ESP_DES",
- "ESP_3DES",
- "ESP_RC5",
- "ESP_IDEA",
- "ESP_CAST",
- "ESP_BLOWFISH",
- "ESP_3IDEA",
- "ESP_DES_IV32",
- "ESP_RC4",
- "ESP_NULL",
- "ESP_AES",
- "ESP_AES-CTR",
- "ESP_AES-CCM_8",
- "ESP_AES-CCM_12",
- "ESP_AES-CCM_16",
- "ESP_UNASSIGNED_17",
- "ESP_AES_GCM_8",
- "ESP_AES_GCM_12",
- "ESP_AES_GCM_16",
- "ESP_SEED_CBC",
- "ESP_CAMELLIA"
- };
+ "DES_IV64",
+ "DES_CBC",
+ "3DES_CBC",
+ "RC5_CBC",
+ "IDEA_CBC",
+ "CAST_CBC",
+ "BLOWFISH_CBC",
+ "3IDEA",
+ "DES_IV32",
+ "RC4",
+ "NULL",
+ "AES_CBC",
+ "AES_CTR",
+ "AES_CCM_8",
+ "AES_CCM_12",
+ "AES_CCM_16",
+ "UNASSIGNED_17",
+ "AES_GCM_8",
+ "AES_GCM_12",
+ "AES_GCM_16",
+ "SEED_CBC",
+ "CAMELLIA_CBC"
+};
-/*
- * ipsec drafts suggest "high" ESP ids values for testing,
- * assign generic ESP_ID<num> if not officially defined
- */
static const char *const esp_transform_name_high[] = {
- "ESP_SERPENT",
- "ESP_TWOFISH"
- };
+ "SERPENT_CBC",
+ "TWOFISH_CBC"
+};
enum_names esp_transformid_names_high =
- { ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
+ { ESP_SERPENT, ESP_TWOFISH, esp_transform_name_high, NULL };
enum_names esp_transformid_names =
- { ESP_DES_IV64, ESP_CAMELLIA, esp_transform_name, &esp_transformid_names_high };
+ { ESP_DES_IV64, ESP_CAMELLIA, esp_transform_name, &esp_transformid_names_high };
/* IPCOMP transform values */
@@ -434,10 +415,10 @@ static const char *const ipcomp_transform_name[] = {
"IPCOMP_DEFLAT",
"IPCOMP_LZS",
"IPCOMP_LZJH",
- };
+};
enum_names ipcomp_transformid_names =
- { IPCOMP_OUI, IPCOMP_LZJH, ipcomp_transform_name, NULL };
+ { IPCOMP_OUI, IPCOMP_LZJH, ipcomp_transform_name, NULL };
/* Identification type values */
@@ -453,10 +434,10 @@ static const char *const ident_name[] = {
"ID_DER_ASN1_DN",
"ID_DER_ASN1_GN",
"ID_KEY_ID",
- };
+};
enum_names ident_names =
- { ID_IPV4_ADDR, ID_KEY_ID, ident_name, NULL };
+ { ID_IPV4_ADDR, ID_KEY_ID, ident_name, NULL };
/* Certificate type values */
@@ -472,21 +453,18 @@ static const char *const cert_type_name[] = {
"CERT_ARL",
"CERT_SPKI",
"CERT_X509_ATTRIBUTE",
- };
+};
enum_names cert_type_names =
- { CERT_NONE, CERT_X509_ATTRIBUTE, cert_type_name, NULL };
+ { CERT_NONE, CERT_X509_ATTRIBUTE, cert_type_name, NULL };
/* Certificate policy names */
-static const char *const cert_policy_name[] = {
+ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
"ALWAYS_SEND",
"SEND_IF_ASKED",
"NEVER_SEND",
- };
-
-enum_names cert_policy_names =
- { CERT_ALWAYS_SEND, CERT_NEVER_SEND, cert_policy_name, NULL };
+);
/* Goal BITs for establishing an SA
* Note: we drop the POLICY_ prefix so that logs are more concise.
@@ -494,7 +472,7 @@ enum_names cert_policy_names =
const char *const sa_policy_bit_names[] = {
"PSK",
- "RSASIG",
+ "PUBKEY",
"ENCRYPT",
"AUTHENTICATE",
"COMPRESS",
@@ -517,24 +495,23 @@ const char *const sa_policy_bit_names[] = {
"DONTREAUTH",
"BEET",
"MOBIKE",
- "ECDSA",
"PROXY",
NULL
- };
+};
const char *const policy_shunt_names[4] = {
"TRAP",
"PASS",
"DROP",
"REJECT",
- };
+};
const char *const policy_fail_names[4] = {
"NONE",
"PASS",
"DROP",
"REJECT",
- };
+};
/* Oakley transform attributes
* oakley_attr_bit_names does double duty: it is used for enum names
@@ -560,7 +537,7 @@ const char *const oakley_attr_bit_names[] = {
"OAKLEY_GROUP_ORDER",
"OAKLEY_BLOCK_SIZE",
NULL
- };
+};
static const char *const oakley_var_attr_name[] = {
"OAKLEY_GROUP_PRIME (variable length)",
@@ -574,36 +551,36 @@ static const char *const oakley_var_attr_name[] = {
NULL,
NULL,
"OAKLEY_GROUP_ORDER (variable length)",
- };
+};
static enum_names oakley_attr_desc_tv = {
- OAKLEY_ENCRYPTION_ALGORITHM + ISAKMP_ATTR_AF_TV,
- OAKLEY_GROUP_ORDER + ISAKMP_ATTR_AF_TV, oakley_attr_bit_names, NULL };
+ OAKLEY_ENCRYPTION_ALGORITHM + ISAKMP_ATTR_AF_TV,
+ OAKLEY_GROUP_ORDER + ISAKMP_ATTR_AF_TV, oakley_attr_bit_names, NULL };
enum_names oakley_attr_names = {
- OAKLEY_GROUP_PRIME, OAKLEY_GROUP_ORDER,
- oakley_var_attr_name, &oakley_attr_desc_tv };
+ OAKLEY_GROUP_PRIME, OAKLEY_GROUP_ORDER,
+ oakley_var_attr_name, &oakley_attr_desc_tv };
/* for each Oakley attribute, which enum_names describes its values? */
enum_names *oakley_attr_val_descs[] = {
- NULL, /* (none) */
- &oakley_enc_names, /* OAKLEY_ENCRYPTION_ALGORITHM */
- &oakley_hash_names, /* OAKLEY_HASH_ALGORITHM */
- &oakley_auth_names, /* OAKLEY_AUTHENTICATION_METHOD */
- &oakley_group_names, /* OAKLEY_GROUP_DESCRIPTION */
+ NULL, /* (none) */
+ &oakley_enc_names, /* OAKLEY_ENCRYPTION_ALGORITHM */
+ &oakley_hash_names, /* OAKLEY_HASH_ALGORITHM */
+ &oakley_auth_names, /* OAKLEY_AUTHENTICATION_METHOD */
+ &oakley_group_names, /* OAKLEY_GROUP_DESCRIPTION */
&oakley_group_type_names,/* OAKLEY_GROUP_TYPE */
- NULL, /* OAKLEY_GROUP_PRIME */
- NULL, /* OAKLEY_GROUP_GENERATOR_ONE */
- NULL, /* OAKLEY_GROUP_GENERATOR_TWO */
- NULL, /* OAKLEY_GROUP_CURVE_A */
- NULL, /* OAKLEY_GROUP_CURVE_B */
- &oakley_lifetime_names, /* OAKLEY_LIFE_TYPE */
- NULL, /* OAKLEY_LIFE_DURATION */
- &oakley_prf_names, /* OAKLEY_PRF */
- NULL, /* OAKLEY_KEY_LENGTH */
- NULL, /* OAKLEY_FIELD_SIZE */
- NULL, /* OAKLEY_GROUP_ORDER */
- };
+ NULL, /* OAKLEY_GROUP_PRIME */
+ NULL, /* OAKLEY_GROUP_GENERATOR_ONE */
+ NULL, /* OAKLEY_GROUP_GENERATOR_TWO */
+ NULL, /* OAKLEY_GROUP_CURVE_A */
+ NULL, /* OAKLEY_GROUP_CURVE_B */
+ &oakley_lifetime_names, /* OAKLEY_LIFE_TYPE */
+ NULL, /* OAKLEY_LIFE_DURATION */
+ &oakley_prf_names, /* OAKLEY_PRF */
+ NULL, /* OAKLEY_KEY_LENGTH */
+ NULL, /* OAKLEY_FIELD_SIZE */
+ NULL, /* OAKLEY_GROUP_ORDER */
+};
/* IPsec DOI attributes (RFC 2407 "IPsec DOI" section 4.5) */
@@ -617,7 +594,7 @@ static const char *const ipsec_attr_name[] = {
"KEY_ROUNDS",
"COMPRESS_DICT_SIZE",
"COMPRESS_PRIVATE_ALG",
- };
+};
static const char *const ipsec_var_attr_name[] = {
"SA_LIFE_DURATION (variable length)",
@@ -628,40 +605,40 @@ static const char *const ipsec_var_attr_name[] = {
NULL,
NULL,
"COMPRESS_PRIVATE_ALG (variable length)",
- };
+};
static enum_names ipsec_attr_desc_tv = {
- SA_LIFE_TYPE + ISAKMP_ATTR_AF_TV,
- COMPRESS_PRIVATE_ALG + ISAKMP_ATTR_AF_TV,
- ipsec_attr_name, NULL };
+ SA_LIFE_TYPE + ISAKMP_ATTR_AF_TV,
+ COMPRESS_PRIVATE_ALG + ISAKMP_ATTR_AF_TV,
+ ipsec_attr_name, NULL };
enum_names ipsec_attr_names = {
- SA_LIFE_DURATION, COMPRESS_PRIVATE_ALG,
- ipsec_var_attr_name, &ipsec_attr_desc_tv };
+ SA_LIFE_DURATION, COMPRESS_PRIVATE_ALG,
+ ipsec_var_attr_name, &ipsec_attr_desc_tv };
/* for each IPsec attribute, which enum_names describes its values? */
enum_names *ipsec_attr_val_descs[] = {
- NULL, /* (none) */
- &sa_lifetime_names, /* SA_LIFE_TYPE */
- NULL, /* SA_LIFE_DURATION */
- &oakley_group_names, /* GROUP_DESCRIPTION */
- &enc_mode_names, /* ENCAPSULATION_MODE */
- &auth_alg_names, /* AUTH_ALGORITHM */
- NULL, /* KEY_LENGTH */
- NULL, /* KEY_ROUNDS */
- NULL, /* COMPRESS_DICT_SIZE */
- NULL, /* COMPRESS_PRIVATE_ALG */
- };
+ NULL, /* (none) */
+ &sa_lifetime_names, /* SA_LIFE_TYPE */
+ NULL, /* SA_LIFE_DURATION */
+ &oakley_group_names, /* GROUP_DESCRIPTION */
+ &enc_mode_names, /* ENCAPSULATION_MODE */
+ &auth_alg_names, /* AUTH_ALGORITHM */
+ NULL, /* KEY_LENGTH */
+ NULL, /* KEY_ROUNDS */
+ NULL, /* COMPRESS_DICT_SIZE */
+ NULL, /* COMPRESS_PRIVATE_ALG */
+};
/* SA Lifetime Type attribute */
static const char *const sa_lifetime_name[] = {
"SA_LIFE_TYPE_SECONDS",
"SA_LIFE_TYPE_KBYTES",
- };
+};
enum_names sa_lifetime_names =
- { SA_LIFE_TYPE_SECONDS, SA_LIFE_TYPE_KBYTES, sa_lifetime_name, NULL };
+ { SA_LIFE_TYPE_SECONDS, SA_LIFE_TYPE_KBYTES, sa_lifetime_name, NULL };
/* Encapsulation Mode attribute */
@@ -670,55 +647,55 @@ static const char *const enc_mode_name[] = {
"ENCAPSULATION_MODE_TRANSPORT",
"ENCAPSULATION_MODE_UDP_TUNNEL",
"ENCAPSULATION_MODE_UDP_TRANSPORT",
- };
+};
static const char *const enc_udp_mode_name[] = {
- "ENCAPSULATION_MODE_UDP_TUNNEL",
- "ENCAPSULATION_MODE_UDP_TRANSPORT",
- };
+ "ENCAPSULATION_MODE_UDP_TUNNEL",
+ "ENCAPSULATION_MODE_UDP_TRANSPORT",
+ };
static enum_names enc_udp_mode_names =
- { ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS, ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS, enc_udp_mode_name, NULL };
+ { ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS, ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS, enc_udp_mode_name, NULL };
enum_names enc_mode_names =
- { ENCAPSULATION_MODE_TUNNEL, ENCAPSULATION_MODE_UDP_TRANSPORT_RFC, enc_mode_name, &enc_udp_mode_names };
+ { ENCAPSULATION_MODE_TUNNEL, ENCAPSULATION_MODE_UDP_TRANSPORT_RFC, enc_mode_name, &enc_udp_mode_names };
/* Auth Algorithm attribute */
static const char *const auth_alg_name[] = {
- "AUTH_ALGORITHM_HMAC_MD5",
- "AUTH_ALGORITHM_HMAC_SHA1",
- "AUTH_ALGORITHM_DES_MAC",
- "AUTH_ALGORITHM_KPDK",
- "AUTH_ALGORITHM_HMAC_SHA2_256",
- "AUTH_ALGORITHM_HMAC_SHA2_384",
- "AUTH_ALGORITHM_HMAC_SHA2_512",
- "AUTH_ALGORITHM_HMAC_RIPEMD",
- "AUTH_ALGORITHM_AES_XCBC_MAC",
- "AUTH_ALGORITHM_SIG_RSA"
- };
+ "HMAC_MD5",
+ "HMAC_SHA1",
+ "DES_MAC",
+ "KPDK",
+ "HMAC_SHA2_256",
+ "HMAC_SHA2_384",
+ "HMAC_SHA2_512",
+ "HMAC_RIPEMD",
+ "AES_XCBC_96",
+ "SIG_RSA"
+};
static const char *const extended_auth_alg_name[] = {
- "AUTH_ALGORITHM_NULL"
- };
+ "NULL"
+ };
enum_names extended_auth_alg_names =
- { AUTH_ALGORITHM_NULL, AUTH_ALGORITHM_NULL, extended_auth_alg_name, NULL };
+ { AUTH_ALGORITHM_NULL, AUTH_ALGORITHM_NULL, extended_auth_alg_name, NULL };
enum_names auth_alg_names =
- { AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_SIG_RSA, auth_alg_name
- , &extended_auth_alg_names };
+ { AUTH_ALGORITHM_HMAC_MD5, AUTH_ALGORITHM_SIG_RSA, auth_alg_name
+ , &extended_auth_alg_names };
/* From draft-beaulieu-ike-xauth */
static const char *const xauth_type_name[] = {
- "Generic",
- "RADIUS-CHAP",
- "OTP",
- "S/KEY",
+ "Generic",
+ "RADIUS-CHAP",
+ "OTP",
+ "S/KEY",
};
enum_names xauth_type_names =
- { XAUTH_TYPE_GENERIC, XAUTH_TYPE_SKEY, xauth_type_name, NULL};
+ { XAUTH_TYPE_GENERIC, XAUTH_TYPE_SKEY, xauth_type_name, NULL};
/* From draft-beaulieu-ike-xauth */
static const char *const xauth_attr_tv_name[] = {
@@ -730,11 +707,11 @@ static const char *const xauth_attr_tv_name[] = {
NULL,
NULL,
"XAUTH_STATUS",
- };
+};
enum_names xauth_attr_tv_names = {
- XAUTH_TYPE + ISAKMP_ATTR_AF_TV,
- XAUTH_STATUS + ISAKMP_ATTR_AF_TV, xauth_attr_tv_name, NULL };
+ XAUTH_TYPE + ISAKMP_ATTR_AF_TV,
+ XAUTH_STATUS + ISAKMP_ATTR_AF_TV, xauth_attr_tv_name, NULL };
static const char *const unity_attr_name[] = {
"UNITY_BANNER",
@@ -751,8 +728,15 @@ static const char *const unity_attr_name[] = {
};
enum_names unity_attr_names =
- { UNITY_BANNER , UNITY_DDNS_HOSTNAME, unity_attr_name , &xauth_attr_tv_names };
+ { UNITY_BANNER , UNITY_DDNS_HOSTNAME, unity_attr_name , &xauth_attr_tv_names };
+static const char *const microsoft_attr_name[] = {
+ "INTERNAL_IP4_SERVER",
+ "INTERNAL_IP6_SERVER",
+};
+
+enum_names microsoft_attr_names =
+ { INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, microsoft_attr_name , &unity_attr_names };
static const char *const xauth_attr_name[] = {
"XAUTH_USER_NAME",
@@ -764,10 +748,10 @@ static const char *const xauth_attr_name[] = {
"XAUTH_STATUS (wrong TLV syntax, should be TV)",
"XAUTH_NEXT_PIN",
"XAUTH_ANSWER",
- };
+};
enum_names xauth_attr_names =
- { XAUTH_USER_NAME , XAUTH_ANSWER, xauth_attr_name , &unity_attr_names };
+ { XAUTH_USER_NAME , XAUTH_ANSWER, xauth_attr_name , &microsoft_attr_names };
static const char *const modecfg_attr_name[] = {
"INTERNAL_IP4_ADDRESS",
@@ -785,97 +769,104 @@ static const char *const modecfg_attr_name[] = {
"INTERNAL_IP4_SUBNET",
"SUPPORTED_ATTRIBUTES",
"INTERNAL_IP6_SUBNET",
- };
+};
enum_names modecfg_attr_names =
- { INTERNAL_IP4_ADDRESS, INTERNAL_IP6_SUBNET, modecfg_attr_name , &xauth_attr_names };
+ { INTERNAL_IP4_ADDRESS, INTERNAL_IP6_SUBNET, modecfg_attr_name , &xauth_attr_names };
/* Oakley Lifetime Type attribute */
static const char *const oakley_lifetime_name[] = {
"OAKLEY_LIFE_SECONDS",
"OAKLEY_LIFE_KILOBYTES",
- };
+};
enum_names oakley_lifetime_names =
- { OAKLEY_LIFE_SECONDS, OAKLEY_LIFE_KILOBYTES, oakley_lifetime_name, NULL };
+ { OAKLEY_LIFE_SECONDS, OAKLEY_LIFE_KILOBYTES, oakley_lifetime_name, NULL };
/* Oakley PRF attribute (none defined) */
enum_names oakley_prf_names =
- { 1, 0, NULL, NULL };
+ { 1, 0, NULL, NULL };
/* Oakley Encryption Algorithm attribute */
static const char *const oakley_enc_name[] = {
- "OAKLEY_DES_CBC",
- "OAKLEY_IDEA_CBC",
- "OAKLEY_BLOWFISH_CBC",
- "OAKLEY_RC5_R16_B64_CBC",
- "OAKLEY_3DES_CBC",
- "OAKLEY_CAST_CBC",
- "OAKLEY_AES_CBC",
- };
+ "DES_CBC",
+ "IDEA_CBC",
+ "BLOWFISH_CBC",
+ "RC5_R16_B64_CBC",
+ "3DES_CBC",
+ "CAST_CBC",
+ "AES_CBC",
+ "CAMELLIA_CBC"
+};
#ifdef NO_EXTRA_IKE
enum_names oakley_enc_names =
- { OAKLEY_DES_CBC, OAKLEY_AES_CBC, oakley_enc_name, NULL };
+ { OAKLEY_DES_CBC, OAKLEY_CAMELLIA_CBC, oakley_enc_name, NULL };
#else
static const char *const oakley_enc_name_draft_aes_cbc_02[] = {
- "OAKLEY_MARS_CBC" /* 65001 */,
- "OAKLEY_RC6_CBC" /* 65002 */,
- "OAKLEY_ID_65003" /* 65003 */,
- "OAKLEY_SERPENT_CBC" /* 65004 */,
- "OAKLEY_TWOFISH_CBC" /* 65005 */,
+ "MARS_CBC" /* 65001 */,
+ "RC6_CBC" /* 65002 */,
+ "ID_65003" /* 65003 */,
+ "SERPENT_CBC" /* 65004 */,
+ "TWOFISH_CBC" /* 65005 */,
};
+
static const char *const oakley_enc_name_ssh[] = {
- "OAKLEY_TWOFISH_CBC_SSH",
+ "TWOFISH_CBC_SSH",
};
+
enum_names oakley_enc_names_ssh =
- { OAKLEY_TWOFISH_CBC_SSH, OAKLEY_TWOFISH_CBC_SSH, oakley_enc_name_ssh
- , NULL };
+ { OAKLEY_TWOFISH_CBC_SSH, OAKLEY_TWOFISH_CBC_SSH, oakley_enc_name_ssh
+ , NULL };
enum_names oakley_enc_names_draft_aes_cbc_02 =
- { OAKLEY_MARS_CBC, OAKLEY_TWOFISH_CBC, oakley_enc_name_draft_aes_cbc_02
- , &oakley_enc_names_ssh };
+ { OAKLEY_MARS_CBC, OAKLEY_TWOFISH_CBC, oakley_enc_name_draft_aes_cbc_02
+ , &oakley_enc_names_ssh };
enum_names oakley_enc_names =
- { OAKLEY_DES_CBC, OAKLEY_AES_CBC, oakley_enc_name
- , &oakley_enc_names_draft_aes_cbc_02 };
+ { OAKLEY_DES_CBC, OAKLEY_CAMELLIA_CBC, oakley_enc_name
+ , &oakley_enc_names_draft_aes_cbc_02 };
#endif
/* Oakley Hash Algorithm attribute */
static const char *const oakley_hash_name[] = {
- "OAKLEY_MD5",
- "OAKLEY_SHA",
- "OAKLEY_TIGER",
- "OAKLEY_SHA2_256",
- "OAKLEY_SHA2_384",
- "OAKLEY_SHA2_512",
- };
+ "HMAC_MD5",
+ "HMAC_SHA1",
+ "HMAC_TIGER",
+ "HMAC_SHA2_256",
+ "HMAC_SHA2_384",
+ "HMAC_SHA2_512",
+};
enum_names oakley_hash_names =
- { OAKLEY_MD5, OAKLEY_SHA2_512, oakley_hash_name, NULL };
+ { OAKLEY_MD5, OAKLEY_SHA2_512, oakley_hash_name, NULL };
/* Oakley Authentication Method attribute */
static const char *const oakley_auth_name1[] = {
- "OAKLEY_PRESHARED_KEY",
- "OAKLEY_DSS_SIG",
- "OAKLEY_RSA_SIG",
- "OAKLEY_RSA_ENC",
- "OAKLEY_RSA_ENC_REV",
- "OAKLEY_ELGAMAL_ENC",
- "OAKLEY_ELGAMAL_ENC_REV",
- };
+ "pre-shared key",
+ "DSS signature",
+ "RSA signature",
+ "RSA encryption",
+ "RSA encryption revised",
+ "ElGamal encryption",
+ "ELGamal encryption revised",
+ "ECDSA signature",
+ "ECDSA-256 signature",
+ "ECDSA-384 signature",
+ "ECDSA-521-signature",
+};
static const char *const oakley_auth_name2[] = {
"HybridInitRSA",
"HybridRespRSA",
"HybridInitDSS",
"HybridRespDSS",
- };
+};
static const char *const oakley_auth_name3[] = {
"XAUTHInitPreShared",
@@ -888,44 +879,64 @@ static const char *const oakley_auth_name3[] = {
"XAUTHRespRSAEncryption",
"XAUTHInitRSARevisedEncryption",
"XAUTHRespRSARevisedEncryption",
- };
+};
static enum_names oakley_auth_names1 =
- { OAKLEY_PRESHARED_KEY, OAKLEY_ELGAMAL_ENC_REV
- , oakley_auth_name1, NULL };
+ { OAKLEY_PRESHARED_KEY, OAKLEY_ECDSA_521
+ , oakley_auth_name1, NULL };
static enum_names oakley_auth_names2 =
- { HybridInitRSA, HybridRespDSS
- , oakley_auth_name2, &oakley_auth_names1 };
+ { HybridInitRSA, HybridRespDSS
+ , oakley_auth_name2, &oakley_auth_names1 };
enum_names oakley_auth_names =
- { XAUTHInitPreShared, XAUTHRespRSARevisedEncryption
- , oakley_auth_name3, &oakley_auth_names2 };
+ { XAUTHInitPreShared, XAUTHRespRSARevisedEncryption
+ , oakley_auth_name3, &oakley_auth_names2 };
/* Oakley Group Description attribute */
static const char *const oakley_group_name[] = {
- "OAKLEY_GROUP_MODP768",
- "OAKLEY_GROUP_MODP1024",
- "OAKLEY_GROUP_GP155",
- "OAKLEY_GROUP_GP185",
- "OAKLEY_GROUP_MODP1536",
- };
+ "MODP_768",
+ "MODP_1024",
+ "GP_155",
+ "GP_185",
+ "MODP_1536",
+};
static const char *const oakley_group_name_rfc3526[] = {
- "OAKLEY_GROUP_MODP2048",
- "OAKLEY_GROUP_MODP3072",
- "OAKLEY_GROUP_MODP4096",
- "OAKLEY_GROUP_MODP6144",
- "OAKLEY_GROUP_MODP8192"
+ "MODP_2048",
+ "MODP_3072",
+ "MODP_4096",
+ "MODP_6144",
+ "MODP_8192"
+};
+
+static const char *const oakley_group_name_rfc4753[] = {
+ "ECP_256",
+ "ECP_384",
+ "ECP_521"
+};
+
+static const char *const oakley_group_name_rfc5114[] = {
+ "ECP_192",
+ "ECP_224"
};
+
+enum_names oakley_group_names_rfc5114 =
+ { ECP_192_BIT, ECP_224_BIT,
+ oakley_group_name_rfc5114, NULL };
+
+enum_names oakley_group_names_rfc4753 =
+ { ECP_256_BIT, ECP_521_BIT,
+ oakley_group_name_rfc4753, &oakley_group_names_rfc5114 };
+
enum_names oakley_group_names_rfc3526 =
- { OAKLEY_GROUP_MODP2048, OAKLEY_GROUP_MODP8192,
- oakley_group_name_rfc3526, NULL };
+ { MODP_2048_BIT, MODP_8192_BIT,
+ oakley_group_name_rfc3526, &oakley_group_names_rfc4753 };
enum_names oakley_group_names =
- { OAKLEY_GROUP_MODP768, OAKLEY_GROUP_MODP1536,
- oakley_group_name, &oakley_group_names_rfc3526 };
+ { MODP_768_BIT, MODP_1536_BIT,
+ oakley_group_name, &oakley_group_names_rfc3526 };
/* Oakley Group Type attribute */
@@ -933,10 +944,10 @@ static const char *const oakley_group_type_name[] = {
"OAKLEY_GROUP_TYPE_MODP",
"OAKLEY_GROUP_TYPE_ECP",
"OAKLEY_GROUP_TYPE_EC2N",
- };
+};
enum_names oakley_group_type_names =
- { OAKLEY_GROUP_TYPE_MODP, OAKLEY_GROUP_TYPE_EC2N, oakley_group_type_name, NULL };
+ { OAKLEY_GROUP_TYPE_MODP, OAKLEY_GROUP_TYPE_EC2N, oakley_group_type_name, NULL };
/* Notify messages -- error types */
@@ -971,38 +982,38 @@ static const char *const notification_name[] = {
"CERTIFICATE_UNAVAILABLE",
"UNSUPPORTED_EXCHANGE_TYPE",
"UNEQUAL_PAYLOAD_LENGTHS",
- };
+};
static const char *const notification_status_name[] = {
"CONNECTED",
- };
+};
static const char *const ipsec_notification_name[] = {
"IPSEC_RESPONDER_LIFETIME",
"IPSEC_REPLAY_STATUS",
"IPSEC_INITIAL_CONTACT",
- };
+};
static const char *const notification_dpd_name[] = {
- "R_U_THERE",
- "R_U_THERE_ACK",
+ "R_U_THERE",
+ "R_U_THERE_ACK",
};
enum_names notification_dpd_names =
- { R_U_THERE, R_U_THERE_ACK,
- notification_dpd_name, NULL };
+ { R_U_THERE, R_U_THERE_ACK,
+ notification_dpd_name, NULL };
enum_names ipsec_notification_names =
- { IPSEC_RESPONDER_LIFETIME, IPSEC_INITIAL_CONTACT,
- ipsec_notification_name, &notification_dpd_names };
+ { IPSEC_RESPONDER_LIFETIME, IPSEC_INITIAL_CONTACT,
+ ipsec_notification_name, &notification_dpd_names };
enum_names notification_status_names =
- { CONNECTED, CONNECTED,
- notification_status_name, &ipsec_notification_names };
+ { CONNECTED, CONNECTED,
+ notification_status_name, &ipsec_notification_names };
enum_names notification_names =
- { INVALID_PAYLOAD_TYPE, UNEQUAL_PAYLOAD_LENGTHS,
- notification_name, &notification_status_names };
+ { INVALID_PAYLOAD_TYPE, UNEQUAL_PAYLOAD_LENGTHS,
+ notification_name, &notification_status_names };
/* MODECFG
* From draft-dukes-ike-mode-cfg
@@ -1014,20 +1025,20 @@ const char *const attr_msg_type_name[] = {
"ISAKMP_CFG_SET",
"ISAKMP_CFG_ACK",
NULL
- };
+};
enum_names attr_msg_type_names =
- { 0 , ISAKMP_CFG_ACK, attr_msg_type_name , NULL };
+ { 0 , ISAKMP_CFG_ACK, attr_msg_type_name , NULL };
/* socket address family info */
static const char *const af_inet_name[] = {
"AF_INET",
- };
+};
static const char *const af_inet6_name[] = {
"AF_INET6",
- };
+};
static enum_names af_names6 = { AF_INET6, AF_INET6, af_inet6_name, NULL };
@@ -1045,7 +1056,7 @@ const struct af_info af_inet4_info = {
32,
ID_IPV4_ADDR, ID_IPV4_ADDR_SUBNET, ID_IPV4_ADDR_RANGE,
&ipv4_any, &ipv4_wildcard, &ipv4_all,
- };
+};
const struct af_info af_inet6_info = {
AF_INET6,
@@ -1055,29 +1066,28 @@ const struct af_info af_inet6_info = {
128,
ID_IPV6_ADDR, ID_IPV6_ADDR_SUBNET, ID_IPV6_ADDR_RANGE,
&ipv6_any, &ipv6_wildcard, &ipv6_all,
- };
+};
const struct af_info *
aftoinfo(int af)
{
- switch (af)
- {
- case AF_INET:
- return &af_inet4_info;
- case AF_INET6:
- return &af_inet6_info;
- default:
- return NULL;
- }
+ switch (af)
+ {
+ case AF_INET:
+ return &af_inet4_info;
+ case AF_INET6:
+ return &af_inet6_info;
+ default:
+ return NULL;
+ }
}
-bool
-subnetisnone(const ip_subnet *sn)
+bool subnetisnone(const ip_subnet *sn)
{
- ip_address base;
+ ip_address base;
- networkof(sn, &base);
- return isanyaddr(&base) && subnetishost(sn);
+ networkof(sn, &base);
+ return isanyaddr(&base) && subnetishost(sn);
}
/* BIND enumerated types */
@@ -1085,62 +1095,62 @@ subnetisnone(const ip_subnet *sn)
#include <arpa/nameser.h>
static const char *const rr_type_name[] = {
- "T_A", /* 1 host address */
- "T_NS", /* 2 authoritative server */
- "T_MD", /* 3 mail destination */
- "T_MF", /* 4 mail forwarder */
- "T_CNAME", /* 5 canonical name */
- "T_SOA", /* 6 start of authority zone */
- "T_MB", /* 7 mailbox domain name */
- "T_MG", /* 8 mail group member */
- "T_MR", /* 9 mail rename name */
- "T_NULL", /* 10 null resource record */
- "T_WKS", /* 11 well known service */
- "T_PTR", /* 12 domain name pointer */
- "T_HINFO", /* 13 host information */
- "T_MINFO", /* 14 mailbox information */
- "T_MX", /* 15 mail routing information */
- "T_TXT", /* 16 text strings */
- "T_RP", /* 17 responsible person */
- "T_AFSDB", /* 18 AFS cell database */
- "T_X25", /* 19 X_25 calling address */
- "T_ISDN", /* 20 ISDN calling address */
- "T_RT", /* 21 router */
- "T_NSAP", /* 22 NSAP address */
- "T_NSAP_PTR", /* 23 reverse NSAP lookup (deprecated) */
- "T_SIG", /* 24 security signature */
- "T_KEY", /* 25 security key */
- "T_PX", /* 26 X.400 mail mapping */
- "T_GPOS", /* 27 geographical position (withdrawn) */
- "T_AAAA", /* 28 IP6 Address */
- "T_LOC", /* 29 Location Information */
- "T_NXT", /* 30 Next Valid Name in Zone */
- "T_EID", /* 31 Endpoint identifier */
- "T_NIMLOC", /* 32 Nimrod locator */
- "T_SRV", /* 33 Server selection */
- "T_ATMA", /* 34 ATM Address */
- "T_NAPTR", /* 35 Naming Authority PoinTeR */
+ "T_A", /* 1 host address */
+ "T_NS", /* 2 authoritative server */
+ "T_MD", /* 3 mail destination */
+ "T_MF", /* 4 mail forwarder */
+ "T_CNAME", /* 5 canonical name */
+ "T_SOA", /* 6 start of authority zone */
+ "T_MB", /* 7 mailbox domain name */
+ "T_MG", /* 8 mail group member */
+ "T_MR", /* 9 mail rename name */
+ "T_NULL", /* 10 null resource record */
+ "T_WKS", /* 11 well known service */
+ "T_PTR", /* 12 domain name pointer */
+ "T_HINFO", /* 13 host information */
+ "T_MINFO", /* 14 mailbox information */
+ "T_MX", /* 15 mail routing information */
+ "T_TXT", /* 16 text strings */
+ "T_RP", /* 17 responsible person */
+ "T_AFSDB", /* 18 AFS cell database */
+ "T_X25", /* 19 X_25 calling address */
+ "T_ISDN", /* 20 ISDN calling address */
+ "T_RT", /* 21 router */
+ "T_NSAP", /* 22 NSAP address */
+ "T_NSAP_PTR", /* 23 reverse NSAP lookup (deprecated) */
+ "T_SIG", /* 24 security signature */
+ "T_KEY", /* 25 security key */
+ "T_PX", /* 26 X.400 mail mapping */
+ "T_GPOS", /* 27 geographical position (withdrawn) */
+ "T_AAAA", /* 28 IP6 Address */
+ "T_LOC", /* 29 Location Information */
+ "T_NXT", /* 30 Next Valid Name in Zone */
+ "T_EID", /* 31 Endpoint identifier */
+ "T_NIMLOC", /* 32 Nimrod locator */
+ "T_SRV", /* 33 Server selection */
+ "T_ATMA", /* 34 ATM Address */
+ "T_NAPTR", /* 35 Naming Authority PoinTeR */
NULL
- };
+};
enum_names rr_type_names = { T_A, T_NAPTR, rr_type_name, NULL };
/* Query type values which do not appear in resource records */
static const char *const rr_qtype_name[] = {
- "T_IXFR", /* 251 incremental zone transfer */
- "T_AXFR", /* 252 transfer zone of authority */
- "T_MAILB", /* 253 transfer mailbox records */
- "T_MAILA", /* 254 transfer mail agent records */
- "T_ANY", /* 255 wildcard match */
+ "T_IXFR", /* 251 incremental zone transfer */
+ "T_AXFR", /* 252 transfer zone of authority */
+ "T_MAILB", /* 253 transfer mailbox records */
+ "T_MAILA", /* 254 transfer mail agent records */
+ "T_ANY", /* 255 wildcard match */
NULL
- };
+};
enum_names rr_qtype_names = { T_IXFR, T_ANY, rr_qtype_name, &rr_type_names };
static const char *const rr_class_name[] = {
- "C_IN", /* 1 the arpa internet */
+ "C_IN", /* 1 the arpa internet */
NULL
- };
+};
enum_names rr_class_names = { C_IN, C_IN, rr_class_name, NULL };
@@ -1149,34 +1159,33 @@ enum_names rr_class_names = { C_IN, C_IN, rr_class_name, NULL };
*
*/
const char *const natt_type_bitnames[] = {
- "draft-ietf-ipsec-nat-t-ike-00/01", /* 0 */
- "draft-ietf-ipsec-nat-t-ike-02/03",
- "RFC 3947",
- "3", /* 3 */
- "4", "5", "6", "7",
- "8", "9", "10", "11",
- "12", "13", "14", "15",
- "16", "17", "18", "19",
- "20", "21", "22", "23",
- "24", "25", "26", "27",
- "28", "29",
- "nat is behind me",
- "nat is behind peer"
+ "draft-ietf-ipsec-nat-t-ike-00/01", /* 0 */
+ "draft-ietf-ipsec-nat-t-ike-02/03",
+ "RFC 3947",
+ "3", /* 3 */
+ "4", "5", "6", "7",
+ "8", "9", "10", "11",
+ "12", "13", "14", "15",
+ "16", "17", "18", "19",
+ "20", "21", "22", "23",
+ "24", "25", "26", "27",
+ "28", "29",
+ "nat is behind me",
+ "nat is behind peer"
};
/* look up enum names in an enum_names */
-const char *
-enum_name(enum_names *ed, unsigned long val)
+const char* enum_name(enum_names *ed, unsigned long val)
{
- enum_names *p;
-
- for (p = ed; p != NULL; p = p->en_next_range)
- {
- if (p->en_first <= val && val <= p->en_last)
- return p->en_names[val - p->en_first];
- }
- return NULL;
+ enum_names *p;
+
+ for (p = ed; p != NULL; p = p->en_next_range)
+ {
+ if (p->en_first <= val && val <= p->en_last)
+ return p->en_names[val - p->en_first];
+ }
+ return NULL;
}
/* find or construct a string to describe an enum value
@@ -1185,16 +1194,16 @@ enum_name(enum_names *ed, unsigned long val)
const char *
enum_show(enum_names *ed, unsigned long val)
{
- const char *p = enum_name(ed, val);
+ const char *p = enum_name(ed, val);
- if (p == NULL)
- {
- static char buf[12]; /* only one! I hope that it is big enough */
+ if (p == NULL)
+ {
+ static char buf[12]; /* only one! I hope that it is big enough */
- snprintf(buf, sizeof(buf), "%lu??", val);
- p = buf;
- }
- return p;
+ snprintf(buf, sizeof(buf), "%lu??", val);
+ p = buf;
+ }
+ return p;
}
@@ -1203,123 +1212,126 @@ static char bitnamesbuf[200]; /* only one! I hope that it is big enough! */
int
enum_search(enum_names *ed, const char *str)
{
- enum_names *p;
- const char *ptr;
- unsigned en;
+ enum_names *p;
+ const char *ptr;
+ unsigned en;
- for (p = ed; p != NULL; p = p->en_next_range)
- for (en = p->en_first; en <= p->en_last ;en++)
+ for (p = ed; p != NULL; p = p->en_next_range)
{
- ptr = p->en_names[en - p->en_first];
- if (ptr == 0) continue;
- /* if (strncmp(ptr, str, strlen(ptr))==0) */
- if (strcmp(ptr, str) == 0)
- return en;
+ for (en = p->en_first; en <= p->en_last ;en++)
+ {
+ ptr = p->en_names[en - p->en_first];
+ if (ptr == 0)
+ {
+ continue;
+ }
+ if (streq(ptr, str))
+ {
+ return en;
+ }
+ }
}
- return -1;
+ return -1;
}
/* construct a string to name the bits on in a set
* Result may be in STATIC buffer!
* Note: prettypolicy depends on internal details.
*/
-const char *
-bitnamesof(const char *const table[], lset_t val)
+const char* bitnamesof(const char *const table[], lset_t val)
{
- char *p = bitnamesbuf;
- lset_t bit;
- const char *const *tp;
+ char *p = bitnamesbuf;
+ lset_t bit;
+ const char *const *tp;
- if (val == 0)
- return "none";
+ if (val == 0)
+ return "none";
- for (tp = table, bit = 01; val != 0; bit <<= 1)
- {
- if (val & bit)
+ for (tp = table, bit = 01; val != 0; bit <<= 1)
{
- const char *n = *tp;
- size_t nl;
-
- if (n == NULL || *n == '\0')
- {
- /* no name for this bit, so use hex */
- static char flagbuf[sizeof("0x80000000")];
-
- snprintf(flagbuf, sizeof(flagbuf), "0x%llx", bit);
- n = flagbuf;
- }
-
- nl = strlen(n);
-
- if (p != bitnamesbuf && p < bitnamesbuf+sizeof(bitnamesbuf) - 1)
- *p++ = '+';
-
- if (bitnamesbuf+sizeof(bitnamesbuf) - p > (ptrdiff_t)nl)
- {
- strcpy(p, n);
- p += nl;
- }
- val -= bit;
+ if (val & bit)
+ {
+ const char *n = *tp;
+ size_t nl;
+
+ if (n == NULL || *n == '\0')
+ {
+ /* no name for this bit, so use hex */
+ static char flagbuf[sizeof("0x80000000")];
+
+ snprintf(flagbuf, sizeof(flagbuf), "0x%llx", bit);
+ n = flagbuf;
+ }
+
+ nl = strlen(n);
+
+ if (p != bitnamesbuf && p < bitnamesbuf+sizeof(bitnamesbuf) - 1)
+ *p++ = '+';
+
+ if (bitnamesbuf+sizeof(bitnamesbuf) - p > (ptrdiff_t)nl)
+ {
+ strcpy(p, n);
+ p += nl;
+ }
+ val -= bit;
+ }
+ if (*tp != NULL)
+ tp++; /* move on, but not past end */
}
- if (*tp != NULL)
- tp++; /* move on, but not past end */
- }
- *p = '\0';
- return bitnamesbuf;
+ *p = '\0';
+ return bitnamesbuf;
}
/* print a policy: like bitnamesof, but it also does the non-bitfields.
* Suppress the shunt and fail fields if 0.
*/
-const char *
-prettypolicy(lset_t policy)
+const char* prettypolicy(lset_t policy)
{
- const char *bn = bitnamesof(sa_policy_bit_names
- , policy & ~(POLICY_SHUNT_MASK | POLICY_FAIL_MASK));
- size_t len;
- lset_t shunt = (policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT;
- lset_t fail = (policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT;
-
- if (bn != bitnamesbuf)
- bitnamesbuf[0] = '\0';
- len = strlen(bitnamesbuf);
- if (shunt != 0)
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+%s"
- , policy_shunt_names[shunt]);
- len += strlen(bitnamesbuf + len);
- }
- if (fail != 0)
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+failure%s"
- , policy_fail_names[fail]);
- len += strlen(bitnamesbuf + len);
- }
- if (NEVER_NEGOTIATE(policy))
- {
- snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+NEVER_NEGOTIATE");
- len += strlen(bitnamesbuf + len);
- }
- return bitnamesbuf;
+ const char *bn = bitnamesof(sa_policy_bit_names
+ , policy & ~(POLICY_SHUNT_MASK | POLICY_FAIL_MASK));
+ size_t len;
+ lset_t shunt = (policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT;
+ lset_t fail = (policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT;
+
+ if (bn != bitnamesbuf)
+ bitnamesbuf[0] = '\0';
+ len = strlen(bitnamesbuf);
+ if (shunt != 0)
+ {
+ snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+%s"
+ , policy_shunt_names[shunt]);
+ len += strlen(bitnamesbuf + len);
+ }
+ if (fail != 0)
+ {
+ snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+failure%s"
+ , policy_fail_names[fail]);
+ len += strlen(bitnamesbuf + len);
+ }
+ if (NEVER_NEGOTIATE(policy))
+ {
+ snprintf(bitnamesbuf + len, sizeof(bitnamesbuf) - len, "+NEVER_NEGOTIATE");
+ len += strlen(bitnamesbuf + len);
+ }
+ return bitnamesbuf;
}
/* test a set by seeing if all bits have names */
-bool
-testset(const char *const table[], lset_t val)
+bool testset(const char *const table[], lset_t val)
{
- lset_t bit;
- const char *const *tp;
-
- for (tp = table, bit = 01; val != 0; bit <<= 1, tp++)
- {
- const char *n = *tp;
-
- if (n == NULL || ((val & bit) && *n == '\0'))
- return FALSE;
- val &= ~bit;
- }
- return TRUE;
+ lset_t bit;
+ const char *const *tp;
+
+ for (tp = table, bit = 01; val != 0; bit <<= 1, tp++)
+ {
+ const char *n = *tp;
+
+ if (n == NULL || ((val & bit) && *n == '\0'))
+ return FALSE;
+ val &= ~bit;
+ }
+ return TRUE;
}
@@ -1328,40 +1340,43 @@ const char sparse_end[] = "end of sparse names";
/* look up enum names in a sparse_names */
const char *sparse_name(sparse_names sd, unsigned long val)
{
- const struct sparse_name *p;
+ const struct sparse_name *p;
- for (p = sd; p->name != sparse_end; p++)
- if (p->val == val)
- return p->name;
- return NULL;
+ for (p = sd; p->name != sparse_end; p++)
+ if (p->val == val)
+ return p->name;
+ return NULL;
}
/* find or construct a string to describe an sparse value
* Result may be in STATIC buffer!
*/
-const char *
-sparse_val_show(sparse_names sd, unsigned long val)
+const char* sparse_val_show(sparse_names sd, unsigned long val)
{
- const char *p = sparse_name(sd, val);
+ const char *p = sparse_name(sd, val);
- if (p == NULL)
- {
- static char buf[12]; /* only one! I hope that it is big enough */
+ if (p == NULL)
+ {
+ static char buf[12]; /* only one! I hope that it is big enough */
- snprintf(buf, sizeof(buf), "%lu??", val);
- p = buf;
- }
- return p;
+ snprintf(buf, sizeof(buf), "%lu??", val);
+ p = buf;
+ }
+ return p;
}
void init_constants(void)
{
- happy(anyaddr(AF_INET, &ipv4_any));
- happy(anyaddr(AF_INET6, &ipv6_any));
+ happy(anyaddr(AF_INET, &ipv4_any));
+ happy(anyaddr(AF_INET6, &ipv6_any));
- happy(addrtosubnet(&ipv4_any, &ipv4_wildcard));
- happy(addrtosubnet(&ipv6_any, &ipv6_wildcard));
+ happy(addrtosubnet(&ipv4_any, &ipv4_wildcard));
+ happy(addrtosubnet(&ipv6_any, &ipv6_wildcard));
- happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
- happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
+ happy(initsubnet(&ipv4_any, 0, '0', &ipv4_all));
+ happy(initsubnet(&ipv6_any, 0, '0', &ipv6_all));
}
+
+u_char secret_of_the_day[HASH_SIZE_SHA1];
+
+
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
index 409dd1d61..5fe936e08 100644
--- a/src/pluto/constants.h
+++ b/src/pluto/constants.h
@@ -1,4 +1,3 @@
-
/* manifest constants
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
@@ -12,13 +11,15 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: constants.h 4612 2008-11-11 06:37:37Z andreas $
*/
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
+#include <utils.h>
+#include <utils/identification.h>
+#include <crypto/hashers/hasher.h>
+
extern const char compile_time_interop_options[];
extern void init_constants(void);
@@ -28,8 +29,6 @@ extern void init_constants(void);
* Any changes here should be reflected there.
*/
-#define elemsof(array) (sizeof(array) / sizeof(*(array))) /* number of elements in an array */
-
/* Many routines return only success or failure, but wish to describe
* the failure in a message. We use the convention that they return
* a NULL on success and a pointer to constant string on failure.
@@ -39,19 +38,10 @@ extern void init_constants(void);
* <freeswan.h> defines err_t for this return type.
*/
-typedef int bool;
-#define FALSE 0
-#define TRUE 1
-
-#define NULL_FD (-1) /* NULL file descriptor */
+#define NULL_FD (-1) /* NULL file descriptor */
#define dup_any(fd) ((fd) == NULL_FD? NULL_FD : dup(fd))
#define close_any(fd) { if ((fd) != NULL_FD) { close(fd); (fd) = NULL_FD; } }
-#define BITS_PER_BYTE 8
-
-#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
-#define strcaseeq(a, b) (strcasecmp((a), (b)) == 0) /* clearer shorthand */
-
/* set type with room for at least 64 elements for ALG opts (was 32 in stock FS) */
typedef unsigned long long lset_t;
@@ -71,8 +61,8 @@ typedef unsigned long long lset_t;
# define DEFAULT_CTLBASE IPSEC_PIDDIR "/pluto"
#endif
-#define CTL_SUFFIX ".ctl" /* for UNIX domain socket pathname */
-#define LOCK_SUFFIX ".pid" /* for pluto's lock */
+#define CTL_SUFFIX ".ctl" /* for UNIX domain socket pathname */
+#define LOCK_SUFFIX ".pid" /* for pluto's lock */
#define INFO_SUFFIX ".info" /* for UNIX domain socket for apps */
/* Routines to check and display values.
@@ -86,10 +76,10 @@ typedef unsigned long long lset_t;
*/
struct enum_names {
- unsigned long en_first; /* first value in range */
- unsigned long en_last; /* last value in range (inclusive) */
- const char *const *en_names;
- const struct enum_names *en_next_range; /* descriptor of next range */
+ unsigned long en_first; /* first value in range */
+ unsigned long en_last; /* last value in range (inclusive) */
+ const char *const *en_names;
+ const struct enum_names *en_next_range; /* descriptor of next range */
};
typedef const struct enum_names enum_names;
@@ -108,8 +98,8 @@ extern const char *bitnamesof(const char *const table[], lset_t val);
* Often appropriate for enums defined by others.
*/
struct sparse_name {
- unsigned long val;
- const char *const name;
+ unsigned long val;
+ const char *const name;
};
typedef const struct sparse_name sparse_names[];
@@ -119,264 +109,172 @@ extern const char sparse_end[];
#define FULL_INET_ADDRESS_SIZE 6
-/* Group parameters from draft-ietf-ike-01.txt section 6 */
-
-#define MODP_GENERATOR "2"
-
-#define MODP768_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF"
-
-#define MODP1024_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED " \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 " \
- "FFFFFFFF FFFFFFFF"
-
-#define MODP1536_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 " \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD " \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 " \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED " \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D " \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F " \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D " \
- "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF "
-
-/* draft-ietf-ipsec-ike-modp-groups-03.txt */
-#define MODP2048_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"
-
-#define MODP3072_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"
-
-#define MODP4096_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" \
- "FFFFFFFF FFFFFFFF"
-
-/* copy&pasted from rfc3526: */
-#define MODP6144_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08" \
- "8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B" \
- "302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9" \
- "A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6" \
- "49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8" \
- "FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C" \
- "180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718" \
- "3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D" \
- "04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D" \
- "B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226" \
- "1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC" \
- "E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7 88719A10 BDBA5B26" \
- "99C32718 6AF4E23C 1A946834 B6150BDA 2583E9CA 2AD44CE8 DBBBC2DB" \
- "04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2" \
- "233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127" \
- "D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD F8FF9406" \
- "AD9E530E E5DB382F 413001AE B06A53ED 9027D831 179727B0 865A8918" \
- "DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B DB7F1447 E6CC254B 33205151" \
- "2BD7AF42 6FB8F401 378CD2BF 5983CA01 C64B92EC F032EA15 D1721D03" \
- "F482D7CE 6E74FEF6 D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F" \
- "BEC7E8F3 23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B" \
- "B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632" \
- "387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E" \
- "6DCC4024 FFFFFFFF FFFFFFFF"
-
-/* copy&pasted from rfc3526: */
-#define MODP8192_MODULUS \
- "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
- "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
- "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
- "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
- "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
- "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
- "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
- "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
- "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
- "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
- "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
- "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
- "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
- "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
- "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
- "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
- "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
- "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
- "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
- "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
- "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
- "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \
- "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \
- "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \
- "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \
- "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \
- "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \
- "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
- "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \
- "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \
- "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \
- "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" \
- "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" \
- "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" \
- "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" \
- "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" \
- "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" \
- "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" \
- "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" \
- "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" \
- "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" \
- "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" \
- "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"
-#define LOCALSECRETSIZE (512 / BITS_PER_BYTE)
-
/* limits on nonce sizes. See RFC2409 "The internet key exchange (IKE)" 5 */
-#define MINIMUM_NONCE_SIZE 8 /* bytes */
-#define DEFAULT_NONCE_SIZE 16 /* bytes */
-#define MAXIMUM_NONCE_SIZE 256 /* bytes */
+#define MINIMUM_NONCE_SIZE 8 /* bytes */
+#define DEFAULT_NONCE_SIZE 16 /* bytes */
+#define MAXIMUM_NONCE_SIZE 256 /* bytes */
#define COOKIE_SIZE 8
#define MAX_ISAKMP_SPI_SIZE 16
-#define MD2_DIGEST_SIZE (128 / BITS_PER_BYTE)
-#define MD5_DIGEST_SIZE (128 / BITS_PER_BYTE)
-#define SHA1_DIGEST_SIZE (160 / BITS_PER_BYTE)
-#define SHA2_256_DIGEST_SIZE (256 / BITS_PER_BYTE)
-#define SHA2_384_DIGEST_SIZE (384 / BITS_PER_BYTE)
-#define SHA2_512_DIGEST_SIZE (512 / BITS_PER_BYTE)
-
-#define MD5_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA1_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA2_256_BLOCK_SIZE (512 / BITS_PER_BYTE)
-#define SHA2_384_BLOCK_SIZE (1024 / BITS_PER_BYTE)
-#define SHA2_512_BLOCK_SIZE (1024 / BITS_PER_BYTE)
-
-#define DES_CBC_BLOCK_SIZE (64 / BITS_PER_BYTE)
-
-#define DSS_QBITS 160 /* bits in DSS's "q" (FIPS 186-1) */
+#define DES_CBC_BLOCK_SIZE (64 / BITS_PER_BYTE)
/* Maximum is required for SHA2_512 */
-#define MAX_DIGEST_LEN SHA2_512_DIGEST_SIZE
-#define MAX_HASH_BLOCK_SIZE SHA2_512_BLOCK_SIZE
+#define MAX_DIGEST_LEN HASH_SIZE_SHA512
/* RFC 2404 "HMAC-SHA-1-96" section 3 */
-#define HMAC_SHA1_KEY_LEN SHA1_DIGEST_SIZE
+#define HMAC_SHA1_KEY_LEN HASH_SIZE_SHA1
/* RFC 2403 "HMAC-MD5-96" section 3 */
-#define HMAC_MD5_KEY_LEN MD5_DIGEST_SIZE
+#define HMAC_MD5_KEY_LEN HASH_SIZE_MD5
-#define IKE_UDP_PORT 500
+#define IKE_UDP_PORT 500
+
+/* IPsec AH transform values
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
+ * and in http://www.iana.org/assignments/isakmp-registry
+ */
+enum ipsec_authentication_algo {
+ AH_NONE = 0,
+ AH_MD5 = 2,
+ AH_SHA = 3,
+ AH_DES = 4,
+ AH_SHA2_256 = 5,
+ AH_SHA2_384 = 6,
+ AH_SHA2_512 = 7,
+ AH_RIPEMD = 8,
+ AH_AES_XCBC_MAC = 9,
+ AH_RSA = 10
+};
+
+extern enum_names ah_transformid_names;
+
+/* IPsec ESP transform values
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
+ * and from http://www.iana.org/assignments/isakmp-registry
+ */
+
+enum ipsec_cipher_algo {
+ ESP_NONE = 0,
+ ESP_DES_IV64 = 1,
+ ESP_DES = 2,
+ ESP_3DES = 3,
+ ESP_RC5 = 4,
+ ESP_IDEA = 5,
+ ESP_CAST = 6,
+ ESP_BLOWFISH = 7,
+ ESP_3IDEA = 8,
+ ESP_DES_IV32 = 9,
+ ESP_RC4 = 10,
+ ESP_NULL = 11,
+ ESP_AES = 12,
+ ESP_AES_CTR = 13,
+ ESP_AES_CCM_8 = 14,
+ ESP_AES_CCM_12 = 15,
+ ESP_AES_CCM_16 = 16,
+ ESP_UNASSIGNED_17 = 17,
+ ESP_AES_GCM_8 = 18,
+ ESP_AES_GCM_12 = 19,
+ ESP_AES_GCM_16 = 20,
+ ESP_SEED_CBC = 21,
+ ESP_CAMELLIA = 22,
+ ESP_SERPENT = 252,
+ ESP_TWOFISH = 253
+};
+
+extern enum_names esp_transformid_names;
+
+/* IPCOMP transform values
+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
+ */
+
+enum ipsec_comp_algo {
+ IPSCOMP_NONE = 0,
+ IPCOMP_OUI = 1,
+ IPCOMP_DEFLATE = 2,
+ IPCOMP_LZS = 3,
+ IPCOMP_LZJH = 4
+};
+
+extern enum_names ipcomp_transformid_names;
+
+/* Certificate type values
+ * RFC 2408 ISAKMP, chapter 3.9
+ */
+enum ipsec_cert_type {
+ CERT_NONE= 0,
+ CERT_PKCS7_WRAPPED_X509= 1,
+ CERT_PGP= 2,
+ CERT_DNS_SIGNED_KEY= 3,
+ CERT_X509_SIGNATURE= 4,
+ CERT_X509_KEY_EXCHANGE= 5,
+ CERT_KERBEROS_TOKENS= 6,
+ CERT_CRL= 7,
+ CERT_ARL= 8,
+ CERT_SPKI= 9,
+ CERT_X509_ATTRIBUTE= 10,
+ CERT_RAW_RSA_KEY= 11
+};
/* RFC 2560 OCSP - certificate status */
typedef enum {
- CERT_GOOD = 0,
- CERT_REVOKED = 1,
- CERT_UNKNOWN = 2,
- CERT_UNDEFINED = 3
+ CERT_GOOD = 0,
+ CERT_REVOKED = 1,
+ CERT_UNKNOWN = 2,
+ CERT_UNDEFINED = 3
} cert_status_t;
/* RFC 2459 CRL reason codes */
-extern enum_names crl_reason_names;
+extern enum_name_t *crl_reason_names;
typedef enum {
- REASON_UNSPECIFIED = 0,
- REASON_KEY_COMPROMISE = 1,
- REASON_CA_COMPROMISE = 2,
- REASON_AFFILIATION_CHANGED = 3,
- REASON_SUPERSEDED = 4,
- REASON_CESSATION_OF_OPERATON = 5,
- REASON_CERTIFICATE_HOLD = 6,
- REASON_REMOVE_FROM_CRL = 8
+ REASON_UNSPECIFIED = 0,
+ REASON_KEY_COMPROMISE = 1,
+ REASON_CA_COMPROMISE = 2,
+ REASON_AFFILIATION_CHANGED = 3,
+ REASON_SUPERSEDED = 4,
+ REASON_CESSATION_OF_OPERATON = 5,
+ REASON_CERTIFICATE_HOLD = 6,
+ REASON_REMOVE_FROM_CRL = 8
} crl_reason_t;
/* RFC 3706 Dead Peer Detection */
-extern enum_names dpd_action_names;
+extern enum_name_t *dpd_action_names;
typedef enum {
- DPD_ACTION_NONE = 0,
- DPD_ACTION_CLEAR = 1,
- DPD_ACTION_HOLD = 2,
- DPD_ACTION_RESTART = 3,
- DPD_ACTION_UNKNOWN = 4
+ DPD_ACTION_NONE = 0,
+ DPD_ACTION_CLEAR = 1,
+ DPD_ACTION_HOLD = 2,
+ DPD_ACTION_RESTART = 3,
+ DPD_ACTION_UNKNOWN = 4
} dpd_action_t;
/* Timer events */
-extern enum_names timer_event_names;
+extern enum_name_t *timer_event_names;
enum event_type {
- EVENT_NULL, /* non-event */
- EVENT_REINIT_SECRET, /* Refresh cookie secret */
+ EVENT_NULL, /* non-event */
+ EVENT_REINIT_SECRET, /* Refresh cookie secret */
#ifdef KLIPS
- EVENT_SHUNT_SCAN, /* scan shunt eroutes known to kernel */
+ EVENT_SHUNT_SCAN, /* scan shunt eroutes known to kernel */
#endif
- EVENT_SO_DISCARD, /* discard unfinished state object */
- EVENT_RETRANSMIT, /* Retransmit packet */
- EVENT_SA_REPLACE, /* SA replacement event */
- EVENT_SA_REPLACE_IF_USED, /* SA replacement event */
- EVENT_SA_EXPIRE, /* SA expiration event */
- EVENT_NAT_T_KEEPALIVE, /* NAT Traversal Keepalive */
- EVENT_DPD, /* dead peer detection */
- EVENT_DPD_TIMEOUT, /* dead peer detection timeout */
- EVENT_LOG_DAILY /* reset certain log events/stats */
+ EVENT_SO_DISCARD, /* discard unfinished state object */
+ EVENT_RETRANSMIT, /* Retransmit packet */
+ EVENT_SA_REPLACE, /* SA replacement event */
+ EVENT_SA_REPLACE_IF_USED, /* SA replacement event */
+ EVENT_SA_EXPIRE, /* SA expiration event */
+ EVENT_NAT_T_KEEPALIVE, /* NAT Traversal Keepalive */
+ EVENT_DPD, /* dead peer detection */
+ EVENT_DPD_TIMEOUT, /* dead peer detection timeout */
+ EVENT_LOG_DAILY /* reset certain log events/stats */
};
-#define EVENT_REINIT_SECRET_DELAY 3600 /* 1 hour */
-#define EVENT_RETRANSMIT_DELAY_0 10 /* 10 seconds */
+#define EVENT_REINIT_SECRET_DELAY 3600 /* 1 hour */
+#define EVENT_RETRANSMIT_DELAY_0 10 /* 10 seconds */
/* Misc. stuff */
@@ -429,29 +327,29 @@ extern enum_names doi_names;
extern const char *const debug_bit_names[];
#endif
-#define DBG_RAW LELEM(0) /* raw packet I/O */
-#define DBG_CRYPT LELEM(1) /* encryption/decryption of messages */
-#define DBG_PARSING LELEM(2) /* show decoding of messages */
-#define DBG_EMITTING LELEM(3) /* show encoding of messages */
-#define DBG_CONTROL LELEM(4) /* control flow within Pluto */
-#define DBG_LIFECYCLE LELEM(5) /* SA lifecycle */
-#define DBG_KLIPS LELEM(6) /* messages to KLIPS */
-#define DBG_DNS LELEM(7) /* DNS activity */
-#define DBG_NATT LELEM(8) /* NAT-T */
-#define DBG_OPPO LELEM(9) /* opportunism */
-#define DBG_CONTROLMORE LELEM(10) /* more detailed debugging */
+#define DBG_RAW LELEM(0) /* raw packet I/O */
+#define DBG_CRYPT LELEM(1) /* encryption/decryption of messages */
+#define DBG_PARSING LELEM(2) /* show decoding of messages */
+#define DBG_EMITTING LELEM(3) /* show encoding of messages */
+#define DBG_CONTROL LELEM(4) /* control flow within Pluto */
+#define DBG_LIFECYCLE LELEM(5) /* SA lifecycle */
+#define DBG_KLIPS LELEM(6) /* messages to KLIPS */
+#define DBG_DNS LELEM(7) /* DNS activity */
+#define DBG_NATT LELEM(8) /* NAT-T */
+#define DBG_OPPO LELEM(9) /* opportunism */
+#define DBG_CONTROLMORE LELEM(10) /* more detailed debugging */
-#define DBG_PRIVATE LELEM(11) /* private information: DANGER! */
+#define DBG_PRIVATE LELEM(11) /* private information: DANGER! */
-#define IMPAIR0 12 /* first bit for IMPAIR_* */
+#define IMPAIR0 12 /* first bit for IMPAIR_* */
-#define IMPAIR_DELAY_ADNS_KEY_ANSWER LELEM(IMPAIR0+0) /* sleep before answering */
-#define IMPAIR_DELAY_ADNS_TXT_ANSWER LELEM(IMPAIR0+1) /* sleep before answering */
-#define IMPAIR_BUST_MI2 LELEM(IMPAIR0+2) /* make MI2 really large */
-#define IMPAIR_BUST_MR2 LELEM(IMPAIR0+3) /* make MI2 really large */
+#define IMPAIR_DELAY_ADNS_KEY_ANSWER LELEM(IMPAIR0+0) /* sleep before answering */
+#define IMPAIR_DELAY_ADNS_TXT_ANSWER LELEM(IMPAIR0+1) /* sleep before answering */
+#define IMPAIR_BUST_MI2 LELEM(IMPAIR0+2) /* make MI2 really large */
+#define IMPAIR_BUST_MR2 LELEM(IMPAIR0+3) /* make MI2 really large */
-#define DBG_NONE 0 /* no options on, including impairments */
-#define DBG_ALL LRANGES(DBG_RAW, DBG_CONTROLMORE) /* all logging options on EXCEPT DBG_PRIVATE */
+#define DBG_NONE 0 /* no options on, including impairments */
+#define DBG_ALL LRANGES(DBG_RAW, DBG_CONTROLMORE) /* all logging options on EXCEPT DBG_PRIVATE */
/* State of exchanges
*
@@ -484,86 +382,86 @@ extern enum_names state_names;
extern const char *const state_story[];
enum state_kind {
- STATE_UNDEFINED, /* 0 -- most likely accident */
+ STATE_UNDEFINED, /* 0 -- most likely accident */
- /* Opportunism states: see "Opportunistic Encryption" 2.2 */
+ /* Opportunism states: see "Opportunistic Encryption" 2.2 */
- OPPO_ACQUIRE, /* got an ACQUIRE message for this pair */
- OPPO_GW_DISCOVERED, /* got TXT specifying gateway */
+ OPPO_ACQUIRE, /* got an ACQUIRE message for this pair */
+ OPPO_GW_DISCOVERED, /* got TXT specifying gateway */
- /* IKE states */
+ /* IKE states */
- STATE_MAIN_R0,
- STATE_MAIN_I1,
- STATE_MAIN_R1,
- STATE_MAIN_I2,
- STATE_MAIN_R2,
- STATE_MAIN_I3,
- STATE_MAIN_R3,
- STATE_MAIN_I4,
+ STATE_MAIN_R0,
+ STATE_MAIN_I1,
+ STATE_MAIN_R1,
+ STATE_MAIN_I2,
+ STATE_MAIN_R2,
+ STATE_MAIN_I3,
+ STATE_MAIN_R3,
+ STATE_MAIN_I4,
- STATE_QUICK_R0,
- STATE_QUICK_I1,
- STATE_QUICK_R1,
- STATE_QUICK_I2,
- STATE_QUICK_R2,
+ STATE_QUICK_R0,
+ STATE_QUICK_I1,
+ STATE_QUICK_R1,
+ STATE_QUICK_I2,
+ STATE_QUICK_R2,
- STATE_INFO,
- STATE_INFO_PROTECTED,
+ STATE_INFO,
+ STATE_INFO_PROTECTED,
- /* XAUTH states */
+ /* XAUTH states */
- STATE_XAUTH_I0, /* initiator state (client) */
- STATE_XAUTH_R1, /* responder state (server) */
- STATE_XAUTH_I1,
- STATE_XAUTH_R2,
- STATE_XAUTH_I2,
- STATE_XAUTH_R3,
+ STATE_XAUTH_I0, /* initiator state (client) */
+ STATE_XAUTH_R1, /* responder state (server) */
+ STATE_XAUTH_I1,
+ STATE_XAUTH_R2,
+ STATE_XAUTH_I2,
+ STATE_XAUTH_R3,
- /* Mode Config pull states */
+ /* Mode Config pull states */
- STATE_MODE_CFG_R0, /* responder state (server) */
- STATE_MODE_CFG_I1, /* initiator state (client) */
- STATE_MODE_CFG_R1,
- STATE_MODE_CFG_I2,
+ STATE_MODE_CFG_R0, /* responder state (server) */
+ STATE_MODE_CFG_I1, /* initiator state (client) */
+ STATE_MODE_CFG_R1,
+ STATE_MODE_CFG_I2,
- /* Mode Config push states */
+ /* Mode Config push states */
- STATE_MODE_CFG_I0, /* initiator state (client) */
- STATE_MODE_CFG_R3, /* responder state (server) */
- STATE_MODE_CFG_I3,
- STATE_MODE_CFG_R4,
+ STATE_MODE_CFG_I0, /* initiator state (client) */
+ STATE_MODE_CFG_R3, /* responder state (server) */
+ STATE_MODE_CFG_I3,
+ STATE_MODE_CFG_R4,
- STATE_IKE_ROOF
+ STATE_IKE_ROOF
};
-#define STATE_IKE_FLOOR STATE_MAIN_R0
+#define STATE_IKE_FLOOR STATE_MAIN_R0
-#define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
- | LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
+#define PHASE1_INITIATOR_STATES (LELEM(STATE_MAIN_I1) | LELEM(STATE_MAIN_I2) \
+ | LELEM(STATE_MAIN_I3) | LELEM(STATE_MAIN_I4))
#define ISAKMP_SA_ESTABLISHED_STATES ( \
- LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
- | LELEM(STATE_XAUTH_R1) | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
- | LELEM(STATE_XAUTH_I1) | LELEM(STATE_XAUTH_I2) \
- | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
- | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
+ LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
+ | LELEM(STATE_XAUTH_R1) | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
+ | LELEM(STATE_XAUTH_I1) | LELEM(STATE_XAUTH_I2) \
+ | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
+ | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
- || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
- || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
+ || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
+ || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
- (s) == STATE_MAIN_R3 \
- || (s) == STATE_MAIN_I4 \
- || (s) == STATE_XAUTH_I2 \
- || (s) == STATE_XAUTH_R3 \
- || (s) == STATE_MODE_CFG_R1 \
- || (s) == STATE_MODE_CFG_I2 \
- || (s) == STATE_MODE_CFG_I3 \
- || (s) == STATE_MODE_CFG_R4)
+ (s) == STATE_MAIN_R3 \
+ || (s) == STATE_MAIN_I4 \
+ || (s) == STATE_XAUTH_I2 \
+ || (s) == STATE_XAUTH_R3 \
+ || (s) == STATE_MODE_CFG_R1 \
+ || (s) == STATE_MODE_CFG_I2 \
+ || (s) == STATE_MODE_CFG_I3 \
+ || (s) == STATE_MODE_CFG_R4)
#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
@@ -575,11 +473,11 @@ enum state_kind {
extern enum_names connection_kind_names;
enum connection_kind {
- CK_GROUP, /* policy group: instantiates to template */
- CK_TEMPLATE, /* abstract connection, with wildcard */
- CK_PERMANENT, /* normal connection */
- CK_INSTANCE, /* instance of template, created for a particular attempt */
- CK_GOING_AWAY /* instance being deleted -- don't delete again */
+ CK_GROUP, /* policy group: instantiates to template */
+ CK_TEMPLATE, /* abstract connection, with wildcard */
+ CK_PERMANENT, /* normal connection */
+ CK_INSTANCE, /* instance of template, created for a particular attempt */
+ CK_GOING_AWAY /* instance being deleted -- don't delete again */
};
@@ -593,14 +491,14 @@ extern enum_names routing_story;
/* note that this is assumed to be ordered! */
enum routing_t {
- RT_UNROUTED, /* unrouted */
- RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
- RT_ROUTED_ECLIPSED, /* RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
- RT_ROUTED_PROSPECTIVE, /* routed, and prospective shunt installed */
- RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
- RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
- RT_ROUTED_TUNNEL, /* routed, and erouted to an IPSEC SA group */
- RT_UNROUTED_KEYED /* keyed, but not routed, on purpose */
+ RT_UNROUTED, /* unrouted */
+ RT_UNROUTED_HOLD, /* unrouted, but HOLD shunt installed */
+ RT_ROUTED_ECLIPSED, /* RT_ROUTED_PROSPECTIVE except bare HOLD or instance has eroute */
+ RT_ROUTED_PROSPECTIVE, /* routed, and prospective shunt installed */
+ RT_ROUTED_HOLD, /* routed, and HOLD shunt installed */
+ RT_ROUTED_FAILURE, /* routed, and failure-context shunt installed */
+ RT_ROUTED_TUNNEL, /* routed, and erouted to an IPSEC SA group */
+ RT_UNROUTED_KEYED /* keyed, but not routed, on purpose */
};
#define routed(rs) ((rs) > RT_UNROUTED_HOLD)
@@ -618,25 +516,25 @@ enum routing_t {
extern enum_names payload_names;
extern const char *const payload_name[];
-#define ISAKMP_NEXT_NONE 0 /* No other payload following */
-#define ISAKMP_NEXT_SA 1 /* Security Association */
-#define ISAKMP_NEXT_P 2 /* Proposal */
-#define ISAKMP_NEXT_T 3 /* Transform */
-#define ISAKMP_NEXT_KE 4 /* Key Exchange */
-#define ISAKMP_NEXT_ID 5 /* Identification */
-#define ISAKMP_NEXT_CERT 6 /* Certificate */
-#define ISAKMP_NEXT_CR 7 /* Certificate Request */
-#define ISAKMP_NEXT_HASH 8 /* Hash */
-#define ISAKMP_NEXT_SIG 9 /* Signature */
-#define ISAKMP_NEXT_NONCE 10 /* Nonce */
-#define ISAKMP_NEXT_N 11 /* Notification */
-#define ISAKMP_NEXT_D 12 /* Delete */
-#define ISAKMP_NEXT_VID 13 /* Vendor ID */
+#define ISAKMP_NEXT_NONE 0 /* No other payload following */
+#define ISAKMP_NEXT_SA 1 /* Security Association */
+#define ISAKMP_NEXT_P 2 /* Proposal */
+#define ISAKMP_NEXT_T 3 /* Transform */
+#define ISAKMP_NEXT_KE 4 /* Key Exchange */
+#define ISAKMP_NEXT_ID 5 /* Identification */
+#define ISAKMP_NEXT_CERT 6 /* Certificate */
+#define ISAKMP_NEXT_CR 7 /* Certificate Request */
+#define ISAKMP_NEXT_HASH 8 /* Hash */
+#define ISAKMP_NEXT_SIG 9 /* Signature */
+#define ISAKMP_NEXT_NONCE 10 /* Nonce */
+#define ISAKMP_NEXT_N 11 /* Notification */
+#define ISAKMP_NEXT_D 12 /* Delete */
+#define ISAKMP_NEXT_VID 13 /* Vendor ID */
#define ISAKMP_NEXT_ATTR 14 /* Mode config Attribute */
-#define ISAKMP_NEXT_NATD_RFC 20 /* NAT-Traversal: NAT-D (rfc) */
-#define ISAKMP_NEXT_NATOA_RFC 21 /* NAT-Traversal: NAT-OA (rfc) */
-#define ISAKMP_NEXT_ROOF 22 /* roof on payload types */
+#define ISAKMP_NEXT_NATD_RFC 20 /* NAT-Traversal: NAT-D (rfc) */
+#define ISAKMP_NEXT_NATOA_RFC 21 /* NAT-Traversal: NAT-OA (rfc) */
+#define ISAKMP_NEXT_ROOF 22 /* roof on payload types */
#define ISAKMP_NEXT_NATD_DRAFTS 130 /* NAT-Traversal: NAT-D (drafts) */
#define ISAKMP_NEXT_NATOA_DRAFTS 131 /* NAT-Traversal: NAT-OA (drafts) */
@@ -687,18 +585,24 @@ extern enum_names modecfg_attr_names;
extern enum_names xauth_attr_names;
-/* ISAKMP mode config attributes specific to the Unity vendor Id */
-#define UNITY_BANNER 28672
-#define UNITY_SAVE_PASSWD 28673
-#define UNITY_DEF_DOMAIN 28674
-#define UNITY_SPLITDNS_NAME 28675
-#define UNITY_SPLIT_INCLUDE 28676
-#define UNITY_NATT_PORT 28677
-#define UNITY_LOCAL_LAN 28678
-#define UNITY_PFS 28679
-#define UNITY_FW_TYPE 28680
-#define UNITY_BACKUP_SERVERS 28681
-#define UNITY_DDNS_HOSTNAME 28682
+/* ISAKMP mode config attributes specific to Microsoft */
+#define INTERNAL_IP4_SERVER 23456
+#define INTERNAL_IP6_SERVER 23457
+
+extern enum_names microsoft_attr_names;
+
+/* ISAKMP mode config attributes specific to the Unity vendor ID */
+#define UNITY_BANNER 28672
+#define UNITY_SAVE_PASSWD 28673
+#define UNITY_DEF_DOMAIN 28674
+#define UNITY_SPLITDNS_NAME 28675
+#define UNITY_SPLIT_INCLUDE 28676
+#define UNITY_NATT_PORT 28677
+#define UNITY_LOCAL_LAN 28678
+#define UNITY_PFS 28679
+#define UNITY_FW_TYPE 28680
+#define UNITY_BACKUP_SERVERS 28681
+#define UNITY_DDNS_HOSTNAME 28682
#define UNITY_BASE UNITY_BANNER
@@ -711,8 +615,8 @@ extern enum_names unity_attr_names;
#define XAUTH_TYPE_SKEY 3
/* Values for XAUTH_STATUS */
-#define XAUTH_STATUS_FAIL 0
-#define XAUTH_STATUS_OK 1
+#define XAUTH_STATUS_FAIL 0
+#define XAUTH_STATUS_OK 1
extern enum_names xauth_type_names;
@@ -732,19 +636,19 @@ extern enum_names exchange_names;
#define ISAKMP_XCHG_NONE 0
#define ISAKMP_XCHG_BASE 1
-#define ISAKMP_XCHG_IDPROT 2 /* ID Protection */
-#define ISAKMP_XCHG_AO 3 /* Authentication Only */
-#define ISAKMP_XCHG_AGGR 4 /* Aggressive */
-#define ISAKMP_XCHG_INFO 5 /* Informational */
-#define ISAKMP_XCHG_MODE_CFG 6 /* Mode Config */
+#define ISAKMP_XCHG_IDPROT 2 /* ID Protection */
+#define ISAKMP_XCHG_AO 3 /* Authentication Only */
+#define ISAKMP_XCHG_AGGR 4 /* Aggressive */
+#define ISAKMP_XCHG_INFO 5 /* Informational */
+#define ISAKMP_XCHG_MODE_CFG 6 /* Mode Config */
/* Extra exchange types, defined by Oakley
* RFC2409 "The Internet Key Exchange (IKE)", near end of Appendix A
*/
-#define ISAKMP_XCHG_QUICK 32 /* Oakley Quick Mode */
-#define ISAKMP_XCHG_NGRP 33 /* Oakley New Group Mode */
+#define ISAKMP_XCHG_QUICK 32 /* Oakley Quick Mode */
+#define ISAKMP_XCHG_NGRP 33 /* Oakley New Group Mode */
/* added in draft-ietf-ipsec-ike-01.txt, near end of Appendix A */
-#define ISAKMP_XCHG_ACK_INFO 34 /* Oakley Acknowledged Informational */
+#define ISAKMP_XCHG_ACK_INFO 34 /* Oakley Acknowledged Informational */
/* Flag bits */
@@ -774,20 +678,14 @@ extern enum_names protocol_names;
/* warning: trans_show uses enum_show, so same static buffer is used */
#define trans_show(p, t) \
- ((p)==PROTO_IPSEC_AH ? enum_show(&ah_transformid_names, (t)) \
- : (p)==PROTO_IPSEC_ESP ? enum_show(&esp_transformid_names, (t)) \
- : (p)==PROTO_IPCOMP ? enum_show(&ipcomp_transformid_names, (t)) \
- : "??")
-
-/* many transform values are moved to freeswan/ipsec_policy.h */
-
-extern enum_names isakmp_transformid_names;
+ ((p)==PROTO_IPSEC_AH ? enum_show(&ah_transformid_names, (t)) \
+ : (p)==PROTO_IPSEC_ESP ? enum_show(&esp_transformid_names, (t)) \
+ : (p)==PROTO_IPCOMP ? enum_show(&ipcomp_transformid_names, (t)) \
+ : "??")
#define KEY_IKE 1
-extern enum_names ah_transformid_names;
-extern enum_names esp_transformid_names;
-extern enum_names ipcomp_transformid_names;
+extern enum_names isakmp_transformid_names;
/* the following are from RFC 2393/draft-shacham-ippcp-rfc2393bis-05.txt 3.3 */
typedef u_int16_t cpi_t;
@@ -801,15 +699,16 @@ typedef u_int16_t cpi_t;
extern enum_names ident_names;
extern enum_names cert_type_names;
-extern enum_names cert_policy_names;
+
+extern enum_name_t *cert_policy_names;
typedef enum certpolicy {
- CERT_ALWAYS_SEND = 0, /* the default */
- CERT_SEND_IF_ASKED = 1,
- CERT_NEVER_SEND = 2,
+ CERT_ALWAYS_SEND = 0,
+ CERT_SEND_IF_ASKED = 1,
+ CERT_NEVER_SEND = 2,
- CERT_YES_SEND = 3, /* synonym for CERT_ALWAYS_SEND */
- CERT_NO_SEND = 4 /* synonym for CERT_NEVER_SEND */
+ CERT_YES_SEND = 3, /* synonym for CERT_ALWAYS_SEND */
+ CERT_NO_SEND = 4 /* synonym for CERT_NEVER_SEND */
} certpolicy_t;
/* Policies for establishing an SA
@@ -825,36 +724,36 @@ extern const char *prettypolicy(lset_t policy);
/* ISAKMP auth techniques (none means never negotiate) */
#define POLICY_PSK LELEM(0)
-#define POLICY_RSASIG LELEM(1)
+#define POLICY_PUBKEY LELEM(1)
-#define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */
-#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_RSASIG | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG)
-#define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */
+#define POLICY_ISAKMP_SHIFT 0 /* log2(POLICY_PSK) */
+#define POLICY_ID_AUTH_MASK (POLICY_PSK | POLICY_PUBKEY | POLICY_XAUTH_PSK | POLICY_XAUTH_RSASIG)
+#define POLICY_ISAKMP_MASK POLICY_ID_AUTH_MASK /* all so far */
/* Quick Mode (IPSEC) attributes */
-#define POLICY_ENCRYPT LELEM(2) /* must be first of IPSEC policies */
-#define POLICY_AUTHENTICATE LELEM(3) /* must be second */
-#define POLICY_COMPRESS LELEM(4) /* must be third */
+#define POLICY_ENCRYPT LELEM(2) /* must be first of IPSEC policies */
+#define POLICY_AUTHENTICATE LELEM(3) /* must be second */
+#define POLICY_COMPRESS LELEM(4) /* must be third */
#define POLICY_TUNNEL LELEM(5)
#define POLICY_PFS LELEM(6)
-#define POLICY_DISABLEARRIVALCHECK LELEM(7) /* supress tunnel egress address checking */
+#define POLICY_DISABLEARRIVALCHECK LELEM(7) /* supress tunnel egress address checking */
-#define POLICY_IPSEC_SHIFT 2 /* log2(POLICY_ENCRYPT) */
-#define POLICY_IPSEC_MASK LRANGES(POLICY_ENCRYPT, POLICY_DISABLEARRIVALCHECK)
+#define POLICY_IPSEC_SHIFT 2 /* log2(POLICY_ENCRYPT) */
+#define POLICY_IPSEC_MASK LRANGES(POLICY_ENCRYPT, POLICY_DISABLEARRIVALCHECK)
/* shunt attributes: what to do when routed without tunnel (2 bits) */
-#define POLICY_SHUNT_SHIFT 8 /* log2(POLICY_SHUNT_PASS) */
-#define POLICY_SHUNT_MASK (03ul << POLICY_SHUNT_SHIFT)
+#define POLICY_SHUNT_SHIFT 8 /* log2(POLICY_SHUNT_PASS) */
+#define POLICY_SHUNT_MASK (03ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_TRAP (0ul << POLICY_SHUNT_SHIFT) /* default: negotiate */
-#define POLICY_SHUNT_PASS (1ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_DROP (2ul << POLICY_SHUNT_SHIFT)
-#define POLICY_SHUNT_REJECT (3ul << POLICY_SHUNT_SHIFT)
+#define POLICY_SHUNT_TRAP (0ul << POLICY_SHUNT_SHIFT) /* default: negotiate */
+#define POLICY_SHUNT_PASS (1ul << POLICY_SHUNT_SHIFT)
+#define POLICY_SHUNT_DROP (2ul << POLICY_SHUNT_SHIFT)
+#define POLICY_SHUNT_REJECT (3ul << POLICY_SHUNT_SHIFT)
/* fail attributes: what to do with failed negotiation (2 bits) */
-#define POLICY_FAIL_SHIFT 10 /* log2(POLICY_FAIL_PASS) */
-#define POLICY_FAIL_MASK (03ul << POLICY_FAIL_SHIFT)
+#define POLICY_FAIL_SHIFT 10 /* log2(POLICY_FAIL_PASS) */
+#define POLICY_FAIL_MASK (03ul << POLICY_FAIL_SHIFT)
#define POLICY_FAIL_NONE (0ul << POLICY_FAIL_SHIFT) /* default */
#define POLICY_FAIL_PASS (1ul << POLICY_FAIL_SHIFT)
@@ -864,21 +763,20 @@ extern const char *prettypolicy(lset_t policy);
/* connection policy
* Other policies could vary per state object. These live in connection.
*/
-#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */
-#define POLICY_OPPO LELEM(13) /* is this opportunistic? */
-#define POLICY_GROUP LELEM(14) /* is this a group template? */
-#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
-#define POLICY_UP LELEM(16) /* do we want this up? */
-#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */
-#define POLICY_XAUTH_PSK LELEM(18) /* do we support XAUTH????PreShared? */
-#define POLICY_XAUTH_RSASIG LELEM(19) /* do we support XAUTH????RSA? */
-#define POLICY_XAUTH_SERVER LELEM(20) /* are we an XAUTH server? */
-#define POLICY_DONT_REAUTH LELEM(21) /* don't reauthenticate on rekeying, IKEv2 only */
-#define POLICY_BEET LELEM(22) /* bound end2end tunnel, IKEv2 */
-#define POLICY_MOBIKE LELEM(23) /* enable MOBIKE for IKEv2 */
-#define POLICY_FORCE_ENCAP LELEM(24) /* force UDP encapsulation (IKEv2) */
-#define POLICY_ECDSASIG LELEM(25) /* ECDSA signature (IKEv2) */
-#define POLICY_PROXY LELEM(26) /* proxy transport mode (MIPv6) */
+#define POLICY_DONT_REKEY LELEM(12) /* don't rekey state either Phase */
+#define POLICY_OPPO LELEM(13) /* is this opportunistic? */
+#define POLICY_GROUP LELEM(14) /* is this a group template? */
+#define POLICY_GROUTED LELEM(15) /* do we want this group routed? */
+#define POLICY_UP LELEM(16) /* do we want this up? */
+#define POLICY_MODECFG_PUSH LELEM(17) /* is modecfg pushed by server? */
+#define POLICY_XAUTH_PSK LELEM(18) /* do we support XAUTH????PreShared? */
+#define POLICY_XAUTH_RSASIG LELEM(19) /* do we support XAUTH????RSA? */
+#define POLICY_XAUTH_SERVER LELEM(20) /* are we an XAUTH server? */
+#define POLICY_DONT_REAUTH LELEM(21) /* don't reauthenticate on rekeying, IKEv2 only */
+#define POLICY_BEET LELEM(22) /* bound end2end tunnel, IKEv2 */
+#define POLICY_MOBIKE LELEM(23) /* enable MOBIKE for IKEv2 */
+#define POLICY_FORCE_ENCAP LELEM(24) /* force UDP encapsulation (IKEv2) */
+#define POLICY_PROXY LELEM(25) /* proxy transport mode (MIPv6) */
/* Any IPsec policy? If not, a connection description
* is only for ISAKMP SA, not IPSEC SA. (A pun, I admit.)
@@ -903,17 +801,17 @@ extern const char *const oakley_attr_bit_names[];
#define OAKLEY_AUTHENTICATION_METHOD 3
#define OAKLEY_GROUP_DESCRIPTION 4
#define OAKLEY_GROUP_TYPE 5
-#define OAKLEY_GROUP_PRIME 6 /* B/V */
-#define OAKLEY_GROUP_GENERATOR_ONE 7 /* B/V */
-#define OAKLEY_GROUP_GENERATOR_TWO 8 /* B/V */
-#define OAKLEY_GROUP_CURVE_A 9 /* B/V */
-#define OAKLEY_GROUP_CURVE_B 10 /* B/V */
+#define OAKLEY_GROUP_PRIME 6 /* B/V */
+#define OAKLEY_GROUP_GENERATOR_ONE 7 /* B/V */
+#define OAKLEY_GROUP_GENERATOR_TWO 8 /* B/V */
+#define OAKLEY_GROUP_CURVE_A 9 /* B/V */
+#define OAKLEY_GROUP_CURVE_B 10 /* B/V */
#define OAKLEY_LIFE_TYPE 11
-#define OAKLEY_LIFE_DURATION 12 /* B/V */
+#define OAKLEY_LIFE_DURATION 12 /* B/V */
#define OAKLEY_PRF 13
#define OAKLEY_KEY_LENGTH 14
#define OAKLEY_FIELD_SIZE 15
-#define OAKLEY_GROUP_ORDER 16 /* B/V */
+#define OAKLEY_GROUP_ORDER 16 /* B/V */
#define OAKLEY_BLOCK_SIZE 17
/* for each Oakley attribute, which enum_names describes its values? */
@@ -926,14 +824,14 @@ extern enum_names *oakley_attr_val_descs[];
extern enum_names ipsec_attr_names;
#define SA_LIFE_TYPE 1
-#define SA_LIFE_DURATION 2 /* B/V */
+#define SA_LIFE_DURATION 2 /* B/V */
#define GROUP_DESCRIPTION 3
#define ENCAPSULATION_MODE 4
#define AUTH_ALGORITHM 5
#define KEY_LENGTH 6
#define KEY_ROUNDS 7
#define COMPRESS_DICT_SIZE 8
-#define COMPRESS_PRIVATE_ALG 9 /* B/V */
+#define COMPRESS_PRIVATE_ALG 9 /* B/V */
/* for each IPsec attribute, which enum_names describes its values? */
extern enum_names *ipsec_attr_val_descs[];
@@ -961,9 +859,9 @@ extern enum_names sa_lifetime_names;
#define PLUTO_SA_LIFE_DURATION_DEFAULT 3600 /* one hour (pluto(8)) */
#define SA_LIFE_DURATION_MAXIMUM 86400 /* one day */
-#define SA_REPLACEMENT_MARGIN_DEFAULT 540 /* (IPSEC & IKE) nine minutes */
-#define SA_REPLACEMENT_FUZZ_DEFAULT 100 /* (IPSEC & IKE) 100% of MARGIN */
-#define SA_REPLACEMENT_RETRIES_DEFAULT 3 /* (IPSEC & IKE) */
+#define SA_REPLACEMENT_MARGIN_DEFAULT 540 /* (IPSEC & IKE) nine minutes */
+#define SA_REPLACEMENT_FUZZ_DEFAULT 100 /* (IPSEC & IKE) 100% of MARGIN */
+#define SA_REPLACEMENT_RETRIES_DEFAULT 3 /* (IPSEC & IKE) */
#define SA_LIFE_DURATION_K_DEFAULT 0xFFFFFFFFlu
@@ -971,7 +869,7 @@ extern enum_names sa_lifetime_names;
extern enum_names enc_mode_names;
-#define ENCAPSULATION_MODE_UNSPECIFIED 0 /* not legal -- used internally */
+#define ENCAPSULATION_MODE_UNSPECIFIED 0 /* not legal -- used internally */
#define ENCAPSULATION_MODE_TUNNEL 1
#define ENCAPSULATION_MODE_TRANSPORT 2
@@ -985,18 +883,18 @@ extern enum_names enc_mode_names;
extern enum_names auth_alg_names, extended_auth_alg_names;
-#define AUTH_ALGORITHM_NONE 0 /* our private designation */
-#define AUTH_ALGORITHM_HMAC_MD5 1
-#define AUTH_ALGORITHM_HMAC_SHA1 2
-#define AUTH_ALGORITHM_DES_MAC 3
-#define AUTH_ALGORITHM_KPDK 4
-#define AUTH_ALGORITHM_HMAC_SHA2_256 5
-#define AUTH_ALGORITHM_HMAC_SHA2_384 6
-#define AUTH_ALGORITHM_HMAC_SHA2_512 7
-#define AUTH_ALGORITHM_HMAC_RIPEMD 8
-#define AUTH_ALGORITHM_AES_XCBC_MAC 9
-#define AUTH_ALGORITHM_SIG_RSA 10
-#define AUTH_ALGORITHM_NULL 251
+#define AUTH_ALGORITHM_NONE 0 /* our private designation */
+#define AUTH_ALGORITHM_HMAC_MD5 1
+#define AUTH_ALGORITHM_HMAC_SHA1 2
+#define AUTH_ALGORITHM_DES_MAC 3
+#define AUTH_ALGORITHM_KPDK 4
+#define AUTH_ALGORITHM_HMAC_SHA2_256 5
+#define AUTH_ALGORITHM_HMAC_SHA2_384 6
+#define AUTH_ALGORITHM_HMAC_SHA2_512 7
+#define AUTH_ALGORITHM_HMAC_RIPEMD 8
+#define AUTH_ALGORITHM_AES_XCBC_MAC 9
+#define AUTH_ALGORITHM_SIG_RSA 10
+#define AUTH_ALGORITHM_NULL 251
/* Oakley Lifetime Type attribute
* draft-ietf-ipsec-ike-01.txt appendix A
@@ -1030,23 +928,24 @@ extern enum_names oakley_prf_names;
extern enum_names oakley_enc_names;
-#define OAKLEY_DES_CBC 1
-#define OAKLEY_IDEA_CBC 2
-#define OAKLEY_BLOWFISH_CBC 3
-#define OAKLEY_RC5_R16_B64_CBC 4
-#define OAKLEY_3DES_CBC 5
-#define OAKLEY_CAST_CBC 6
-#define OAKLEY_AES_CBC 7
+#define OAKLEY_DES_CBC 1
+#define OAKLEY_IDEA_CBC 2
+#define OAKLEY_BLOWFISH_CBC 3
+#define OAKLEY_RC5_R16_B64_CBC 4
+#define OAKLEY_3DES_CBC 5
+#define OAKLEY_CAST_CBC 6
+#define OAKLEY_AES_CBC 7
+#define OAKLEY_CAMELLIA_CBC 8
-#define OAKLEY_MARS_CBC 65001
-#define OAKLEY_RC6_CBC 65002
-#define OAKLEY_ID_65003 65003
-#define OAKLEY_SERPENT_CBC 65004
-#define OAKLEY_TWOFISH_CBC 65005
+#define OAKLEY_MARS_CBC 65001
+#define OAKLEY_RC6_CBC 65002
+#define OAKLEY_ID_65003 65003
+#define OAKLEY_SERPENT_CBC 65004
+#define OAKLEY_TWOFISH_CBC 65005
-#define OAKLEY_TWOFISH_CBC_SSH 65289
+#define OAKLEY_TWOFISH_CBC_SSH 65289
-#define OAKLEY_ENCRYPT_MAX 65535 /* pretty useless :) */
+#define OAKLEY_ENCRYPT_MAX 65535 /* pretty useless :) */
/* Oakley Hash Algorithm attribute
* draft-ietf-ipsec-ike-01.txt appendix A
@@ -1079,42 +978,35 @@ extern enum_names oakley_auth_names;
#define OAKLEY_RSA_ENC_REV 5
#define OAKLEY_ELGAMAL_ENC 6
#define OAKLEY_ELGAMAL_ENC_REV 7
+#define OAKLEY_ECDSA_SIG 8
+#define OAKLEY_ECDSA_256 9
+#define OAKLEY_ECDSA_384 10
+#define OAKLEY_ECDSA_521 11
-#define OAKLEY_AUTH_ROOF 8 /* roof on auth values THAT WE SUPPORT */
+#define OAKLEY_AUTH_ROOF 12 /* roof on auth values THAT WE SUPPORT */
-#define HybridInitRSA 64221
-#define HybridRespRSA 64222
-#define HybridInitDSS 64223
-#define HybridRespDSS 64224
+#define HybridInitRSA 64221
+#define HybridRespRSA 64222
+#define HybridInitDSS 64223
+#define HybridRespDSS 64224
-#define XAUTHInitPreShared 65001
-#define XAUTHRespPreShared 65002
-#define XAUTHInitDSS 65003
+#define XAUTHInitPreShared 65001
+#define XAUTHRespPreShared 65002
+#define XAUTHInitDSS 65003
#define XAUTHRespDSS 65004
-#define XAUTHInitRSA 65005
-#define XAUTHRespRSA 65006
-#define XAUTHInitRSAEncryption 65007
-#define XAUTHRespRSAEncryption 65008
-#define XAUTHInitRSARevisedEncryption 65009
-#define XAUTHRespRSARevisedEncryption 65010
+#define XAUTHInitRSA 65005
+#define XAUTHRespRSA 65006
+#define XAUTHInitRSAEncryption 65007
+#define XAUTHRespRSAEncryption 65008
+#define XAUTHInitRSARevisedEncryption 65009
+#define XAUTHRespRSARevisedEncryption 65010
/* Oakley Group Description attribute
* draft-ietf-ipsec-ike-01.txt appendix A
*/
extern enum_names oakley_group_names;
-#define OAKLEY_GROUP_MODP768 1
-#define OAKLEY_GROUP_MODP1024 2
-#define OAKLEY_GROUP_GP155 3
-#define OAKLEY_GROUP_GP185 4
-#define OAKLEY_GROUP_MODP1536 5
-
-#define OAKLEY_GROUP_MODP2048 14
-#define OAKLEY_GROUP_MODP3072 15
-#define OAKLEY_GROUP_MODP4096 16
-#define OAKLEY_GROUP_MODP6144 17
-#define OAKLEY_GROUP_MODP8192 18
-/* you must also touch: constants.c, crypto.c */
+/* you must also touch: constants.c, crypto.c */
/* Oakley Group Type attribute
* draft-ietf-ipsec-ike-01.txt appendix A
@@ -1134,54 +1026,54 @@ extern enum_names notification_names;
extern enum_names ipsec_notification_names;
typedef enum {
- NOTHING_WRONG = 0, /* unofficial! */
-
- INVALID_PAYLOAD_TYPE = 1,
- DOI_NOT_SUPPORTED = 2,
- SITUATION_NOT_SUPPORTED = 3,
- INVALID_COOKIE = 4,
- INVALID_MAJOR_VERSION = 5,
- INVALID_MINOR_VERSION = 6,
- INVALID_EXCHANGE_TYPE = 7,
- INVALID_FLAGS = 8,
- INVALID_MESSAGE_ID = 9,
- INVALID_PROTOCOL_ID = 10,
- INVALID_SPI = 11,
- INVALID_TRANSFORM_ID = 12,
- ATTRIBUTES_NOT_SUPPORTED = 13,
- NO_PROPOSAL_CHOSEN = 14,
- BAD_PROPOSAL_SYNTAX = 15,
- PAYLOAD_MALFORMED = 16,
- INVALID_KEY_INFORMATION = 17,
- INVALID_ID_INFORMATION = 18,
- INVALID_CERT_ENCODING = 19,
- INVALID_CERTIFICATE = 20,
- CERT_TYPE_UNSUPPORTED = 21,
- INVALID_CERT_AUTHORITY = 22,
- INVALID_HASH_INFORMATION = 23,
- AUTHENTICATION_FAILED = 24,
- INVALID_SIGNATURE = 25,
- ADDRESS_NOTIFICATION = 26,
- NOTIFY_SA_LIFETIME = 27,
- CERTIFICATE_UNAVAILABLE = 28,
- UNSUPPORTED_EXCHANGE_TYPE = 29,
- UNEQUAL_PAYLOAD_LENGTHS = 30,
-
- /* ISAKMP status type */
- CONNECTED = 16384,
-
- /* IPSEC DOI additions; status types (RFC2407 IPSEC DOI 4.6.3)
- * These must be sent under the protection of an ISAKMP SA.
- */
- IPSEC_RESPONDER_LIFETIME = 24576,
- IPSEC_REPLAY_STATUS = 24577,
- IPSEC_INITIAL_CONTACT = 24578,
-
- /* RFC 3706 DPD */
- R_U_THERE = 36136,
- R_U_THERE_ACK = 36137
-
- } notification_t;
+ NOTHING_WRONG = 0, /* unofficial! */
+
+ INVALID_PAYLOAD_TYPE = 1,
+ DOI_NOT_SUPPORTED = 2,
+ SITUATION_NOT_SUPPORTED = 3,
+ INVALID_COOKIE = 4,
+ INVALID_MAJOR_VERSION = 5,
+ INVALID_MINOR_VERSION = 6,
+ INVALID_EXCHANGE_TYPE = 7,
+ INVALID_FLAGS = 8,
+ INVALID_MESSAGE_ID = 9,
+ INVALID_PROTOCOL_ID = 10,
+ INVALID_SPI = 11,
+ INVALID_TRANSFORM_ID = 12,
+ ATTRIBUTES_NOT_SUPPORTED = 13,
+ NO_PROPOSAL_CHOSEN = 14,
+ BAD_PROPOSAL_SYNTAX = 15,
+ PAYLOAD_MALFORMED = 16,
+ INVALID_KEY_INFORMATION = 17,
+ INVALID_ID_INFORMATION = 18,
+ INVALID_CERT_ENCODING = 19,
+ INVALID_CERTIFICATE = 20,
+ CERT_TYPE_UNSUPPORTED = 21,
+ INVALID_CERT_AUTHORITY = 22,
+ INVALID_HASH_INFORMATION = 23,
+ AUTHENTICATION_FAILED = 24,
+ INVALID_SIGNATURE = 25,
+ ADDRESS_NOTIFICATION = 26,
+ NOTIFY_SA_LIFETIME = 27,
+ CERTIFICATE_UNAVAILABLE = 28,
+ UNSUPPORTED_EXCHANGE_TYPE = 29,
+ UNEQUAL_PAYLOAD_LENGTHS = 30,
+
+ /* ISAKMP status type */
+ CONNECTED = 16384,
+
+ /* IPSEC DOI additions; status types (RFC2407 IPSEC DOI 4.6.3)
+ * These must be sent under the protection of an ISAKMP SA.
+ */
+ IPSEC_RESPONDER_LIFETIME = 24576,
+ IPSEC_REPLAY_STATUS = 24577,
+ IPSEC_INITIAL_CONTACT = 24578,
+
+ /* RFC 3706 DPD */
+ R_U_THERE = 36136,
+ R_U_THERE_ACK = 36137
+
+ } notification_t;
/* Public key algorithm number
@@ -1192,8 +1084,8 @@ typedef enum {
enum pubkey_alg
{
- PUBKEY_ALG_RSA = 1,
- PUBKEY_ALG_DSA = 3,
+ PUBKEY_ALG_RSA = 1,
+ PUBKEY_ALG_DSA = 3,
};
/* Limits on size of RSA moduli.
@@ -1203,37 +1095,37 @@ enum pubkey_alg
* real security. For now, we require 512 bits.
*/
-#define RSA_MIN_OCTETS_RFC 12
+#define RSA_MIN_OCTETS_RFC 12
-#define RSA_MIN_OCTETS (512 / BITS_PER_BYTE)
-#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
+#define RSA_MIN_OCTETS (512 / BITS_PER_BYTE)
+#define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
-#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE)
-#define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
+#define RSA_MAX_OCTETS (8192 / BITS_PER_BYTE)
+#define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
/* Note: RFC 2537 encoding adds a few bytes. If you use a small
* modulus like 3, the overhead is only 2 bytes
*/
-#define RSA_MAX_ENCODING_BYTES (RSA_MAX_OCTETS + 2)
+#define RSA_MAX_ENCODING_BYTES (RSA_MAX_OCTETS + 2)
/* socket address family info */
struct af_info
{
- int af;
- const char *name;
- size_t ia_sz;
- size_t sa_sz;
- int mask_cnt;
- u_int8_t id_addr, id_subnet, id_range;
- const ip_address *any;
- const ip_subnet *none; /* 0.0.0.0/32 or IPv6 equivalent */
- const ip_subnet *all; /* 0.0.0.0/0 or IPv6 equivalent */
+ int af;
+ const char *name;
+ size_t ia_sz;
+ size_t sa_sz;
+ int mask_cnt;
+ u_int8_t id_addr, id_subnet, id_range;
+ const ip_address *any;
+ const ip_subnet *none; /* 0.0.0.0/32 or IPv6 equivalent */
+ const ip_subnet *all; /* 0.0.0.0/0 or IPv6 equivalent */
};
extern const struct af_info
- af_inet4_info,
- af_inet6_info;
+ af_inet4_info,
+ af_inet6_info;
extern const struct af_info *aftoinfo(int af);
@@ -1245,18 +1137,18 @@ extern bool subnetisnone(const ip_subnet *sn);
/* BIND enumerated types */
extern enum_names
- rr_qtype_names,
- rr_type_names,
- rr_class_names;
+ rr_qtype_names,
+ rr_type_names,
+ rr_class_names;
/* How authenticated is info that might have come from DNS?
* In order of increasing confidence.
*/
enum dns_auth_level {
- DAL_UNSIGNED, /* AD in response, but no signature: no authentication */
- DAL_NOTSEC, /* no AD in response: authentication impossible */
- DAL_SIGNED, /* AD and signature in response: authentic */
- DAL_LOCAL /* locally provided (pretty good) */
+ DAL_UNSIGNED, /* AD in response, but no signature: no authentication */
+ DAL_NOTSEC, /* no AD in response: authentication impossible */
+ DAL_SIGNED, /* AD and signature in response: authentic */
+ DAL_LOCAL /* locally provided (pretty good) */
};
/*
@@ -1272,4 +1164,7 @@ enum dns_auth_level {
/* natt traversal types */
extern const char *const natt_type_bitnames[];
+/* secret value for responder cookies */
+extern u_char secret_of_the_day[HASH_SIZE_SHA1];
+
#endif /* _CONSTANTS_H */
diff --git a/src/pluto/cookie.c b/src/pluto/cookie.c
index 00197321c..00c863f18 100644
--- a/src/pluto/cookie.c
+++ b/src/pluto/cookie.c
@@ -1,6 +1,7 @@
/* cookie generation/verification routines.
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: cookie.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -23,45 +22,52 @@
#include <freeswan.h>
+#include <library.h>
+#include <crypto/rngs/rng.h>
+
#include "constants.h"
#include "defs.h"
-#include "sha1.h"
-#include "rnd.h"
#include "cookie.h"
-const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
+const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
/* Generate a cookie.
* First argument is true if we're to create an Initiator cookie.
* Length SHOULD be a multiple of sizeof(u_int32_t).
*/
-void
-get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr)
+void get_cookie(bool initiator, u_int8_t *cookie, int length, ip_address *addr)
{
- u_char buffer[SHA1_DIGEST_SIZE];
- SHA1_CTX ctx;
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ u_char buffer[HASH_SIZE_SHA1];
+
+ do {
+ if (initiator)
+ {
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ rng->get_bytes(rng, length, cookie);
+ rng->destroy(rng);
+ }
+ else /* Responder cookie */
+ {
+ chunk_t addr_chunk, secret_chunk, counter_chunk;
+ size_t addr_len;
+ static u_int32_t counter = 0;
+ unsigned char addr_buf[
+ sizeof(union {struct in_addr A; struct in6_addr B;})];
- do {
- if (initiator)
- {
- get_rnd_bytes(cookie, length);
- }
- else /* Responder cookie */
- {
- /* This looks as good as any way */
- size_t addr_length;
- static u_int32_t counter = 0;
- unsigned char addr_buff[
- sizeof(union {struct in_addr A; struct in6_addr B;})];
+ addr_len = addrbytesof(addr, addr_buf, sizeof(addr_buf));
+ addr_chunk = chunk_create(addr_buf, addr_len);
+ secret_chunk = chunk_create(secret_of_the_day, HASH_SIZE_SHA1);
+ counter++;
+ counter_chunk = chunk_create((void *) &counter, sizeof(counter));
+ hasher->get_hash(hasher, addr_chunk, NULL);
+ hasher->get_hash(hasher, secret_chunk, NULL);
+ hasher->get_hash(hasher, counter_chunk, buffer);
+ memcpy(cookie, buffer, length);
+ }
+ } while (is_zero_cookie(cookie)); /* probably never loops */
- addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff));
- SHA1Init(&ctx);
- SHA1Update(&ctx, addr_buff, addr_length);
- SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day));
- counter++;
- SHA1Update(&ctx, (const void *) &counter, sizeof(counter));
- SHA1Final(buffer, &ctx);
- memcpy(cookie, buffer, length);
- }
- } while (is_zero_cookie(cookie)); /* probably never loops */
+ hasher->destroy(hasher);
}
diff --git a/src/pluto/cookie.h b/src/pluto/cookie.h
index b52bb2299..809d66491 100644
--- a/src/pluto/cookie.h
+++ b/src/pluto/cookie.h
@@ -10,15 +10,13 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: cookie.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include <freeswan.h>
-extern const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
+extern const u_char zero_cookie[COOKIE_SIZE]; /* guaranteed 0 */
-extern void get_cookie(bool initiator, u_int8_t *cookie, int length
- , const ip_address *addr);
+extern void get_cookie(bool initiator, u_int8_t *cookie, int length,
+ ip_address *addr);
#define is_zero_cookie(cookie) all_zero((cookie), COOKIE_SIZE)
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index c891d19e6..c800f2acc 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -1,5 +1,7 @@
/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2000-2009 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
@@ -10,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: crl.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <stdlib.h>
@@ -23,13 +23,15 @@
#include <sys/types.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+#include <crypto/hashers/hasher.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "asn1.h"
-#include <asn1/oid.h>
#include "x509.h"
#include "crl.h"
#include "ca.h"
@@ -37,482 +39,482 @@
#include "keys.h"
#include "whack.h"
#include "fetch.h"
-#include "sha1.h"
+
/* chained lists of X.509 crls */
static x509crl_t *x509crls = NULL;
-/* ASN.1 definition of an X.509 certificate list */
-
+/**
+ * ASN.1 definition of an X.509 certificate revocation list
+ */
static const asn1Object_t crlObjects[] = {
- { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
- { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
- { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 8 */
- { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
- { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
- { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
- { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 12 */
- { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
- { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 15 */
- { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
- { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
- { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST 0
+ { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_OPT |
+ ASN1_BODY }, /* 2 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
+ { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
+ { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 8 */
+ { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
+ { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
+ { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
+ { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 12 */
+ { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
+ { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
+ { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 15 */
+ { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
+ { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
+ { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ ASN1_BODY }, /* 23 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 28 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+
+#define CRL_OBJ_CERTIFICATE_LIST 0
#define CRL_OBJ_TBS_CERT_LIST 1
-#define CRL_OBJ_VERSION 2
-#define CRL_OBJ_SIG_ALG 4
-#define CRL_OBJ_ISSUER 5
-#define CRL_OBJ_THIS_UPDATE 6
-#define CRL_OBJ_NEXT_UPDATE 7
+#define CRL_OBJ_VERSION 2
+#define CRL_OBJ_SIG_ALG 4
+#define CRL_OBJ_ISSUER 5
+#define CRL_OBJ_THIS_UPDATE 6
+#define CRL_OBJ_NEXT_UPDATE 7
#define CRL_OBJ_USER_CERTIFICATE 10
#define CRL_OBJ_REVOCATION_DATE 11
#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
-#define CRL_OBJ_EXTN_ID 22
-#define CRL_OBJ_CRITICAL 23
-#define CRL_OBJ_EXTN_VALUE 24
-#define CRL_OBJ_ALGORITHM 27
-#define CRL_OBJ_SIGNATURE 28
-#define CRL_OBJ_ROOF 29
-
+#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
+#define CRL_OBJ_EXTN_ID 22
+#define CRL_OBJ_CRITICAL 23
+#define CRL_OBJ_EXTN_VALUE 24
+#define CRL_OBJ_ALGORITHM 27
+#define CRL_OBJ_SIGNATURE 28
const x509crl_t empty_x509crl = {
- NULL , /* *next */
- UNDEFINED_TIME, /* installed */
- NULL , /* distributionPoints */
- { NULL, 0 } , /* certificateList */
- { NULL, 0 } , /* tbsCertList */
- 1 , /* version */
- OID_UNKNOWN , /* sigAlg */
- { NULL, 0 } , /* issuer */
- UNDEFINED_TIME, /* thisUpdate */
- UNDEFINED_TIME, /* nextUpdate */
- NULL , /* revokedCertificates */
- /* crlExtensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKeySerialNumber */
- { NULL, 0 } , /* crlNumber */
- OID_UNKNOWN , /* algorithm */
- { NULL, 0 } /* signature */
+ NULL , /* *next */
+ UNDEFINED_TIME, /* installed */
+ NULL , /* distributionPoints */
+ { NULL, 0 } , /* certificateList */
+ { NULL, 0 } , /* tbsCertList */
+ 1 , /* version */
+ OID_UNKNOWN , /* sigAlg */
+ { NULL, 0 } , /* issuer */
+ UNDEFINED_TIME, /* thisUpdate */
+ UNDEFINED_TIME, /* nextUpdate */
+ NULL , /* revokedCertificates */
+ /* crlExtensions */
+ /* extension */
+ /* extnID */
+ /* critical */
+ /* extnValue */
+ { NULL, 0 } , /* authKeyID */
+ { NULL, 0 } , /* authKeySerialNumber */
+ { NULL, 0 } , /* crlNumber */
+ OID_UNKNOWN , /* algorithm */
+ { NULL, 0 } /* signature */
};
-/*
- * get the X.509 CRL with a given issuer
+/**
+ * Get the X.509 CRL with a given issuer
*/
-static x509crl_t*
-get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
+static x509crl_t* get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
{
- x509crl_t *crl = x509crls;
- x509crl_t *prev_crl = NULL;
-
- while (crl != NULL)
- {
- if ((keyid.ptr != NULL && crl->authKeyID.ptr != NULL)
- ? same_keyid(keyid, crl->authKeyID)
- : (same_dn(crl->issuer, issuer) && same_serial(serial, crl->authKeySerialNumber)))
+ x509crl_t *crl = x509crls;
+ x509crl_t *prev_crl = NULL;
+
+ while (crl != NULL)
{
- if (crl != x509crls)
- {
- /* bring the CRL up front */
- prev_crl->next = crl->next;
- crl->next = x509crls;
- x509crls = crl;
- }
- return crl;
+ if ((keyid.ptr != NULL && crl->authKeyID.ptr != NULL)
+ ? same_keyid(keyid, crl->authKeyID)
+ : (same_dn(crl->issuer, issuer) && same_serial(serial, crl->authKeySerialNumber)))
+ {
+ if (crl != x509crls)
+ {
+ /* bring the CRL up front */
+ prev_crl->next = crl->next;
+ crl->next = x509crls;
+ x509crls = crl;
+ }
+ return crl;
+ }
+ prev_crl = crl;
+ crl = crl->next;
}
- prev_crl = crl;
- crl = crl->next;
- }
- return NULL;
+ return NULL;
}
-/*
- * free the dynamic memory used to store revoked certificates
+/**
+ * Free the dynamic memory used to store revoked certificates
*/
-static void
-free_revoked_certs(revokedCert_t* revokedCerts)
+static void free_revoked_certs(revokedCert_t* revokedCerts)
{
- while (revokedCerts != NULL)
- {
- revokedCert_t * revokedCert = revokedCerts;
- revokedCerts = revokedCert->next;
- pfree(revokedCert);
- }
+ while (revokedCerts != NULL)
+ {
+ revokedCert_t * revokedCert = revokedCerts;
+ revokedCerts = revokedCert->next;
+ free(revokedCert);
+ }
}
-/*
- * free the dynamic memory used to store CRLs
+/**
+ * Free the dynamic memory used to store CRLs
*/
-void
-free_crl(x509crl_t *crl)
+void free_crl(x509crl_t *crl)
{
- free_revoked_certs(crl->revokedCertificates);
- free_generalNames(crl->distributionPoints, TRUE);
- pfree(crl->certificateList.ptr);
- pfree(crl);
+ free_revoked_certs(crl->revokedCertificates);
+ free_generalNames(crl->distributionPoints, TRUE);
+ free(crl->certificateList.ptr);
+ free(crl);
}
-static void
-free_first_crl(void)
+static void free_first_crl(void)
{
- x509crl_t *crl = x509crls;
+ x509crl_t *crl = x509crls;
- x509crls = crl->next;
- free_crl(crl);
+ x509crls = crl->next;
+ free_crl(crl);
}
-void
-free_crls(void)
+void free_crls(void)
{
- lock_crl_list("free_crls");
+ lock_crl_list("free_crls");
- while (x509crls != NULL)
- free_first_crl();
+ while (x509crls != NULL)
+ free_first_crl();
- unlock_crl_list("free_crls");
+ unlock_crl_list("free_crls");
}
-/*
+/**
* Insert X.509 CRL into chained list
*/
-bool
-insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
+bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
{
- x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");
-
- *crl = empty_x509crl;
-
- if (parse_x509crl(blob, 0, crl))
- {
- x509cert_t *issuer_cert;
- x509crl_t *oldcrl;
- bool valid_sig;
- generalName_t *gn;
-
- /* add distribution point */
- gn = alloc_thing(generalName_t, "generalName");
- gn->kind = GN_URI;
- gn->name = crl_uri;
- gn->next = crl->distributionPoints;
- crl->distributionPoints = gn;
-
- lock_authcert_list("insert_crl");
- /* get the issuer cacert */
- issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber,
- crl->authKeyID, AUTH_CA);
- if (issuer_cert == NULL)
- {
- plog("crl issuer cacert not found");
- free_crl(crl);
- unlock_authcert_list("insert_crl");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl issuer cacert found")
- )
-
- /* check the issuer's signature of the crl */
- valid_sig = check_signature(crl->tbsCertList, crl->signature
- , crl->algorithm, crl->algorithm, issuer_cert);
- unlock_authcert_list("insert_crl");
+ x509crl_t *crl = malloc_thing(x509crl_t);
- if (!valid_sig)
- {
- free_crl(crl);
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
-
- lock_crl_list("insert_crl");
- oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber
- , crl->authKeyID);
+ *crl = empty_x509crl;
- if (oldcrl != NULL)
+ if (parse_x509crl(blob, 0, crl))
{
- if (crl->thisUpdate > oldcrl->thisUpdate)
- {
- /* keep any known CRL distribution points */
- add_distribution_points(oldcrl->distributionPoints
- , &crl->distributionPoints);
-
- /* now delete the old CRL */
- free_first_crl();
+ x509cert_t *issuer_cert;
+ x509crl_t *oldcrl;
+ bool valid_sig;
+ generalName_t *gn;
+
+ /* add distribution point */
+ gn = malloc_thing(generalName_t);
+ gn->kind = GN_URI;
+ gn->name = crl_uri;
+ gn->next = crl->distributionPoints;
+ crl->distributionPoints = gn;
+
+ lock_authcert_list("insert_crl");
+ /* get the issuer cacert */
+ issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber,
+ crl->authKeyID, AUTH_CA);
+ if (issuer_cert == NULL)
+ {
+ plog("crl issuer cacert not found");
+ free_crl(crl);
+ unlock_authcert_list("insert_crl");
+ return FALSE;
+ }
DBG(DBG_CONTROL,
- DBG_log("thisUpdate is newer - existing crl deleted")
+ DBG_log("crl issuer cacert found")
)
- }
- else
- {
- unlock_crl_list("insert_crls");
+
+ /* check the issuer's signature of the crl */
+ valid_sig = x509_check_signature(crl->tbsCertList, crl->signature,
+ crl->algorithm, issuer_cert);
+ unlock_authcert_list("insert_crl");
+
+ if (!valid_sig)
+ {
+ free_crl(crl);
+ return FALSE;
+ }
DBG(DBG_CONTROL,
- DBG_log("thisUpdate is not newer - existing crl not replaced");
+ DBG_log("crl signature is valid")
)
- free_crl(crl);
- return oldcrl->nextUpdate - time(NULL) > 2*crl_check_interval;
- }
- }
- /* insert new CRL */
- crl->next = x509crls;
- x509crls = crl;
+ lock_crl_list("insert_crl");
+ oldcrl = get_x509crl(crl->issuer, crl->authKeySerialNumber
+ , crl->authKeyID);
- unlock_crl_list("insert_crl");
+ if (oldcrl != NULL)
+ {
+ if (crl->thisUpdate > oldcrl->thisUpdate)
+ {
+ /* keep any known CRL distribution points */
+ add_distribution_points(oldcrl->distributionPoints
+ , &crl->distributionPoints);
+
+ /* now delete the old CRL */
+ free_first_crl();
+ DBG(DBG_CONTROL,
+ DBG_log("thisUpdate is newer - existing crl deleted")
+ )
+ }
+ else
+ {
+ unlock_crl_list("insert_crls");
+ DBG(DBG_CONTROL,
+ DBG_log("thisUpdate is not newer - existing crl not replaced");
+ )
+ free_crl(crl);
+ return oldcrl->nextUpdate - time(NULL) > 2*crl_check_interval;
+ }
+ }
- /* If crl caching is enabled then the crl is saved locally.
- * Only http or ldap URIs are cached but not local file URIs.
- * The issuer's subjectKeyID is used as a unique filename
- */
- if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0)
+ /* insert new CRL */
+ crl->next = x509crls;
+ x509crls = crl;
+
+ unlock_crl_list("insert_crl");
+
+ /* If crl caching is enabled then the crl is saved locally.
+ * Only http or ldap URIs are cached but not local file URIs.
+ * The issuer's subjectKeyID is used as a unique filename
+ */
+ if (cache_crl && strncasecmp(crl_uri.ptr, "file", 4) != 0)
+ {
+ char path[BUF_LEN], buf[BUF_LEN];
+ char digest_buf[HASH_SIZE_SHA1];
+ chunk_t subjectKeyID = chunk_from_buf(digest_buf);
+ bool has_keyID;
+
+ if (issuer_cert->subjectKeyID.ptr == NULL)
+ {
+ has_keyID = compute_subjectKeyID(issuer_cert, subjectKeyID);
+ }
+ else
+ {
+ subjectKeyID = issuer_cert->subjectKeyID;
+ has_keyID = TRUE;
+ }
+ if (has_keyID)
+ {
+ datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
+ snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
+ chunk_write(crl->certificateList, path, "crl", 0022, TRUE);
+ }
+ }
+
+ /* is the fetched crl valid? */
+ return crl->nextUpdate - time(NULL) > 2*crl_check_interval;
+ }
+ else
{
- char path[BUF_LEN];
- char buf[BUF_LEN];
- char digest_buf[SHA1_DIGEST_SIZE];
- chunk_t subjectKeyID = { digest_buf, SHA1_DIGEST_SIZE };
-
- if (issuer_cert->subjectKeyID.ptr == NULL)
- compute_subjectKeyID(issuer_cert, subjectKeyID);
- else
- subjectKeyID = issuer_cert->subjectKeyID;
-
- datatot(subjectKeyID.ptr, subjectKeyID.len, 16, buf, BUF_LEN);
- snprintf(path, BUF_LEN, "%s/%s.crl", CRL_PATH, buf);
- write_chunk(path, "crl", crl->certificateList, 0022, TRUE);
+ plog(" error in X.509 crl");
+ free_crl(crl);
+ return FALSE;
}
-
- /* is the fetched crl valid? */
- return crl->nextUpdate - time(NULL) > 2*crl_check_interval;
- }
- else
- {
- plog(" error in X.509 crl");
- free_crl(crl);
- return FALSE;
- }
}
-/*
+/**
* Loads CRLs
*/
-void
-load_crls(void)
+void load_crls(void)
{
- struct dirent **filelist;
- u_char buf[BUF_LEN];
- u_char *save_dir;
- int n;
-
- /* change directory to specified path */
- save_dir = getcwd(buf, BUF_LEN);
- if (chdir(CRL_PATH))
- {
- plog("Could not change to directory '%s'", CRL_PATH);
- }
- else
- {
- plog("Changing to directory '%s'", CRL_PATH);
- n = scandir(CRL_PATH, &filelist, file_select, alphasort);
-
- if (n < 0)
- plog(" scandir() error");
+ struct dirent **filelist;
+ u_char buf[BUF_LEN];
+ u_char *save_dir;
+ int n;
+
+ /* change directory to specified path */
+ save_dir = getcwd(buf, BUF_LEN);
+ if (chdir(CRL_PATH))
+ {
+ plog("Could not change to directory '%s'", CRL_PATH);
+ }
else
{
- while (n--)
- {
- bool pgp = FALSE;
- chunk_t blob = empty_chunk;
- char *filename = filelist[n]->d_name;
+ plog("Changing to directory '%s'", CRL_PATH);
+ n = scandir(CRL_PATH, &filelist, file_select, alphasort);
- if (load_coded_file(filename, NULL, "crl", &blob, &pgp))
+ if (n < 0)
+ plog(" scandir() error");
+ else
{
- chunk_t crl_uri;
-
- crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
- crl_uri.ptr = alloc_bytes(crl_uri.len + 1, "crl uri");
-
- /* build CRL file URI */
- snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s"
- , CRL_PATH, filename);
-
- insert_crl(blob, crl_uri, FALSE);
+ while (n--)
+ {
+ bool pgp = FALSE;
+ chunk_t blob = chunk_empty;
+ char *filename = filelist[n]->d_name;
+
+ if (load_coded_file(filename, NULL, "crl", &blob, &pgp))
+ {
+ chunk_t crl_uri;
+
+ crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
+ crl_uri.ptr = malloc(crl_uri.len + 1);
+
+ /* build CRL file URI */
+ snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s"
+ , CRL_PATH, filename);
+
+ insert_crl(blob, crl_uri, FALSE);
+ }
+ free(filelist[n]);
+ }
+ free(filelist);
}
- free(filelist[n]);
- }
- free(filelist);
}
- }
- /* restore directory path */
- ignore_result(chdir(save_dir));
+ /* restore directory path */
+ ignore_result(chdir(save_dir));
}
-/*
+/**
* Parses a CRL revocation reason code
*/
-static crl_reason_t
-parse_crl_reasonCode(chunk_t object)
+static crl_reason_t parse_crl_reasonCode(chunk_t object)
{
- crl_reason_t reason = REASON_UNSPECIFIED;
-
- if (*object.ptr == ASN1_ENUMERATED
- && asn1_length(&object) == 1)
- {
- reason = *object.ptr;
- }
-
- DBG(DBG_PARSING,
- DBG_log(" '%s'", enum_name(&crl_reason_names, reason))
- )
- return reason;
+ crl_reason_t reason = REASON_UNSPECIFIED;
+
+ if (*object.ptr == ASN1_ENUMERATED
+ && asn1_length(&object) == 1)
+ {
+ reason = *object.ptr;
+ }
+
+ DBG(DBG_PARSING,
+ DBG_log(" '%N'", crl_reason_names, reason)
+ )
+ return reason;
}
/*
* Parses an X.509 CRL
*/
-bool
-parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
+bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
- chunk_t extnID;
- chunk_t userCertificate = empty_chunk;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < CRL_OBJ_ROOF)
- {
- if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID) {
- case CRL_OBJ_CERTIFICATE_LIST:
- crl->certificateList = object;
- break;
- case CRL_OBJ_TBS_CERT_LIST:
- crl->tbsCertList = object;
- break;
- case CRL_OBJ_VERSION:
- crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", crl->version);
- )
- break;
- case CRL_OBJ_SIG_ALG:
- crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_ISSUER:
- crl->issuer = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case CRL_OBJ_THIS_UPDATE:
- crl->thisUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_NEXT_UPDATE:
- crl->nextUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_USER_CERTIFICATE:
- userCertificate = object;
- break;
- case CRL_OBJ_REVOCATION_DATE:
- {
- /* put all the serial numbers and the revocation date in a chained list
- with revocedCertificates pointing to the first revoked certificate */
-
- revokedCert_t *revokedCert = alloc_thing(revokedCert_t, "revokedCert");
- revokedCert->userCertificate = userCertificate;
- revokedCert->revocationDate = parse_time(object, level);
- revokedCert->revocationReason = REASON_UNSPECIFIED;
- revokedCert->next = crl->revokedCertificates;
- crl->revokedCertificates = revokedCert;
- }
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_ID:
- case CRL_OBJ_EXTN_ID:
- extnID = object;
- break;
- case CRL_OBJ_CRL_ENTRY_CRITICAL:
- case CRL_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
- case CRL_OBJ_EXTN_VALUE:
- {
- u_int extn_oid = known_oid(extnID);
-
- if (extn_oid == OID_CRL_REASON_CODE)
- {
- crl->revokedCertificates->revocationReason =
- parse_crl_reasonCode(object);
- }
- else if (extn_oid == OID_AUTHORITY_KEY_ID)
- {
- parse_authorityKeyIdentifier(object, level
- , &crl->authKeyID, &crl->authKeySerialNumber);
- }
- else if (extn_oid == OID_CRL_NUMBER)
- {
- if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
- return FALSE;
- crl->crlNumber = object;
+ u_char buf[BUF_LEN];
+ asn1_parser_t *parser;
+ chunk_t extnID;
+ chunk_t userCertificate = chunk_empty;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(crlObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser)+1;
+
+ switch (objectID) {
+ case CRL_OBJ_CERTIFICATE_LIST:
+ crl->certificateList = object;
+ break;
+ case CRL_OBJ_TBS_CERT_LIST:
+ crl->tbsCertList = object;
+ break;
+ case CRL_OBJ_VERSION:
+ crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG(DBG_PARSING,
+ DBG_log(" v%d", crl->version);
+ )
+ break;
+ case CRL_OBJ_SIG_ALG:
+ crl->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case CRL_OBJ_ISSUER:
+ crl->issuer = object;
+ DBG(DBG_PARSING,
+ dntoa(buf, BUF_LEN, object);
+ DBG_log(" '%s'",buf)
+ )
+ break;
+ case CRL_OBJ_THIS_UPDATE:
+ crl->thisUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_NEXT_UPDATE:
+ crl->nextUpdate = asn1_parse_time(object, level);
+ break;
+ case CRL_OBJ_USER_CERTIFICATE:
+ userCertificate = object;
+ break;
+ case CRL_OBJ_REVOCATION_DATE:
+ {
+ /* put all the serial numbers and the revocation date in a chained list
+ with revocedCertificates pointing to the first revoked certificate */
+
+ revokedCert_t *revokedCert = malloc_thing(revokedCert_t);
+ revokedCert->userCertificate = userCertificate;
+ revokedCert->revocationDate = asn1_parse_time(object, level);
+ revokedCert->revocationReason = REASON_UNSPECIFIED;
+ revokedCert->next = crl->revokedCertificates;
+ crl->revokedCertificates = revokedCert;
+ }
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_ID:
+ case CRL_OBJ_EXTN_ID:
+ extnID = object;
+ break;
+ case CRL_OBJ_CRL_ENTRY_CRITICAL:
+ case CRL_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(critical)?"TRUE":"FALSE");
+ )
+ break;
+ case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
+ case CRL_OBJ_EXTN_VALUE:
+ {
+ u_int extn_oid = asn1_known_oid(extnID);
+
+ if (extn_oid == OID_CRL_REASON_CODE)
+ {
+ crl->revokedCertificates->revocationReason =
+ parse_crl_reasonCode(object);
+ }
+ else if (extn_oid == OID_AUTHORITY_KEY_ID)
+ {
+ parse_authorityKeyIdentifier(object, level
+ , &crl->authKeyID, &crl->authKeySerialNumber);
+ }
+ else if (extn_oid == OID_CRL_NUMBER)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "crlNumber"))
+ {
+ goto end;
+ }
+ crl->crlNumber = object;
+ }
+ }
+ break;
+ case CRL_OBJ_ALGORITHM:
+ crl->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case CRL_OBJ_SIGNATURE:
+ crl->signature = object;
+ break;
+ default:
+ break;
}
- }
- break;
- case CRL_OBJ_ALGORITHM:
- crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_SIGNATURE:
- crl->signature = object;
- break;
- default:
- break;
}
- objectID++;
- }
- time(&crl->installed);
- return TRUE;
+ success = parser->success(parser);
+ time(&crl->installed);
+
+end:
+ parser->destroy(parser);
+ return success;
}
/* Checks if the current certificate is revoked. It goes through the
@@ -523,28 +525,28 @@ static cert_status_t
check_revocation(const x509crl_t *crl, chunk_t serial
, time_t *revocationDate, crl_reason_t * revocationReason)
{
- revokedCert_t *revokedCert = crl->revokedCertificates;
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
-
- DBG(DBG_CONTROL,
- DBG_dump_chunk("serial number:", serial)
- )
-
- while(revokedCert != NULL)
- {
- /* compare serial numbers */
- if (revokedCert->userCertificate.len == serial.len &&
- memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0)
+ revokedCert_t *revokedCert = crl->revokedCertificates;
+
+ *revocationDate = UNDEFINED_TIME;
+ *revocationReason = REASON_UNSPECIFIED;
+
+ DBG(DBG_CONTROL,
+ DBG_dump_chunk("serial number:", serial)
+ )
+
+ while(revokedCert != NULL)
{
- *revocationDate = revokedCert->revocationDate;
- *revocationReason = revokedCert->revocationReason;
- return CERT_REVOKED;
+ /* compare serial numbers */
+ if (revokedCert->userCertificate.len == serial.len &&
+ memeq(revokedCert->userCertificate.ptr, serial.ptr, serial.len))
+ {
+ *revocationDate = revokedCert->revocationDate;
+ *revocationReason = revokedCert->revocationReason;
+ return CERT_REVOKED;
+ }
+ revokedCert = revokedCert->next;
}
- revokedCert = revokedCert->next;
- }
- return CERT_GOOD;
+ return CERT_GOOD;
}
/*
@@ -553,37 +555,37 @@ check_revocation(const x509crl_t *crl, chunk_t serial
void
check_crls(void)
{
- x509crl_t *crl;
+ x509crl_t *crl;
- lock_crl_list("check_crls");
- crl = x509crls;
-
- while (crl != NULL)
- {
- time_t time_left = crl->nextUpdate - time(NULL);
- u_char buf[BUF_LEN];
+ lock_crl_list("check_crls");
+ crl = x509crls;
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, crl->issuer);
- DBG_log("issuer: '%s'",buf);
- if (crl->authKeyID.ptr != NULL)
- {
- datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- DBG_log("%ld seconds left", time_left)
- )
- if (time_left < 2*crl_check_interval)
+ while (crl != NULL)
{
- fetch_req_t *req = build_crl_fetch_request(crl->issuer
- , crl->authKeySerialNumber
- , crl->authKeyID, crl->distributionPoints);
- add_crl_fetch_request(req);
+ time_t time_left = crl->nextUpdate - time(NULL);
+ u_char buf[BUF_LEN];
+
+ DBG(DBG_CONTROL,
+ dntoa(buf, BUF_LEN, crl->issuer);
+ DBG_log("issuer: '%s'",buf);
+ if (crl->authKeyID.ptr != NULL)
+ {
+ datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
+ DBG_log("%ld seconds left", time_left)
+ )
+ if (time_left < 2*crl_check_interval)
+ {
+ fetch_req_t *req = build_crl_fetch_request(crl->issuer
+ , crl->authKeySerialNumber
+ , crl->authKeyID, crl->distributionPoints);
+ add_crl_fetch_request(req);
+ }
+ crl = crl->next;
}
- crl = crl->next;
- }
- unlock_crl_list("check_crls");
+ unlock_crl_list("check_crls");
}
/*
@@ -593,118 +595,117 @@ cert_status_t
verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
, crl_reason_t *revocationReason)
{
- x509crl_t *crl;
-
- ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID);
+ x509crl_t *crl;
- generalName_t *crluri = (ca == NULL)? NULL : ca->crluri;
+ ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID);
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
+ generalName_t *crluri = (ca == NULL)? NULL : ca->crluri;
- lock_crl_list("verify_by_crl");
- crl = get_x509crl(cert->issuer, cert->authKeySerialNumber, cert->authKeyID);
+ *revocationDate = UNDEFINED_TIME;
+ *revocationReason = REASON_UNSPECIFIED;
- if (crl == NULL)
- {
- unlock_crl_list("verify_by_crl");
- plog("crl not found");
+ lock_crl_list("verify_by_crl");
+ crl = get_x509crl(cert->issuer, cert->authKeySerialNumber, cert->authKeyID);
- if (cert->crlDistributionPoints != NULL)
+ if (crl == NULL)
{
- fetch_req_t *req = build_crl_fetch_request(cert->issuer
- , cert->authKeySerialNumber
- , cert->authKeyID, cert->crlDistributionPoints);
- add_crl_fetch_request(req);
- }
+ unlock_crl_list("verify_by_crl");
+ plog("crl not found");
- if (crluri != NULL)
- {
- fetch_req_t *req = build_crl_fetch_request(cert->issuer
- , cert->authKeySerialNumber
- , cert->authKeyID, crluri);
- add_crl_fetch_request(req);
- }
+ if (cert->crlDistributionPoints != NULL)
+ {
+ fetch_req_t *req = build_crl_fetch_request(cert->issuer
+ , cert->authKeySerialNumber
+ , cert->authKeyID, cert->crlDistributionPoints);
+ add_crl_fetch_request(req);
+ }
- if (cert->crlDistributionPoints != 0 || crluri != NULL)
- {
- wake_fetch_thread("verify_by_crl");
- return CERT_UNKNOWN;
+ if (crluri != NULL)
+ {
+ fetch_req_t *req = build_crl_fetch_request(cert->issuer
+ , cert->authKeySerialNumber
+ , cert->authKeyID, crluri);
+ add_crl_fetch_request(req);
+ }
+
+ if (cert->crlDistributionPoints != 0 || crluri != NULL)
+ {
+ wake_fetch_thread("verify_by_crl");
+ return CERT_UNKNOWN;
+ }
+ else
+ return CERT_UNDEFINED;
}
else
- return CERT_UNDEFINED;
- }
- else
- {
- x509cert_t *issuer_cert;
- bool valid;
-
- DBG(DBG_CONTROL,
- DBG_log("crl found")
- )
-
- add_distribution_points(cert->crlDistributionPoints
- , &crl->distributionPoints);
-
- add_distribution_points(crluri
- , &crl->distributionPoints);
-
- lock_authcert_list("verify_by_crl");
-
- issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber
- , crl->authKeyID, AUTH_CA);
- valid = check_signature(crl->tbsCertList, crl->signature
- , crl->algorithm, crl->algorithm, issuer_cert);
-
- unlock_authcert_list("verify_by_crl");
-
- if (valid)
{
- cert_status_t status;
+ x509cert_t *issuer_cert;
+ bool valid;
- DBG(DBG_CONTROL,
- DBG_log("crl signature is valid")
- )
- /* return the expiration date */
- *until = crl->nextUpdate;
+ DBG(DBG_CONTROL,
+ DBG_log("crl found")
+ )
- /* has the certificate been revoked? */
- status = check_revocation(crl, cert->serialNumber, revocationDate
- , revocationReason);
+ add_distribution_points(cert->crlDistributionPoints
+ , &crl->distributionPoints);
- if (*until < time(NULL))
- {
- fetch_req_t *req;
+ add_distribution_points(crluri
+ , &crl->distributionPoints);
- plog("crl update is overdue since %s"
- , timetoa(until, TRUE));
+ lock_authcert_list("verify_by_crl");
- /* try to fetch a crl update */
- req = build_crl_fetch_request(crl->issuer
- , crl->authKeySerialNumber
- , crl->authKeyID, crl->distributionPoints);
- unlock_crl_list("verify_by_crl");
+ issuer_cert = get_authcert(crl->issuer, crl->authKeySerialNumber
+ , crl->authKeyID, AUTH_CA);
+ valid = x509_check_signature(crl->tbsCertList, crl->signature,
+ crl->algorithm, issuer_cert);
+
+ unlock_authcert_list("verify_by_crl");
- add_crl_fetch_request(req);
- wake_fetch_thread("verify_by_crl");
- }
- else
- {
- unlock_crl_list("verify_by_crl");
- DBG(DBG_CONTROL,
- DBG_log("crl is valid")
- )
- }
- return status;
- }
- else
- {
- unlock_crl_list("verify_by_crl");
- plog("crl signature is invalid");
- return CERT_UNKNOWN;
+ if (valid)
+ {
+ cert_status_t status;
+
+ DBG(DBG_CONTROL,
+ DBG_log("crl signature is valid")
+ )
+ /* return the expiration date */
+ *until = crl->nextUpdate;
+
+ /* has the certificate been revoked? */
+ status = check_revocation(crl, cert->serialNumber, revocationDate
+ , revocationReason);
+
+ if (*until < time(NULL))
+ {
+ fetch_req_t *req;
+
+ plog("crl update is overdue since %T", until, TRUE);
+
+ /* try to fetch a crl update */
+ req = build_crl_fetch_request(crl->issuer
+ , crl->authKeySerialNumber
+ , crl->authKeyID, crl->distributionPoints);
+ unlock_crl_list("verify_by_crl");
+
+ add_crl_fetch_request(req);
+ wake_fetch_thread("verify_by_crl");
+ }
+ else
+ {
+ unlock_crl_list("verify_by_crl");
+ DBG(DBG_CONTROL,
+ DBG_log("crl is valid")
+ )
+ }
+ return status;
+ }
+ else
+ {
+ unlock_crl_list("verify_by_crl");
+ plog("crl signature is invalid");
+ return CERT_UNKNOWN;
+ }
}
- }
}
/*
@@ -713,63 +714,63 @@ verify_by_crl(const x509cert_t *cert, time_t *until, time_t *revocationDate
void
list_crls(bool utc, bool strict)
{
- x509crl_t *crl;
+ x509crl_t *crl;
- lock_crl_list("list_crls");
- crl = x509crls;
+ lock_crl_list("list_crls");
+ crl = x509crls;
- if (crl != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 CRLs:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (crl != NULL)
- {
- u_char buf[BUF_LEN];
- u_int revoked = 0;
- revokedCert_t *revokedCert = crl->revokedCertificates;
-
- /* count number of revoked certificates in CRL */
- while (revokedCert != NULL)
- {
- revoked++;
- revokedCert = revokedCert->next;
- }
-
- whack_log(RC_COMMENT, "%s, revoked certs: %d",
- timetoa(&crl->installed, utc), revoked);
- dntoa(buf, BUF_LEN, crl->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- if (crl->crlNumber.ptr != NULL)
+ if (crl != NULL)
{
- datatot(crl->crlNumber.ptr, crl->crlNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " crlnumber: %s", buf);
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of X.509 CRLs:");
+ whack_log(RC_COMMENT, " ");
}
- list_distribution_points(crl->distributionPoints);
-
- whack_log(RC_COMMENT, " updates: this %s",
- timetoa(&crl->thisUpdate, utc));
- whack_log(RC_COMMENT, " next %s %s",
- timetoa(&crl->nextUpdate, utc),
- check_expiry(crl->nextUpdate, CRL_WARNING_INTERVAL, strict));
- if (crl->authKeyID.ptr != NULL)
- {
- datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (crl->authKeySerialNumber.ptr != NULL)
+
+ while (crl != NULL)
{
- datatot(crl->authKeySerialNumber.ptr, crl->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
+ u_char buf[BUF_LEN];
+ u_int revoked = 0;
+ revokedCert_t *revokedCert = crl->revokedCertificates;
+
+ /* count number of revoked certificates in CRL */
+ while (revokedCert != NULL)
+ {
+ revoked++;
+ revokedCert = revokedCert->next;
+ }
+
+ whack_log(RC_COMMENT, "%T, revoked certs: %d",
+ &crl->installed, utc, revoked);
+ dntoa(buf, BUF_LEN, crl->issuer);
+ whack_log(RC_COMMENT, " issuer: '%s'", buf);
+ if (crl->crlNumber.ptr != NULL)
+ {
+ datatot(crl->crlNumber.ptr, crl->crlNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " crlnumber: %s", buf);
+ }
+ list_distribution_points(crl->distributionPoints);
+
+ whack_log(RC_COMMENT, " updates: this %T",
+ &crl->thisUpdate, utc);
+ whack_log(RC_COMMENT, " next %T %s",
+ &crl->nextUpdate, utc,
+ check_expiry(crl->nextUpdate, CRL_WARNING_INTERVAL, strict));
+ if (crl->authKeyID.ptr != NULL)
+ {
+ datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (crl->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(crl->authKeySerialNumber.ptr, crl->authKeySerialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
- crl = crl->next;
- }
- unlock_crl_list("list_crls");
+ crl = crl->next;
+ }
+ unlock_crl_list("list_crls");
}
diff --git a/src/pluto/crl.h b/src/pluto/crl.h
index b5051dcac..7c110ad5a 100644
--- a/src/pluto/crl.h
+++ b/src/pluto/crl.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: crl.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include "constants.h"
@@ -22,9 +20,9 @@ typedef struct revokedCert revokedCert_t;
struct revokedCert{
revokedCert_t *next;
- chunk_t userCertificate;
- time_t revocationDate;
- crl_reason_t revocationReason;
+ chunk_t userCertificate;
+ time_t revocationDate;
+ crl_reason_t revocationReason;
};
/* storage structure for an X.509 CRL */
@@ -33,28 +31,28 @@ typedef struct x509crl x509crl_t;
struct x509crl {
x509crl_t *next;
- time_t installed;
+ time_t installed;
generalName_t *distributionPoints;
chunk_t certificateList;
chunk_t tbsCertList;
u_int version;
- /* signature */
+ /* signature */
int sigAlg;
chunk_t issuer;
time_t thisUpdate;
time_t nextUpdate;
revokedCert_t *revokedCertificates;
- /* v2 extensions */
- /* crlExtensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- chunk_t crlNumber;
+ /* v2 extensions */
+ /* crlExtensions */
+ /* extension */
+ /* extnID */
+ /* critical */
+ /* extnValue */
+ chunk_t authKeyID;
+ chunk_t authKeySerialNumber;
+ chunk_t crlNumber;
- /* signatureAlgorithm */
+ /* signatureAlgorithm */
int algorithm;
chunk_t signature;
};
@@ -82,7 +80,7 @@ extern void load_crls(void);
extern void check_crls(void);
extern bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl);
extern cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until
- , time_t *revocationDate, crl_reason_t *revocationReason);
+ , time_t *revocationDate, crl_reason_t *revocationReason);
extern void list_crls(bool utc, bool strict);
extern void free_crls(void);
extern void free_crl(x509crl_t *crl);
diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c
index 207192e14..1adccc74e 100644
--- a/src/pluto/crypto.c
+++ b/src/pluto/crypto.c
@@ -1,6 +1,6 @@
/* crypto interfaces
- * Copyright (C) 1998-2001 D. Hugh Redelmeier
- * Copyright (C) 2007 Andreas Steffen
+ * Copyright (C) 1998-2001 D. Hugh Redelmeier
+ * Copyright (C) 2007-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,617 +11,582 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: crypto.c 3252 2007-10-06 21:24:50Z andreas $
*/
-#include <stdio.h>
-#include <string.h>
-#include <stddef.h>
-#include <sys/types.h>
-
#include <freeswan.h>
-#define HEADER_DES_LOCL_H /* stupid trick to force prototype decl in <des.h> */
-#include <libdes/des.h>
-
-#include <errno.h>
#include "constants.h"
#include "defs.h"
-#include "state.h"
+#include "crypto.h"
#include "log.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
-#include "alg_info.h"
-#include "ike_alg.h"
-
-
-/* moduli and generator. */
-
-static MP_INT
- modp1024_modulus,
- modp1536_modulus,
- modp2048_modulus,
- modp3072_modulus,
- modp4096_modulus,
- modp6144_modulus,
- modp8192_modulus;
-
-MP_INT groupgenerator; /* MODP group generator (2) */
-
-static void do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
-
-static struct encrypt_desc crypto_encryptor_3des =
-{
- algo_type: IKE_ALG_ENCRYPT,
- algo_id: OAKLEY_3DES_CBC,
- algo_next: NULL,
- enc_ctxsize: sizeof(des_key_schedule) * 3,
- enc_blocksize: DES_CBC_BLOCK_SIZE,
- keydeflen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- keyminlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- keymaxlen: DES_CBC_BLOCK_SIZE * 3 * BITS_PER_BYTE,
- do_crypt: do_3des,
-};
-
-/* MD5 hash test vectors
- * from RFC 1321 "MD5 Message-Digest Algorithm"
- * April 1992, R. Rivest, RSA Data Security
- */
-
-static const u_char md5_test0_msg[] = {
-
-};
-
-static const u_char md5_test0_msg_digest[] = {
- 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
- 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
-};
-
-static const u_char md5_test1_msg[] = {
- 0x61
-};
-
-static const u_char md5_test1_msg_digest[] = {
- 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
- 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61
-};
-
-static const u_char md5_test2_msg[] = {
- 0x61, 0x62, 0x63
-};
-
-static const u_char md5_test2_msg_digest[] = {
- 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
- 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72
-};
-
-static const u_char md5_test3_msg[] = {
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20,
- 0x64, 0x69, 0x67, 0x65, 0x73, 0x74
-};
-
-static const u_char md5_test3_msg_digest[] = {
- 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
- 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0
-};
-
-static const u_char md5_test4_msg[] = {
- 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
- 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- 0x79, 0x7a
-};
-static const u_char md5_test4_msg_digest[] = {
- 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
- 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b
-};
-
-static const u_char md5_test5_msg[] = {
- 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
- 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
- 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
- 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33,
- 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
-};
+static struct encrypt_desc encrypt_desc_3des =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_3DES_CBC,
+ algo_next: NULL,
-static const u_char md5_test5_msg_digest[] = {
- 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
- 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f
+ enc_blocksize: DES_BLOCK_SIZE,
+ keydeflen: DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
+ keyminlen: DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
+ keymaxlen: DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
};
-static const u_char md5_test6_msg[] = {
- 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
- 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
- 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32,
- 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30
-};
+#define AES_KEY_MIN_LEN 128
+#define AES_KEY_DEF_LEN 128
+#define AES_KEY_MAX_LEN 256
-static const u_char md5_test6_msg_digest[] = {
- 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
- 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a
-};
-
-static const hash_testvector_t md5_hash_testvectors[] = {
- { sizeof(md5_test0_msg), md5_test0_msg, md5_test0_msg_digest },
- { sizeof(md5_test1_msg), md5_test1_msg, md5_test1_msg_digest },
- { sizeof(md5_test2_msg), md5_test2_msg, md5_test2_msg_digest },
- { sizeof(md5_test3_msg), md5_test3_msg, md5_test3_msg_digest },
- { sizeof(md5_test4_msg), md5_test4_msg, md5_test4_msg_digest },
- { sizeof(md5_test5_msg), md5_test5_msg, md5_test5_msg_digest },
- { sizeof(md5_test6_msg), md5_test6_msg, md5_test6_msg_digest },
- { 0, NULL, NULL }
-};
-
-/* MD5 hmac test vectors
- * from RFC 2202 "Test Cases for HMAC-MD5 and HMAC-SHA-1"
- * September 1997, P. Cheng, IBM & R. Glenn, NIST
- */
-
-static const u_char md5_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
-};
-
-static const u_char md5_hmac1_msg[] = {
- 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
-};
-
-static const u_char md5_hmac1[] = {
- 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
- 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
-};
-
-static const u_char md5_hmac2_key[] = {
- 0x4a, 0x65, 0x66, 0x65
-};
-
-static const u_char md5_hmac2_msg[] = {
- 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20,
- 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20,
- 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68,
- 0x69, 0x6e, 0x67, 0x3f
-};
+static struct encrypt_desc encrypt_desc_aes =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_AES_CBC,
+ algo_next: NULL,
-static const u_char md5_hmac2[] = {
- 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
- 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38
+ enc_blocksize: AES_BLOCK_SIZE,
+ keyminlen: AES_KEY_MIN_LEN,
+ keydeflen: AES_KEY_DEF_LEN,
+ keymaxlen: AES_KEY_MAX_LEN,
};
-static const u_char md5_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
-};
+#define BLOWFISH_KEY_MIN_LEN 128
+#define BLOWFISH_KEY_MAX_LEN 448
-static const u_char md5_hmac3_msg[] = {
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
- 0xdd, 0xdd
-};
+static struct encrypt_desc encrypt_desc_blowfish =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_BLOWFISH_CBC,
+ algo_next: NULL,
-static const u_char md5_hmac3[] = {
- 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
- 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6
+ enc_blocksize: BLOWFISH_BLOCK_SIZE,
+ keyminlen: BLOWFISH_KEY_MIN_LEN,
+ keydeflen: BLOWFISH_KEY_MIN_LEN,
+ keymaxlen: BLOWFISH_KEY_MAX_LEN,
};
-static const u_char md5_hmac4_key[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
- 0x19
-};
+#define SERPENT_KEY_MIN_LEN 128
+#define SERPENT_KEY_DEF_LEN 128
+#define SERPENT_KEY_MAX_LEN 256
-static const u_char md5_hmac4_msg[] = {
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd
-};
-
-static const u_char md5_hmac4[] = {
- 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
- 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79
-};
+static struct encrypt_desc encrypt_desc_serpent =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_SERPENT_CBC,
+ algo_next: NULL,
-static const u_char md5_hmac6_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ enc_blocksize: SERPENT_BLOCK_SIZE,
+ keyminlen: SERPENT_KEY_MIN_LEN,
+ keydeflen: SERPENT_KEY_DEF_LEN,
+ keymaxlen: SERPENT_KEY_MAX_LEN,
};
-static const u_char md5_hmac6_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x2d, 0x20,
- 0x48, 0x61, 0x73, 0x68, 0x20, 0x4b, 0x65, 0x79,
- 0x20, 0x46, 0x69, 0x72, 0x73, 0x74
-};
+#define TWOFISH_KEY_MIN_LEN 128
+#define TWOFISH_KEY_DEF_LEN 128
+#define TWOFISH_KEY_MAX_LEN 256
-static const u_char md5_hmac6[] = {
- 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
- 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd
-};
+static struct encrypt_desc encrypt_desc_twofish =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_TWOFISH_CBC,
+ algo_next: NULL,
-static const u_char md5_hmac7_msg[] = {
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x69,
- 0x6e, 0x67, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65,
- 0x72, 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x42,
- 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x53, 0x69, 0x7a,
- 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x61, 0x6e,
- 0x64, 0x20, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x72,
- 0x20, 0x54, 0x68, 0x61, 0x6e, 0x20, 0x4f, 0x6e,
- 0x65, 0x20, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x2d,
- 0x53, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x61, 0x74,
- 0x61
+ enc_blocksize: TWOFISH_BLOCK_SIZE,
+ keydeflen: TWOFISH_KEY_MIN_LEN,
+ keyminlen: TWOFISH_KEY_DEF_LEN,
+ keymaxlen: TWOFISH_KEY_MAX_LEN,
};
-static const u_char md5_hmac7[] = {
- 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
- 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e
-};
+static struct encrypt_desc encrypt_desc_twofish_ssh =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_TWOFISH_CBC_SSH,
+ algo_next: NULL,
-static const hmac_testvector_t md5_hmac_testvectors[] = {
- { sizeof(md5_hmac1_key), md5_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, md5_hmac1 },
- { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, md5_hmac2 },
- { sizeof(md5_hmac3_key), md5_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, md5_hmac3 },
- { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, md5_hmac4 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, md5_hmac6 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, md5_hmac7 },
- { 0, NULL, 0, NULL, NULL }
+ enc_blocksize: TWOFISH_BLOCK_SIZE,
+ keydeflen: TWOFISH_KEY_MIN_LEN,
+ keyminlen: TWOFISH_KEY_DEF_LEN,
+ keymaxlen: TWOFISH_KEY_MAX_LEN,
};
-static struct hash_desc crypto_hasher_md5 =
-{
+static struct hash_desc hash_desc_md5 =
+{
algo_type: IKE_ALG_HASH,
algo_id: OAKLEY_MD5,
algo_next: NULL,
- hash_ctx_size: sizeof(MD5_CTX),
- hash_block_size: MD5_BLOCK_SIZE,
- hash_digest_size: MD5_DIGEST_SIZE,
- hash_testvectors: md5_hash_testvectors,
- hmac_testvectors: md5_hmac_testvectors,
- hash_init: (void (*)(void *)) MD5Init,
- hash_update: (void (*)(void *, const u_int8_t *, size_t)) MD5Update,
- hash_final: (void (*)(u_char *, void *)) MD5Final
+ hash_digest_size: HASH_SIZE_MD5,
};
-/* SHA-1 test vectors
- * from "The Secure Hash Algorithm Validation System (SHAVS)"
- * July 22, 2004, Lawrence E. Bassham III, NIST
- */
-
-static const u_char sha1_short2_msg[] = {
- 0x5e
+static struct hash_desc hash_desc_sha1 =
+{
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA,
+ algo_next: NULL,
+ hash_digest_size: HASH_SIZE_SHA1,
};
-static const u_char sha1_short2_msg_digest[] = {
- 0x5e, 0x6f, 0x80, 0xa3, 0x4a, 0x97, 0x98, 0xca,
- 0xfc, 0x6a, 0x5d, 0xb9, 0x6c, 0xc5, 0x7b, 0xa4,
- 0xc4, 0xdb, 0x59, 0xc2
+static struct hash_desc hash_desc_sha2_256 = {
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA2_256,
+ algo_next: NULL,
+ hash_digest_size: HASH_SIZE_SHA256,
};
-static const u_char sha1_short4_msg[] = {
- 0x9a, 0x7d, 0xfd, 0xf1, 0xec, 0xea, 0xd0, 0x6e,
- 0xd6, 0x46, 0xaa, 0x55, 0xfe, 0x75, 0x71, 0x46
+static struct hash_desc hash_desc_sha2_384 = {
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA2_384,
+ algo_next: NULL,
+ hash_digest_size: HASH_SIZE_SHA384,
};
-static const u_char sha1_short4_msg_digest[] = {
- 0x82, 0xab, 0xff, 0x66, 0x05, 0xdb, 0xe1, 0xc1,
- 0x7d, 0xef, 0x12, 0xa3, 0x94, 0xfa, 0x22, 0xa8,
- 0x2b, 0x54, 0x4a, 0x35
+static struct hash_desc hash_desc_sha2_512 = {
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA2_512,
+ algo_next: NULL,
+ hash_digest_size: HASH_SIZE_SHA512,
};
-static const u_char sha1_long2_msg[] = {
- 0xf7, 0x8f, 0x92, 0x14, 0x1b, 0xcd, 0x17, 0x0a,
- 0xe8, 0x9b, 0x4f, 0xba, 0x15, 0xa1, 0xd5, 0x9f,
- 0x3f, 0xd8, 0x4d, 0x22, 0x3c, 0x92, 0x51, 0xbd,
- 0xac, 0xbb, 0xae, 0x61, 0xd0, 0x5e, 0xd1, 0x15,
- 0xa0, 0x6a, 0x7c, 0xe1, 0x17, 0xb7, 0xbe, 0xea,
- 0xd2, 0x44, 0x21, 0xde, 0xd9, 0xc3, 0x25, 0x92,
- 0xbd, 0x57, 0xed, 0xea, 0xe3, 0x9c, 0x39, 0xfa,
- 0x1f, 0xe8, 0x94, 0x6a, 0x84, 0xd0, 0xcf, 0x1f,
- 0x7b, 0xee, 0xad, 0x17, 0x13, 0xe2, 0xe0, 0x95,
- 0x98, 0x97, 0x34, 0x7f, 0x67, 0xc8, 0x0b, 0x04,
- 0x00, 0xc2, 0x09, 0x81, 0x5d, 0x6b, 0x10, 0xa6,
- 0x83, 0x83, 0x6f, 0xd5, 0x56, 0x2a, 0x56, 0xca,
- 0xb1, 0xa2, 0x8e, 0x81, 0xb6, 0x57, 0x66, 0x54,
- 0x63, 0x1c, 0xf1, 0x65, 0x66, 0xb8, 0x6e, 0x3b,
- 0x33, 0xa1, 0x08, 0xb0, 0x53, 0x07, 0xc0, 0x0a,
- 0xff, 0x14, 0xa7, 0x68, 0xed, 0x73, 0x50, 0x60,
- 0x6a, 0x0f, 0x85, 0xe6, 0xa9, 0x1d, 0x39, 0x6f,
- 0x5b, 0x5c, 0xbe, 0x57, 0x7f, 0x9b, 0x38, 0x80,
- 0x7c, 0x7d, 0x52, 0x3d, 0x6d, 0x79, 0x2f, 0x6e,
- 0xbc, 0x24, 0xa4, 0xec, 0xf2, 0xb3, 0xa4, 0x27,
- 0xcd, 0xbb, 0xfb
+const struct dh_desc unset_group = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_NONE,
+ algo_next: NULL,
+ ke_size: 0
};
-static const u_char sha1_long2_msg_digest[] = {
- 0xcb, 0x00, 0x82, 0xc8, 0xf1, 0x97, 0xd2, 0x60,
- 0x99, 0x1b, 0xa6, 0xa4, 0x60, 0xe7, 0x6e, 0x20,
- 0x2b, 0xad, 0x27, 0xb3
+static struct dh_desc dh_desc_modp_1024 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_1024_BIT,
+ algo_next: NULL,
+ ke_size: 1024 / BITS_PER_BYTE
};
-static const hash_testvector_t sha1_hash_testvectors[] = {
- { sizeof(sha1_short2_msg), sha1_short2_msg, sha1_short2_msg_digest },
- { sizeof(sha1_short4_msg), sha1_short4_msg, sha1_short4_msg_digest },
- { sizeof(sha1_long2_msg), sha1_long2_msg, sha1_long2_msg_digest },
- { 0, NULL, NULL }
+static struct dh_desc dh_desc_modp_1536 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_1536_BIT,
+ algo_next: NULL,
+ ke_size: 1536 / BITS_PER_BYTE
};
-/* SHA-1 hmac test vectors
- * from RFC 2202 "Test Cases for HMAC-MD5 and HMAC-SHA-1"
- * September 1997, P. Cheng, IBM & R. Glenn, NIST
- */
-
-static const u_char sha1_hmac1_key[] = {
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b
+static struct dh_desc dh_desc_modp_2048 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_2048_BIT,
+ algo_next: NULL,
+ ke_size: 2048 / BITS_PER_BYTE
};
-static const u_char sha1_hmac1[] = {
- 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
- 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
- 0xf1, 0x46, 0xbe, 0x00
+static struct dh_desc dh_desc_modp_3072 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_3072_BIT,
+ algo_next: NULL,
+ ke_size: 3072 / BITS_PER_BYTE
};
-static const u_char sha1_hmac2[] = {
- 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2,
- 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c,
- 0x25, 0x9a, 0x7c, 0x79
+static struct dh_desc dh_desc_modp_4096 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_4096_BIT,
+ algo_next: NULL,
+ ke_size: 4096 / BITS_PER_BYTE
};
-static const u_char sha1_hmac3_key[] = {
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa
+static struct dh_desc dh_desc_modp_6144 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_6144_BIT,
+ algo_next: NULL,
+ ke_size: 6144 / BITS_PER_BYTE
};
-static const u_char sha1_hmac3[] = {
- 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd,
- 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f,
- 0x63, 0xf1, 0x75, 0xd3
+static struct dh_desc dh_desc_modp_8192 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: MODP_8192_BIT,
+ algo_next: NULL,
+ ke_size: 8192 / BITS_PER_BYTE
};
-static const u_char sha1_hmac4[] = {
- 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6,
- 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c,
- 0x2d, 0x72, 0x35, 0xda
+static struct dh_desc dh_desc_ecp_256 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: ECP_256_BIT,
+ algo_next: NULL,
+ ke_size: 2*256 / BITS_PER_BYTE
};
-static const u_char sha1_hmac6[] = {
- 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
- 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
- 0xed, 0x40, 0x21, 0x12
+static struct dh_desc dh_desc_ecp_384 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: ECP_384_BIT,
+ algo_next: NULL,
+ ke_size: 2*384 / BITS_PER_BYTE
};
-static const u_char sha1_hmac7[] = {
- 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78,
- 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08,
- 0xbb, 0xff, 0x1a, 0x91
+static struct dh_desc dh_desc_ecp_521 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: ECP_521_BIT,
+ algo_next: NULL,
+ ke_size: 2*528 / BITS_PER_BYTE
};
-static const hmac_testvector_t sha1_hmac_testvectors[] = {
- { sizeof(sha1_hmac1_key), sha1_hmac1_key, sizeof(md5_hmac1_msg), md5_hmac1_msg, sha1_hmac1 },
- { sizeof(md5_hmac2_key), md5_hmac2_key, sizeof(md5_hmac2_msg), md5_hmac2_msg, sha1_hmac2 },
- { sizeof(sha1_hmac3_key), sha1_hmac3_key, sizeof(md5_hmac3_msg), md5_hmac3_msg, sha1_hmac3 },
- { sizeof(md5_hmac4_key), md5_hmac4_key, sizeof(md5_hmac4_msg), md5_hmac4_msg, sha1_hmac4 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac6_msg), md5_hmac6_msg, sha1_hmac6 },
- { sizeof(md5_hmac6_key), md5_hmac6_key, sizeof(md5_hmac7_msg), md5_hmac7_msg, sha1_hmac7 },
- { 0, NULL, 0, NULL, NULL }
+static struct dh_desc dh_desc_ecp_192 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: ECP_192_BIT,
+ algo_next: NULL,
+ ke_size: 2*192 / BITS_PER_BYTE
};
-static struct hash_desc crypto_hasher_sha1 =
-{
- algo_type: IKE_ALG_HASH,
- algo_id: OAKLEY_SHA,
- algo_next: NULL,
- hash_ctx_size: sizeof(SHA1_CTX),
- hash_block_size: SHA1_BLOCK_SIZE,
- hash_digest_size: SHA1_DIGEST_SIZE,
- hash_testvectors: sha1_hash_testvectors,
- hmac_testvectors: sha1_hmac_testvectors,
- hash_init: (void (*)(void *)) SHA1Init,
- hash_update: (void (*)(void *, const u_int8_t *, size_t)) SHA1Update,
- hash_final: (void (*)(u_char *, void *)) SHA1Final
+static struct dh_desc dh_desc_ecp_224 = {
+ algo_type: IKE_ALG_DH_GROUP,
+ algo_id: ECP_224_BIT,
+ algo_next: NULL,
+ ke_size: 2*224 / BITS_PER_BYTE
};
-void
-init_crypto(void)
+void init_crypto(void)
{
- if (mpz_init_set_str(&groupgenerator, MODP_GENERATOR, 10) != 0
- || mpz_init_set_str(&modp1024_modulus, MODP1024_MODULUS, 16) != 0
- || mpz_init_set_str(&modp1536_modulus, MODP1536_MODULUS, 16) != 0
- || mpz_init_set_str(&modp2048_modulus, MODP2048_MODULUS, 16) != 0
- || mpz_init_set_str(&modp3072_modulus, MODP3072_MODULUS, 16) != 0
- || mpz_init_set_str(&modp4096_modulus, MODP4096_MODULUS, 16) != 0
- || mpz_init_set_str(&modp6144_modulus, MODP6144_MODULUS, 16) != 0
- || mpz_init_set_str(&modp8192_modulus, MODP8192_MODULUS, 16) != 0)
- exit_log("mpz_init_set_str() failed in init_crypto()");
-
- ike_alg_add((struct ike_alg *) &crypto_encryptor_3des);
- ike_alg_add((struct ike_alg *) &crypto_hasher_sha1);
- ike_alg_add((struct ike_alg *) &crypto_hasher_md5);
- ike_alg_init();
- ike_alg_test();
+ enumerator_t *enumerator;
+ encryption_algorithm_t encryption_alg;
+ hash_algorithm_t hash_alg;
+ diffie_hellman_group_t dh_group;
+ bool no_md5 = TRUE;
+ bool no_sha1 = TRUE;
+
+ enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &hash_alg))
+ {
+ const struct hash_desc *desc;
+
+ switch (hash_alg)
+ {
+ case HASH_SHA1:
+ desc = &hash_desc_sha1;
+ no_sha1 = FALSE;
+ break;
+ case HASH_SHA256:
+ desc = &hash_desc_sha2_256;
+ break;
+ case HASH_SHA384:
+ desc = &hash_desc_sha2_384;
+ break;
+ case HASH_SHA512:
+ desc = &hash_desc_sha2_512;
+ break;
+ case HASH_MD5:
+ desc = &hash_desc_md5;
+ no_md5 = FALSE;
+ break;
+ default:
+ continue;
+ }
+ ike_alg_add((struct ike_alg *)desc);
+ }
+ enumerator->destroy(enumerator);
+
+ if (no_sha1)
+ {
+ exit_log("pluto cannot run without a SHA-1 hasher");
+ }
+ if (no_md5)
+ {
+ exit_log("pluto cannot run without an MD5 hasher");
+ }
+
+ enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &encryption_alg))
+ {
+ const struct encrypt_desc *desc;
+
+ switch (encryption_alg)
+ {
+ case ENCR_3DES:
+ desc = &encrypt_desc_3des;
+ break;
+ case ENCR_BLOWFISH:
+ desc = &encrypt_desc_blowfish;
+ break;
+ case ENCR_AES_CBC:
+ desc = &encrypt_desc_aes;
+ break;
+ case ENCR_TWOFISH_CBC:
+ desc = &encrypt_desc_twofish;
+ ike_alg_add((struct ike_alg *)&encrypt_desc_twofish_ssh);
+ break;
+ case ENCR_SERPENT_CBC:
+ desc = &encrypt_desc_serpent;
+ break;
+ default:
+ continue;
+ }
+ ike_alg_add((struct ike_alg *)desc);
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &dh_group))
+ {
+ const struct dh_desc *desc;
+
+ switch (dh_group)
+ {
+ case MODP_1024_BIT:
+ desc = &dh_desc_modp_1024;
+ break;
+ case MODP_1536_BIT:
+ desc = &dh_desc_modp_1536;
+ break;
+ case MODP_2048_BIT:
+ desc = &dh_desc_modp_2048;
+ break;
+ case MODP_3072_BIT:
+ desc = &dh_desc_modp_3072;
+ break;
+ case MODP_4096_BIT:
+ desc = &dh_desc_modp_4096;
+ break;
+ case MODP_6144_BIT:
+ desc = &dh_desc_modp_6144;
+ break;
+ case MODP_8192_BIT:
+ desc = &dh_desc_modp_8192;
+ break;
+ case ECP_256_BIT:
+ desc = &dh_desc_ecp_256;
+ break;
+ case ECP_384_BIT:
+ desc = &dh_desc_ecp_384;
+ break;
+ case ECP_521_BIT:
+ desc = &dh_desc_ecp_521;
+ break;
+ case ECP_192_BIT:
+ desc = &dh_desc_ecp_192;
+ break;
+ case ECP_224_BIT:
+ desc = &dh_desc_ecp_224;
+ break;
+ default:
+ continue;
+ }
+ ike_alg_add((struct ike_alg *)desc);
+ }
+ enumerator->destroy(enumerator);
}
-/* Oakley group description
- *
- * See RFC2409 "The Internet key exchange (IKE)" 6.
- */
-
-const struct oakley_group_desc unset_group = {0, NULL, 0}; /* magic signifier */
-
-const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE] = {
-# define BYTES(bits) (((bits) + BITS_PER_BYTE - 1) / BITS_PER_BYTE)
- { OAKLEY_GROUP_MODP1024, &modp1024_modulus, BYTES(1024) },
- { OAKLEY_GROUP_MODP1536, &modp1536_modulus, BYTES(1536) },
- { OAKLEY_GROUP_MODP2048, &modp2048_modulus, BYTES(2048) },
- { OAKLEY_GROUP_MODP3072, &modp3072_modulus, BYTES(3072) },
- { OAKLEY_GROUP_MODP4096, &modp4096_modulus, BYTES(4096) },
- { OAKLEY_GROUP_MODP6144, &modp6144_modulus, BYTES(6144) },
- { OAKLEY_GROUP_MODP8192, &modp8192_modulus, BYTES(8192) },
-# undef BYTES
-};
-
-const struct oakley_group_desc *
-lookup_group(u_int16_t group)
+void free_crypto(void)
{
- int i;
-
- for (i = 0; i != elemsof(oakley_group); i++)
- if (group == oakley_group[i].group)
- return &oakley_group[i];
- return NULL;
+ /* currently nothing to do */
}
-/* Encryption Routines
- *
- * Each uses and updates the state object's st_new_iv.
- * This must already be initialized.
+/**
+ * Converts IKEv1 encryption algorithm name to crypter name
*/
+encryption_algorithm_t oakley_to_encryption_algorithm(int alg)
+{
+ switch (alg)
+ {
+ case OAKLEY_DES_CBC:
+ return ENCR_DES;
+ case OAKLEY_IDEA_CBC:
+ return ENCR_IDEA;
+ case OAKLEY_BLOWFISH_CBC:
+ return ENCR_BLOWFISH;
+ case OAKLEY_RC5_R16_B64_CBC:
+ return ENCR_RC5;
+ case OAKLEY_3DES_CBC:
+ return ENCR_3DES;
+ case OAKLEY_CAST_CBC:
+ return ENCR_CAST;
+ case OAKLEY_AES_CBC:
+ return ENCR_AES_CBC;
+ case OAKLEY_SERPENT_CBC:
+ return ENCR_SERPENT_CBC;
+ case OAKLEY_TWOFISH_CBC:
+ case OAKLEY_TWOFISH_CBC_SSH:
+ return ENCR_TWOFISH_CBC;
+ default:
+ return ENCR_UNDEFINED;
+ }
+}
-/* encrypt or decrypt part of an IKE message using DES
- * See RFC 2409 "IKE" Appendix B
+/**
+ * Converts IKEv1 hash algorithm name to hasher name
*/
-static void __attribute__ ((unused))
-do_des(bool enc, void *buf, size_t buf_len, struct state *st)
+hash_algorithm_t oakley_to_hash_algorithm(int alg)
{
- des_key_schedule ks;
-
- (void) des_set_key((des_cblock *)st->st_enc_key.ptr, ks);
-
- passert(st->st_new_iv_len >= DES_CBC_BLOCK_SIZE);
- st->st_new_iv_len = DES_CBC_BLOCK_SIZE; /* truncate */
-
- des_ncbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
- ks,
- (des_cblock *)st->st_new_iv, enc);
+ switch (alg)
+ {
+ case OAKLEY_MD5:
+ return HASH_MD5;
+ case OAKLEY_SHA:
+ return HASH_SHA1;
+ case OAKLEY_SHA2_256:
+ return HASH_SHA256;
+ case OAKLEY_SHA2_384:
+ return HASH_SHA384;
+ case OAKLEY_SHA2_512:
+ return HASH_SHA512;
+ default:
+ return HASH_UNKNOWN;
+ }
}
-/* encrypt or decrypt part of an IKE message using 3DES
- * See RFC 2409 "IKE" Appendix B
+/**
+ * Converts IKEv1 hash algorithm name to IKEv2 prf name
*/
-static void
-do_3des(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+pseudo_random_function_t oakley_to_prf(int alg)
{
- des_key_schedule ks[3];
-
- passert (!key_size || (key_size==(DES_CBC_BLOCK_SIZE * 3)))
- (void) des_set_key((des_cblock *)key + 0, ks[0]);
- (void) des_set_key((des_cblock *)key + 1, ks[1]);
- (void) des_set_key((des_cblock *)key + 2, ks[2]);
-
- des_ede3_cbc_encrypt((des_cblock *)buf, (des_cblock *)buf, buf_len,
- ks[0], ks[1], ks[2],
- (des_cblock *)iv, enc);
+ switch (alg)
+ {
+ case OAKLEY_MD5:
+ return PRF_HMAC_MD5;
+ case OAKLEY_SHA:
+ return PRF_HMAC_SHA1;
+ case OAKLEY_SHA2_256:
+ return PRF_HMAC_SHA2_256;
+ case OAKLEY_SHA2_384:
+ return PRF_HMAC_SHA2_384;
+ case OAKLEY_SHA2_512:
+ return PRF_HMAC_SHA2_512;
+ default:
+ return PRF_UNDEFINED;
+ }
}
-/* hash and prf routines */
-void
-crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st)
+/**
+ * Maps IKEv1 authentication method to IKEv2 signature scheme
+ */
+signature_scheme_t oakley_to_signature_scheme(int method)
{
- passert(st->st_new_iv_len >= e->enc_blocksize);
- st->st_new_iv_len = e->enc_blocksize; /* truncate */
-
- e->do_crypt(buf, size, st->st_enc_key.ptr, st->st_enc_key.len, st->st_new_iv, enc);
- /*
- e->set_key(&ctx, st->st_enc_key.ptr, st->st_enc_key.len);
- e->cbc_crypt(&ctx, buf, size, st->st_new_iv, enc);
- */
+ switch (method)
+ {
+ case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ return SIGN_RSA_EMSA_PKCS1_NULL;
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ return SIGN_ECDSA_WITH_NULL;
+ default:
+ return SIGN_UNKNOWN;
+ }
}
-/* HMAC package
- * rfc2104.txt specifies how HMAC works.
+/**
+ * Converts IKEv2 encryption to IKEv1 encryption algorithm
*/
-
-void
-hmac_init(struct hmac_ctx *ctx,
- const struct hash_desc *h,
- const u_char *key, size_t key_len)
+int oakley_from_encryption_algorithm(encryption_algorithm_t alg)
{
- int k;
-
- ctx->h = h;
- ctx->hmac_digest_size = h->hash_digest_size;
-
- /* Prepare the two pads for the HMAC */
-
- memset(ctx->buf1, '\0', h->hash_block_size);
-
- if (key_len <= h->hash_block_size)
- {
- memcpy(ctx->buf1, key, key_len);
- }
- else
- {
- h->hash_init(&ctx->hash_ctx);
- h->hash_update(&ctx->hash_ctx, key, key_len);
- h->hash_final(ctx->buf1, &ctx->hash_ctx);
- }
-
- memcpy(ctx->buf2, ctx->buf1, h->hash_block_size);
-
- for (k = 0; k < h->hash_block_size; k++)
- {
- ctx->buf1[k] ^= HMAC_IPAD;
- ctx->buf2[k] ^= HMAC_OPAD;
- }
-
- hmac_reinit(ctx);
+ switch (alg)
+ {
+ case ENCR_DES:
+ return OAKLEY_DES_CBC;
+ case ENCR_3DES:
+ return OAKLEY_3DES_CBC;
+ case ENCR_RC5:
+ return OAKLEY_RC5_R16_B64_CBC;
+ case ENCR_IDEA:
+ return OAKLEY_IDEA_CBC;
+ case ENCR_CAST:
+ return OAKLEY_CAST_CBC;
+ case ENCR_BLOWFISH:
+ return OAKLEY_BLOWFISH_CBC;
+ case ENCR_AES_CBC:
+ return OAKLEY_AES_CBC;
+ case ENCR_CAMELLIA_CBC:
+ return OAKLEY_CAMELLIA_CBC;
+ case ENCR_SERPENT_CBC:
+ return OAKLEY_SERPENT_CBC;
+ case ENCR_TWOFISH_CBC:
+ return OAKLEY_TWOFISH_CBC;
+ default:
+ return 0;
+ }
}
-void
-hmac_reinit(struct hmac_ctx *ctx)
+/**
+ * Converts IKEv2 integrity to IKEv1 hash algorithm
+ */
+int oakley_from_integrity_algorithm(integrity_algorithm_t alg)
{
- ctx->h->hash_init(&ctx->hash_ctx);
- ctx->h->hash_update(&ctx->hash_ctx, ctx->buf1, ctx->h->hash_block_size);
+ switch (alg)
+ {
+ case AUTH_HMAC_MD5_96:
+ return OAKLEY_MD5;
+ case AUTH_HMAC_SHA1_96:
+ return OAKLEY_SHA;
+ case AUTH_HMAC_SHA2_256_128:
+ return OAKLEY_SHA2_256;
+ case AUTH_HMAC_SHA2_384_192:
+ return OAKLEY_SHA2_384;
+ case AUTH_HMAC_SHA2_512_256:
+ return OAKLEY_SHA2_512;
+ default:
+ return 0;
+ }
}
-void
-hmac_update(struct hmac_ctx *ctx,
- const u_char *data, size_t data_len)
+/**
+ * Converts IKEv2 encryption to IKEv1 ESP encryption algorithm
+ */
+int esp_from_encryption_algorithm(encryption_algorithm_t alg)
{
- ctx->h->hash_update(&ctx->hash_ctx, data, data_len);
+ switch (alg)
+ {
+ case ENCR_DES:
+ return ESP_DES;
+ case ENCR_3DES:
+ return ESP_3DES;
+ case ENCR_RC5:
+ return ESP_RC5;
+ case ENCR_IDEA:
+ return ESP_IDEA;
+ case ENCR_CAST:
+ return ESP_CAST;
+ case ENCR_BLOWFISH:
+ return ESP_BLOWFISH;
+ case ENCR_NULL:
+ return ESP_NULL;
+ case ENCR_AES_CBC:
+ return ESP_AES;
+ case ENCR_AES_CTR:
+ return ESP_AES_CTR;
+ case ENCR_AES_CCM_ICV8:
+ return ESP_AES_CCM_8;
+ case ENCR_AES_CCM_ICV12:
+ return ESP_AES_CCM_12;
+ case ENCR_AES_CCM_ICV16:
+ return ESP_AES_CCM_16;
+ case ENCR_AES_GCM_ICV8:
+ return ESP_AES_GCM_8;
+ case ENCR_AES_GCM_ICV12:
+ return ESP_AES_GCM_12;
+ case ENCR_AES_GCM_ICV16:
+ return ESP_AES_GCM_16;
+ case ENCR_CAMELLIA_CBC:
+ return ESP_CAMELLIA;
+ case ENCR_SERPENT_CBC:
+ return ESP_SERPENT;
+ case ENCR_TWOFISH_CBC:
+ return ESP_TWOFISH;
+ default:
+ return 0;
+ }
}
-void
-hmac_final(u_char *output, struct hmac_ctx *ctx)
+/**
+ * Converts IKEv2 integrity to IKEv1 ESP authentication algorithm
+ */
+int esp_from_integrity_algorithm(integrity_algorithm_t alg)
{
- const struct hash_desc *h = ctx->h;
-
- h->hash_final(output, &ctx->hash_ctx);
-
- h->hash_init(&ctx->hash_ctx);
- h->hash_update(&ctx->hash_ctx, ctx->buf2, h->hash_block_size);
- h->hash_update(&ctx->hash_ctx, output, h->hash_digest_size);
- h->hash_final(output, &ctx->hash_ctx);
+ switch (alg)
+ {
+ case AUTH_HMAC_MD5_96:
+ return AUTH_ALGORITHM_HMAC_MD5;
+ case AUTH_HMAC_SHA1_96:
+ return AUTH_ALGORITHM_HMAC_SHA1;
+ case AUTH_AES_XCBC_96:
+ return AUTH_ALGORITHM_AES_XCBC_MAC;
+ case AUTH_HMAC_SHA2_256_128:
+ return AUTH_ALGORITHM_HMAC_SHA2_256;
+ case AUTH_HMAC_SHA2_384_192:
+ return AUTH_ALGORITHM_HMAC_SHA2_384;
+ case AUTH_HMAC_SHA2_512_256:
+ return AUTH_ALGORITHM_HMAC_SHA2_512;
+ default:
+ return 0;
+ }
}
diff --git a/src/pluto/crypto.h b/src/pluto/crypto.h
index e773d86df..06c4e1d1a 100644
--- a/src/pluto/crypto.h
+++ b/src/pluto/crypto.h
@@ -10,31 +10,20 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: crypto.h 3252 2007-10-06 21:24:50Z andreas $
*/
-#include <gmp.h> /* GNU MP library */
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+#include <credentials/keys/public_key.h>
-#include "libsha2/sha2.h"
#include "ike_alg.h"
extern void init_crypto(void);
+extern void free_crypto(void);
-/* Oakley group descriptions */
-
-extern MP_INT groupgenerator; /* MODP group generator (2) */
-
-struct oakley_group_desc {
- u_int16_t group;
- MP_INT *modulus;
- size_t bytes;
-};
-
-extern const struct oakley_group_desc unset_group; /* magic signifier */
-extern const struct oakley_group_desc *lookup_group(u_int16_t group);
-#define OAKLEY_GROUP_SIZE 7
-extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
+extern const struct dh_desc unset_group; /* magic signifier */
/* unification of cryptographic encoding/decoding algorithms
* The IV is taken from and returned to st->st_new_iv.
@@ -46,63 +35,23 @@ extern const struct oakley_group_desc oakley_group[OAKLEY_GROUP_SIZE];
#define MAX_OAKLEY_KEY_LEN0 (3 * DES_CBC_BLOCK_SIZE)
#define MAX_OAKLEY_KEY_LEN (256/BITS_PER_BYTE)
-struct state; /* forward declaration, dammit */
+struct state; /* forward declaration, dammit */
-void crypto_cbc_encrypt(const struct encrypt_desc *e, bool enc, u_int8_t *buf, size_t size, struct state *st);
-
-#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
- , (st)->st_iv_len = (st)->st_new_iv_len)
+#define update_iv(st) memcpy((st)->st_iv, (st)->st_new_iv \
+ , (st)->st_iv_len = (st)->st_new_iv_len)
#define set_ph1_iv(st, iv) \
- passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
- memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
+ passert((st)->st_ph1_iv_len <= sizeof((st)->st_ph1_iv)); \
+ memcpy((st)->st_ph1_iv, (iv), (st)->st_ph1_iv_len);
/* unification of cryptographic hashing mechanisms */
-#ifndef NO_HASH_CTX
-union hash_ctx {
- MD5_CTX ctx_md5;
- SHA1_CTX ctx_sha1;
- sha256_context ctx_sha256;
- sha512_context ctx_sha512;
- };
-
-/* HMAC package
- * Note that hmac_ctx can be (and is) copied since there are
- * no persistent pointers into it.
- */
-
-struct hmac_ctx {
- const struct hash_desc *h; /* underlying hash function */
- size_t hmac_digest_size; /* copy of h->hash_digest_size */
- union hash_ctx hash_ctx; /* ctx for hash function */
- u_char buf1[MAX_HASH_BLOCK_SIZE];
- u_char buf2[MAX_HASH_BLOCK_SIZE];
- };
-
-extern void hmac_init(
- struct hmac_ctx *ctx,
- const struct hash_desc *h,
- const u_char *key,
- size_t key_len);
-
-#define hmac_init_chunk(ctx, h, ch) hmac_init((ctx), (h), (ch).ptr, (ch).len)
-
-extern void hmac_reinit(struct hmac_ctx *ctx); /* saves recreating pads */
-
-extern void hmac_update(
- struct hmac_ctx *ctx,
- const u_char *data,
- size_t data_len);
-
-#define hmac_update_chunk(ctx, ch) hmac_update((ctx), (ch).ptr, (ch).len)
-
-extern void hmac_final(u_char *output, struct hmac_ctx *ctx);
+extern encryption_algorithm_t oakley_to_encryption_algorithm(int alg);
+extern hash_algorithm_t oakley_to_hash_algorithm(int alg);
+extern pseudo_random_function_t oakley_to_prf(int alg);
+extern signature_scheme_t oakley_to_signature_scheme(int method);
+extern int oakley_from_encryption_algorithm(encryption_algorithm_t alg);
+extern int oakley_from_integrity_algorithm(integrity_algorithm_t alg);
+extern int esp_from_encryption_algorithm(encryption_algorithm_t alg);
+extern int esp_from_integrity_algorithm(integrity_algorithm_t alg);
-#define hmac_final_chunk(ch, name, ctx) { \
- pfreeany((ch).ptr); \
- (ch).len = (ctx)->hmac_digest_size; \
- (ch).ptr = alloc_bytes((ch).len, name); \
- hmac_final((ch).ptr, (ctx)); \
- }
-#endif
diff --git a/src/pluto/db_ops.c b/src/pluto/db_ops.c
index 993baf53e..4ba4fa324 100644
--- a/src/pluto/db_ops.c
+++ b/src/pluto/db_ops.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: db_ops.c 3252 2007-10-06 21:24:50Z andreas $
*/
/*
@@ -31,22 +29,22 @@
* also update attrs_cur (by offset)
*
* db_context structure:
- * +---------------------+
- * | prop |
- * | .protoid |
- * | .trans | --+
- * | .trans_cnt | |
- * +---------------------+ <-+
- * | trans0 | ----> { trans#1 | ... | trans#i | ... }
- * +---------------------+ ^
- * | trans_cur | ----------------------' current transf.
- * +---------------------+
- * | attrs0 | ----> { attr#1 | ... | attr#j | ... }
- * +---------------------+ ^
- * | attrs_cur | ---------------------' current attr.
- * +---------------------+
- * | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
- * +---------------------+
+ * +---------------------+
+ * | prop |
+ * | .protoid |
+ * | .trans | --+
+ * | .trans_cnt | |
+ * +---------------------+ <-+
+ * | trans0 | ----> { trans#1 | ... | trans#i | ... }
+ * +---------------------+ ^
+ * | trans_cur | ----------------------' current transf.
+ * +---------------------+
+ * | attrs0 | ----> { attr#1 | ... | attr#j | ... }
+ * +---------------------+ ^
+ * | attrs_cur | ---------------------' current attr.
+ * +---------------------+
+ * | max_trans,max_attrs | max_trans/attrs: number of elem. of each vector
+ * +---------------------+
*
* See testing examples at end for interface usage.
*/
@@ -69,50 +67,31 @@
#include <assert.h>
-#ifndef NO_PLUTO
-#else
-#define passert(x) assert(x)
-extern int debug; /* eg: spi.c */
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define alloc_thing(thing, name) alloc_bytes(sizeof (thing), name)
-void * alloc_bytes(size_t size, const char *name) {
- void *p=malloc(size);
- if (p == NULL)
- fprintf(stderr, "unable to malloc %lu bytes for %s",
- (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-#define pfreeany(ptr) free(ptr)
-
-#endif
-
#ifdef NOT_YET
/*
- * Allocator cache:
- * Because of the single-threaded nature of pluto/spdb.c,
- * alloc()/free() is exercised many times with very small
- * lifetime objects.
- * Just caching last object (currently it will select the
- * largest) will avoid this allocation mas^Wperturbations
+ * Allocator cache:
+ * Because of the single-threaded nature of pluto/spdb.c,
+ * alloc()/free() is exercised many times with very small
+ * lifetime objects.
+ * Just caching last object (currently it will select the
+ * largest) will avoid this allocation mas^Wperturbations
*
*/
struct db_ops_alloc_cache {
- void *ptr;
- int size;
+ void *ptr;
+ int size;
};
#endif
#ifndef NO_DB_OPS_STATS
-/*
- * stats: do account for allocations
- * displayed in db_ops_show_status()
+/*
+ * stats: do account for allocations
+ * displayed in db_ops_show_status()
*/
struct db_ops_stats {
- int st_curr_cnt; /* current number of allocations */
- int st_total_cnt; /* total allocations so far */
- size_t st_maxsz; /* max. size requested */
+ int st_curr_cnt; /* current number of allocations */
+ int st_total_cnt; /* total allocations so far */
+ size_t st_maxsz; /* max. size requested */
};
#define DB_OPS_ZERO { 0, 0, 0};
#define DB_OPS_STATS_DESC "{curr_cnt, total_cnt, maxsz}"
@@ -121,239 +100,233 @@ struct db_ops_stats {
static struct db_ops_stats db_context_st = DB_OPS_ZERO;
static struct db_ops_stats db_trans_st = DB_OPS_ZERO;
static struct db_ops_stats db_attrs_st = DB_OPS_ZERO;
-static __inline__ void * alloc_bytes_st (size_t size, const char *str, struct db_ops_stats *st)
+static __inline__ void *malloc_bytes_st(size_t size, struct db_ops_stats *st)
{
- void *ptr = alloc_bytes(size, str);
- if (ptr) {
- st->st_curr_cnt++;
- st->st_total_cnt++;
- if (size > st->st_maxsz) st->st_maxsz=size;
- }
- return ptr;
+ void *ptr = malloc(size);
+ if (ptr)
+ {
+ st->st_curr_cnt++;
+ st->st_total_cnt++;
+ if (size > st->st_maxsz) st->st_maxsz=size;
+ }
+ return ptr;
}
-#define ALLOC_BYTES_ST(z,s,st) alloc_bytes_st(z, s, &st);
-#define PFREE_ST(p,st) do { st.st_curr_cnt--; pfree(p); } while (0);
+#define ALLOC_BYTES_ST(z,st) malloc_bytes_st(z, &st);
+#define PFREE_ST(p,st) do { st.st_curr_cnt--; free(p); } while (0);
#else
-#define ALLOC_BYTES_ST(z,s,n) alloc_bytes(z, s);
-#define PFREE_ST(p,n) pfree(p);
+#define ALLOC_BYTES_ST(z,n) malloc(z);
+#define PFREE_ST(p,n) free(p);
#endif /* NO_DB_OPS_STATS */
-/* Initialize db object
- * max_trans and max_attrs can be 0, will be dynamically expanded
- * as a result of "add" operations
+/* Initialize db object
+ * max_trans and max_attrs can be 0, will be dynamically expanded
+ * as a result of "add" operations
*/
int
db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs)
{
- int ret=-1;
+ ctx->trans0 = NULL;
+ ctx->attrs0 = NULL;
- ctx->trans0 = NULL;
- ctx->attrs0 = NULL;
+ if (max_trans > 0) { /* quite silly if not */
+ ctx->trans0 = ALLOC_BYTES_ST ( sizeof(struct db_trans) * max_trans,
+ db_trans_st);
+ memset(ctx->trans0, '\0', sizeof(struct db_trans) * max_trans);
+ }
- if (max_trans > 0) { /* quite silly if not */
- ctx->trans0 = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
- "db_context->trans", db_trans_st);
- if (!ctx->trans0) goto out;
- }
+ if (max_attrs > 0) { /* quite silly if not */
+ ctx->attrs0 = ALLOC_BYTES_ST (sizeof(struct db_attr) * max_attrs,
+ db_attrs_st);
+ memset(ctx->attrs0, '\0', sizeof(struct db_attr) * max_attrs);
+ }
- if (max_attrs > 0) { /* quite silly if not */
- ctx->attrs0 = ALLOC_BYTES_ST (sizeof (struct db_attr) * max_attrs,
- "db_context->attrs", db_attrs_st);
- if (!ctx->attrs0) goto out;
- }
- ret = 0;
-out:
- if (ret < 0 && ctx->trans0) {
- PFREE_ST(ctx->trans0, db_trans_st);
- ctx->trans0 = NULL;
- }
- ctx->max_trans = max_trans;
- ctx->max_attrs = max_attrs;
- ctx->trans_cur = ctx->trans0;
- ctx->attrs_cur = ctx->attrs0;
- ctx->prop.protoid = protoid;
- ctx->prop.trans = ctx->trans0;
- ctx->prop.trans_cnt = 0;
- return ret;
+ ctx->max_trans = max_trans;
+ ctx->max_attrs = max_attrs;
+ ctx->trans_cur = ctx->trans0;
+ ctx->attrs_cur = ctx->attrs0;
+ ctx->prop.protoid = protoid;
+ ctx->prop.trans = ctx->trans0;
+ ctx->prop.trans_cnt = 0;
+ return 0;
}
-/* Expand storage for transforms by number delta_trans */
+/* Expand storage for transforms by number delta_trans */
static int
db_trans_expand(struct db_context *ctx, int delta_trans)
{
- int ret = -1;
- struct db_trans *new_trans, *old_trans;
- int max_trans = ctx->max_trans + delta_trans;
- int offset;
+ int ret = -1;
+ struct db_trans *new_trans, *old_trans;
+ int max_trans = ctx->max_trans + delta_trans;
+ int offset;
- old_trans = ctx->trans0;
- new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
- "db_context->trans (expand)", db_trans_st);
- if (!new_trans)
- goto out;
- memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
-
- /* update trans0 (obviously) */
- ctx->trans0 = ctx->prop.trans = new_trans;
- /* update trans_cur (by offset) */
- offset = (char *)(new_trans) - (char *)(old_trans);
+ old_trans = ctx->trans0;
+ new_trans = ALLOC_BYTES_ST ( sizeof (struct db_trans) * max_trans,
+ db_trans_st);
+ if (!new_trans)
+ goto out;
+ memcpy(new_trans, old_trans, ctx->max_trans * sizeof(struct db_trans));
+
+ /* update trans0 (obviously) */
+ ctx->trans0 = ctx->prop.trans = new_trans;
+ /* update trans_cur (by offset) */
+ offset = (char *)(new_trans) - (char *)(old_trans);
- {
- char *cctx = (char *)(ctx->trans_cur);
-
- cctx += offset;
- ctx->trans_cur = (struct db_trans *)cctx;
- }
- /* update elem count */
- ctx->max_trans = max_trans;
- PFREE_ST(old_trans, db_trans_st);
- ret = 0;
+ {
+ char *cctx = (char *)(ctx->trans_cur);
+
+ cctx += offset;
+ ctx->trans_cur = (struct db_trans *)cctx;
+ }
+ /* update elem count */
+ ctx->max_trans = max_trans;
+ PFREE_ST(old_trans, db_trans_st);
+ ret = 0;
out:
- return ret;
+ return ret;
}
-/*
- * Expand storage for attributes by delta_attrs number AND
- * rewrite trans->attr pointers
+/*
+ * Expand storage for attributes by delta_attrs number AND
+ * rewrite trans->attr pointers
*/
static int
db_attrs_expand(struct db_context *ctx, int delta_attrs)
{
- int ret = -1;
- struct db_attr *new_attrs, *old_attrs;
- struct db_trans *t;
- int ti;
- int max_attrs = ctx->max_attrs + delta_attrs;
- int offset;
+ int ret = -1;
+ struct db_attr *new_attrs, *old_attrs;
+ struct db_trans *t;
+ int ti;
+ int max_attrs = ctx->max_attrs + delta_attrs;
+ int offset;
+
+ old_attrs = ctx->attrs0;
+ new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
+ db_attrs_st);
+ if (!new_attrs)
+ goto out;
- old_attrs = ctx->attrs0;
- new_attrs = ALLOC_BYTES_ST ( sizeof (struct db_attr) * max_attrs,
- "db_context->attrs (expand)", db_attrs_st);
- if (!new_attrs)
- goto out;
+ memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
+
+ /* update attrs0 and attrs_cur (obviously) */
+ offset = (char *)(new_attrs) - (char *)(old_attrs);
+
+ {
+ char *actx = (char *)(ctx->attrs0);
+
+ actx += offset;
+ ctx->attrs0 = (struct db_attr *)actx;
+
+ actx = (char *)ctx->attrs_cur;
+ actx += offset;
+ ctx->attrs_cur = (struct db_attr *)actx;
+ }
- memcpy(new_attrs, old_attrs, ctx->max_attrs * sizeof(struct db_attr));
-
- /* update attrs0 and attrs_cur (obviously) */
- offset = (char *)(new_attrs) - (char *)(old_attrs);
-
- {
- char *actx = (char *)(ctx->attrs0);
-
- actx += offset;
- ctx->attrs0 = (struct db_attr *)actx;
-
- actx = (char *)ctx->attrs_cur;
- actx += offset;
- ctx->attrs_cur = (struct db_attr *)actx;
- }
+ /* for each transform, rewrite attrs pointer by offsetting it */
+ for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
+ char *actx = (char *)(t->attrs);
- /* for each transform, rewrite attrs pointer by offsetting it */
- for (t=ctx->prop.trans, ti=0; ti < ctx->prop.trans_cnt; t++, ti++) {
- char *actx = (char *)(t->attrs);
-
- actx += offset;
- t->attrs = (struct db_attr *)actx;
- }
- /* update elem count */
- ctx->max_attrs = max_attrs;
- PFREE_ST(old_attrs, db_attrs_st);
- ret = 0;
+ actx += offset;
+ t->attrs = (struct db_attr *)actx;
+ }
+ /* update elem count */
+ ctx->max_attrs = max_attrs;
+ PFREE_ST(old_attrs, db_attrs_st);
+ ret = 0;
out:
- return ret;
+ return ret;
}
-/* Allocate a new db object */
+/* Allocate a new db object */
struct db_context *
db_prop_new(u_int8_t protoid, int max_trans, int max_attrs)
{
- struct db_context *ctx;
- ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), "db_context", db_context_st);
- if (!ctx) goto out;
-
- if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
- PFREE_ST(ctx, db_context_st);
- ctx=NULL;
- }
+ struct db_context *ctx;
+ ctx = ALLOC_BYTES_ST ( sizeof (struct db_context), db_context_st);
+ if (!ctx) goto out;
+
+ if (db_prop_init(ctx, protoid, max_trans, max_attrs) < 0) {
+ PFREE_ST(ctx, db_context_st);
+ ctx=NULL;
+ }
out:
- return ctx;
+ return ctx;
}
-/* Free a db object */
+/* Free a db object */
void
db_destroy(struct db_context *ctx)
{
- if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
- if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
- PFREE_ST(ctx, db_context_st);
+ if (ctx->trans0) PFREE_ST(ctx->trans0, db_trans_st);
+ if (ctx->attrs0) PFREE_ST(ctx->attrs0, db_attrs_st);
+ PFREE_ST(ctx, db_context_st);
}
-/* Start a new transform, expand trans0 is needed */
+/* Start a new transform, expand trans0 is needed */
int
db_trans_add(struct db_context *ctx, u_int8_t transid)
{
- /* skip incrementing current trans pointer the 1st time*/
- if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
- ctx->trans_cur++;
- /*
- * Strategy: if more space is needed, expand by
- * <current_size>/2 + 1
- *
- * This happens to produce a "reasonable" sequence
- * after few allocations, eg.:
- * 0,1,2,4,8,13,20,31,47
- */
- if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
- /* XXX:jjo if fails should shout and flag it */
- if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
- return -1;
- }
- ctx->trans_cur->transid = transid;
- ctx->trans_cur->attrs=ctx->attrs_cur;
- ctx->trans_cur->attr_cnt = 0;
- ctx->prop.trans_cnt++;
- return 0;
+ /* skip incrementing current trans pointer the 1st time*/
+ if (ctx->trans_cur && ctx->trans_cur->attr_cnt)
+ ctx->trans_cur++;
+ /*
+ * Strategy: if more space is needed, expand by
+ * <current_size>/2 + 1
+ *
+ * This happens to produce a "reasonable" sequence
+ * after few allocations, eg.:
+ * 0,1,2,4,8,13,20,31,47
+ */
+ if ((ctx->trans_cur - ctx->trans0) >= ctx->max_trans) {
+ /* XXX:jjo if fails should shout and flag it */
+ if (db_trans_expand(ctx, ctx->max_trans/2 + 1)<0)
+ return -1;
+ }
+ ctx->trans_cur->transid = transid;
+ ctx->trans_cur->attrs=ctx->attrs_cur;
+ ctx->trans_cur->attr_cnt = 0;
+ ctx->prop.trans_cnt++;
+ return 0;
}
-/* Add attr copy to current transform, expanding attrs0 if needed */
+/* Add attr copy to current transform, expanding attrs0 if needed */
int
db_attr_add(struct db_context *ctx, const struct db_attr *a)
{
- /*
- * Strategy: if more space is needed, expand by
- * <current_size>/2 + 1
- */
- if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
- /* XXX:jjo if fails should shout and flag it */
- if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
- return -1;
- }
- *ctx->attrs_cur++=*a;
- ctx->trans_cur->attr_cnt++;
- return 0;
+ /*
+ * Strategy: if more space is needed, expand by
+ * <current_size>/2 + 1
+ */
+ if ((ctx->attrs_cur - ctx->attrs0) >= ctx->max_attrs) {
+ /* XXX:jjo if fails should shout and flag it */
+ if (db_attrs_expand(ctx, ctx->max_attrs/2 + 1) < 0)
+ return -1;
+ }
+ *ctx->attrs_cur++=*a;
+ ctx->trans_cur->attr_cnt++;
+ return 0;
}
-/* Add attr copy (by value) to current transform,
- * expanding attrs0 if needed, just calls db_attr_add().
+/* Add attr copy (by value) to current transform,
+ * expanding attrs0 if needed, just calls db_attr_add().
*/
int
db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val)
{
- struct db_attr attr;
- attr.type = type;
- attr.val = val;
- return db_attr_add (ctx, &attr);
+ struct db_attr attr;
+ attr.type = type;
+ attr.val = val;
+ return db_attr_add (ctx, &attr);
}
#ifndef NO_DB_OPS_STATS
int
db_ops_show_status(void)
{
- whack_log(RC_COMMENT, "stats " __FILE__ ": "
- DB_OPS_STATS_DESC " :"
- DB_OPS_STATS_STR("context")
- DB_OPS_STATS_STR("trans")
- DB_OPS_STATS_STR("attrs"),
- DB_OPS_STATS_F(db_context_st),
- DB_OPS_STATS_F(db_trans_st),
- DB_OPS_STATS_F(db_attrs_st)
- );
- return 0;
+ whack_log(RC_COMMENT, "stats " __FILE__ ": "
+ DB_OPS_STATS_DESC " :"
+ DB_OPS_STATS_STR("context")
+ DB_OPS_STATS_STR("trans")
+ DB_OPS_STATS_STR("attrs"),
+ DB_OPS_STATS_F(db_context_st),
+ DB_OPS_STATS_F(db_trans_st),
+ DB_OPS_STATS_F(db_attrs_st)
+ );
+ return 0;
}
#endif /* NO_DB_OPS_STATS */
/*
@@ -362,51 +335,51 @@ db_ops_show_status(void)
#ifdef TEST
static void db_prop_print(struct db_prop *p)
{
- struct db_trans *t;
- struct db_attr *a;
- int ti, ai;
- enum_names *n, *n_at, *n_av;
- printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
- for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
- switch( t->transid) {
- case PROTO_ISAKMP:
- n=&isakmp_transformid_names;break;
- case PROTO_IPSEC_ESP:
- n=&esp_transformid_names;break;
- default:
- continue;
- }
- printf(" transid=\"%s\"\n",
- enum_name(n, t->transid));
- for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
- int i;
- switch( t->transid) {
- case PROTO_ISAKMP:
- n_at=&oakley_attr_names;
- i=a->type|ISAKMP_ATTR_AF_TV;
- n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
- break;
- case PROTO_IPSEC_ESP:
- n_at=&ipsec_attr_names;
- i=a->type|ISAKMP_ATTR_AF_TV;
- n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
- break;
- default:
- continue;
- }
- printf(" type=\"%s\" value=\"%s\"\n",
- enum_name(n_at, i),
- enum_name(n_av, a->val));
+ struct db_trans *t;
+ struct db_attr *a;
+ int ti, ai;
+ enum_names *n, *n_at, *n_av;
+ printf("protoid=\"%s\"\n", enum_name(&protocol_names, p->protoid));
+ for (ti=0, t=p->trans; ti< p->trans_cnt; ti++, t++) {
+ switch( t->transid) {
+ case PROTO_ISAKMP:
+ n=&isakmp_transformid_names;break;
+ case PROTO_IPSEC_ESP:
+ n=&esp_transformid_names;break;
+ default:
+ continue;
+ }
+ printf(" transid=\"%s\"\n",
+ enum_name(n, t->transid));
+ for (ai=0, a=t->attrs; ai < t->attr_cnt; ai++, a++) {
+ int i;
+ switch( t->transid) {
+ case PROTO_ISAKMP:
+ n_at=&oakley_attr_names;
+ i=a->type|ISAKMP_ATTR_AF_TV;
+ n_av=oakley_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
+ break;
+ case PROTO_IPSEC_ESP:
+ n_at=&ipsec_attr_names;
+ i=a->type|ISAKMP_ATTR_AF_TV;
+ n_av=ipsec_attr_val_descs[(i)&ISAKMP_ATTR_RTYPE_MASK];
+ break;
+ default:
+ continue;
+ }
+ printf(" type=\"%s\" value=\"%s\"\n",
+ enum_name(n_at, i),
+ enum_name(n_av, a->val));
+ }
}
- }
}
static void db_print(struct db_context *ctx)
{
- printf("trans_cur diff=%d, attrs_cur diff=%d\n",
- ctx->trans_cur - ctx->trans0,
- ctx->attrs_cur - ctx->attrs0);
- db_prop_print(&ctx->prop);
+ printf("trans_cur diff=%d, attrs_cur diff=%d\n",
+ ctx->trans_cur - ctx->trans0,
+ ctx->attrs_cur - ctx->attrs0);
+ db_prop_print(&ctx->prop);
}
void
@@ -415,25 +388,25 @@ void abort(void);
void
passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
{
- fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- abort(); /* exiting correctly doesn't always work */
+ fprintf(stderr, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ abort(); /* exiting correctly doesn't always work */
}
int main(void) {
- struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
- db_trans_add(ctx, KEY_IKE);
- db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC);
- db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
- db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
- db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
- db_trans_add(ctx, KEY_IKE);
- db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC);
- db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
- db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
- db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
- db_trans_add(ctx, ESP_3DES);
- db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
- db_print(ctx);
- db_destroy(ctx);
- return 0;
+ struct db_context *ctx=db_prop_new(PROTO_ISAKMP, 0, 0);
+ db_trans_add(ctx, KEY_IKE);
+ db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_3DES_CBC);
+ db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
+ db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
+ db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1024);
+ db_trans_add(ctx, KEY_IKE);
+ db_attr_add_values(ctx, OAKLEY_ENCRYPTION_ALGORITHM, OAKLEY_AES_CBC);
+ db_attr_add_values(ctx, OAKLEY_HASH_ALGORITHM, OAKLEY_MD5);
+ db_attr_add_values(ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
+ db_attr_add_values(ctx, OAKLEY_GROUP_DESCRIPTION, OAKLEY_GROUP_MODP1536);
+ db_trans_add(ctx, ESP_3DES);
+ db_attr_add_values(ctx, AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1);
+ db_print(ctx);
+ db_destroy(ctx);
+ return 0;
}
#endif
diff --git a/src/pluto/db_ops.h b/src/pluto/db_ops.h
index 4004e710a..464c245dd 100644
--- a/src/pluto/db_ops.h
+++ b/src/pluto/db_ops.h
@@ -10,47 +10,45 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: db_ops.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _DB_OPS_H
#define _DB_OPS_H
/*
- * Main db object, (quite proposal "oriented")
+ * Main db object, (quite proposal "oriented")
*/
#ifndef NO_DB_CONTEXT
struct db_context {
- struct db_prop prop; /* proposal buffer (not pointer) */
- struct db_trans *trans0; /* transf. list, dynamically sized */
- struct db_trans *trans_cur; /* current transform ptr */
- struct db_attr *attrs0; /* attr. list, dynamically sized */
- struct db_attr *attrs_cur; /* current attribute ptr */
- int max_trans; /* size of trans list */
- int max_attrs; /* size of attrs list */
+ struct db_prop prop; /* proposal buffer (not pointer) */
+ struct db_trans *trans0; /* transf. list, dynamically sized */
+ struct db_trans *trans_cur; /* current transform ptr */
+ struct db_attr *attrs0; /* attr. list, dynamically sized */
+ struct db_attr *attrs_cur; /* current attribute ptr */
+ int max_trans; /* size of trans list */
+ int max_attrs; /* size of attrs list */
};
/*
- * Allocate a new db object
+ * Allocate a new db object
*/
struct db_context * db_prop_new(u_int8_t protoid, int max_trans, int max_attrs);
-/* Initialize object for proposal building */
+/* Initialize object for proposal building */
int db_prop_init(struct db_context *ctx, u_int8_t protoid, int max_trans, int max_attrs);
-/* Free all resourses for this db */
+/* Free all resourses for this db */
void db_destroy(struct db_context *ctx);
-/* Start a new transform */
+/* Start a new transform */
int db_trans_add(struct db_context *ctx, u_int8_t transid);
-/* Add a new attribute by copying db_attr content */
+/* Add a new attribute by copying db_attr content */
int db_attr_add(struct db_context *db_ctx, const struct db_attr *attr);
-/* Add a new attribute by value */
+/* Add a new attribute by value */
int db_attr_add_values(struct db_context *ctx, u_int16_t type, u_int16_t val);
-/* Get proposal from db object */
+/* Get proposal from db object */
static __inline__ struct db_prop *db_prop_get(struct db_context *ctx) {
- return &ctx->prop;
+ return &ctx->prop;
}
-/* Show stats (allocation, etc) */
+/* Show stats (allocation, etc) */
#endif /* NO_DB_CONTEXT */
int db_ops_show_status(void);
#endif /* _DB_OPS_H */
diff --git a/src/pluto/defs.c b/src/pluto/defs.c
index f2c1eab48..f83318e12 100644
--- a/src/pluto/defs.c
+++ b/src/pluto/defs.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: defs.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <stdlib.h>
@@ -27,296 +25,62 @@
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
-
-const chunk_t empty_chunk = { NULL, 0 };
+#include "whack.h" /* for RC_LOG_SERIOUS */
bool
all_zero(const unsigned char *m, size_t len)
{
- size_t i;
-
- for (i = 0; i != len; i++)
- if (m[i] != '\0')
- return FALSE;
- return TRUE;
-}
-
-/* memory allocation
- *
- * LEAK_DETECTIVE puts a wrapper around each allocation and maintains
- * a list of live ones. If a dead one is freed, an assertion MIGHT fail.
- * If the live list is currupted, that will often be detected.
- * In the end, report_leaks() is called, and the names of remaining
- * live allocations are printed. At the moment, it is hoped, not that
- * the list is empty, but that there will be no surprises.
- *
- * Accepted Leaks:
- * - "struct iface" and "device name" (for "discovered" net interfaces)
- * - "struct event in event_schedule()" (events not associated with states)
- * - "Pluto lock name" (one only, needed until end -- why bother?)
- */
-
-#ifdef LEAK_DETECTIVE
-
-/* this magic number is 3671129837 decimal (623837458 complemented) */
-#define LEAK_MAGIC 0xDAD0FEEDul
-
-union mhdr {
- struct {
- const char *name;
- union mhdr *older, *newer;
- unsigned long magic;
- } i; /* info */
- unsigned long junk; /* force maximal alignment */
-};
-
-static union mhdr *allocs = NULL;
-
-void *alloc_bytes(size_t size, const char *name)
-{
- union mhdr *p = malloc(sizeof(union mhdr) + size);
-
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- p->i.name = name;
- p->i.older = allocs;
- if (allocs != NULL)
- allocs->i.newer = p;
- allocs = p;
- p->i.newer = NULL;
- p->i.magic = LEAK_MAGIC;
-
- memset(p+1, '\0', size);
- return p+1;
-}
-
-void *
-clone_bytes(const void *orig, size_t size, const char *name)
-{
- void *p = alloc_bytes(size, name);
-
- memcpy(p, orig, size);
- return p;
-}
-
-void
-pfree(void *ptr)
-{
- union mhdr *p;
-
- passert(ptr != NULL);
- p = ((union mhdr *)ptr) - 1;
- passert(p->i.magic == LEAK_MAGIC);
- if (p->i.older != NULL)
- {
- passert(p->i.older->i.newer == p);
- p->i.older->i.newer = p->i.newer;
- }
- if (p->i.newer == NULL)
- {
- passert(p == allocs);
- allocs = p->i.older;
- }
- else
- {
- passert(p->i.newer->i.older == p);
- p->i.newer->i.older = p->i.older;
- }
- p->i.magic = ~LEAK_MAGIC;
- free(p);
-}
-
-void
-report_leaks(void)
-{
- union mhdr
- *p = allocs,
- *pprev = NULL;
- unsigned long n = 0;
-
- while (p != NULL)
- {
- passert(p->i.magic == LEAK_MAGIC);
- passert(pprev == p->i.newer);
- pprev = p;
- p = p->i.older;
- n++;
- if (p == NULL || pprev->i.name != p->i.name)
- {
- if (n != 1)
- plog("leak: %lu * %s", n, pprev->i.name);
- else
- plog("leak: %s", pprev->i.name);
- n = 0;
- }
- }
-}
-
-#else /* !LEAK_DETECTIVE */
-
-void *alloc_bytes(size_t size, const char *name)
-{
- void *p = malloc(size);
-
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- memset(p, '\0', size);
- return p;
-}
-
-void *clone_bytes(const void *orig, size_t size, const char *name)
-{
- void *p = malloc(size);
+ size_t i;
- if (p == NULL)
- exit_log("unable to malloc %lu bytes for %s"
- , (unsigned long) size, name);
- memcpy(p, orig, size);
- return p;
+ for (i = 0; i != len; i++)
+ if (m[i] != '\0')
+ return FALSE;
+ return TRUE;
}
-#endif /* !LEAK_DETECTIVE */
/* Note that there may be as many as six IDs that are temporary at
* one time before unsharing the two ends of a connection. So we need
* at least six temporary buffers for DER_ASN1_DN IDs.
* We rotate them. Be careful!
*/
-#define MAX_BUF 10
+#define MAX_BUF 10
char*
temporary_cyclic_buffer(void)
{
- static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
- static int counter = 0; /* cyclic counter */
+ static char buf[MAX_BUF][BUF_LEN]; /* MAX_BUF internal buffers */
+ static int counter = 0; /* cyclic counter */
- if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
- return buf[counter]; /* assign temporary buffer */
+ if (++counter == MAX_BUF) counter = 0; /* next internal buffer */
+ return buf[counter]; /* assign temporary buffer */
}
/* concatenates two sub paths into a string with a maximum size of BUF_LEN
* use for temporary storage only
*/
-const char*
-concatenate_paths(const char *a, const char *b)
+char* concatenate_paths(char *a, char *b)
{
- char *c;
+ char *c;
- if (*b == '/' || *b == '.')
- return b;
+ if (*b == '/' || *b == '.')
+ return b;
- c = temporary_cyclic_buffer();
- snprintf(c, BUF_LEN, "%s/%s", a, b);
- return c;
+ c = temporary_cyclic_buffer();
+ snprintf(c, BUF_LEN, "%s/%s", a, b);
+ return c;
}
-/* compare two chunks, returns zero if a equals b
- * negative/positive if a is earlier/later in the alphabet than b
- */
-int
-cmp_chunk(chunk_t a, chunk_t b)
-{
- int cmp_len, len, cmp_value;
-
- cmp_len = a.len - b.len;
- len = (cmp_len < 0)? a.len : b.len;
- cmp_value = memcmp(a.ptr, b.ptr, len);
-
- return (cmp_value == 0)? cmp_len : cmp_value;
-};
-
/* moves a chunk to a memory position, chunk is freed afterwards
* position pointer is advanced after the insertion point
*/
void
mv_chunk(u_char **pos, chunk_t content)
{
- if (content.len > 0)
- {
- chunkcpy(*pos, content);
- freeanychunk(content);
- }
-}
-
-/*
- * write the binary contents of a chunk_t to a file
- */
-bool
-write_chunk(const char *filename, const char *label, chunk_t ch
-, mode_t mask, bool force)
-{
- mode_t oldmask;
- FILE *fd;
- size_t written;
-
- if (!force)
- {
- fd = fopen(filename, "r");
- if (fd)
- {
- fclose(fd);
- plog(" %s file '%s' already exists", label, filename);
- return FALSE;
- }
- }
-
- /* set umask */
- oldmask = umask(mask);
-
- fd = fopen(filename, "w");
-
- if (fd)
- {
- written = fwrite(ch.ptr, sizeof(u_char), ch.len, fd);
- fclose(fd);
- if (written != ch.len)
+ if (content.len > 0)
{
- plog(" writing to %s file '%s' failed", label, filename);
- umask(oldmask);
- return FALSE;
+ chunkcpy(*pos, content);
+ free(content.ptr);
}
- plog(" written %s file '%s' (%d bytes)", label, filename, (int)ch.len);
- umask(oldmask);
- return TRUE;
- }
- else
- {
- plog(" could not open %s file '%s' for writing", label, filename);
- umask(oldmask);
- return FALSE;
- }
-}
-
-/* Names of the months */
-
-static const char* months[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-
-/*
- * Display a date either in local or UTC time
- */
-char*
-timetoa(const time_t *time, bool utc)
-{
- static char buf[TIMETOA_BUF];
-
- if (*time == UNDEFINED_TIME)
- sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
- else
- {
- struct tm *t = (utc)? gmtime(time) : localtime(time);
-
- sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
- months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
- (utc)?" UTC ":" ", t->tm_year + 1900
- );
- }
- return buf;
}
/* checks if the expiration date has been reached and
@@ -327,44 +91,44 @@ timetoa(const time_t *time, bool utc)
const char*
check_expiry(time_t expiration_date, int warning_interval, bool strict)
{
- time_t now;
- int time_left;
-
- if (expiration_date == UNDEFINED_TIME)
- return "ok (expires never)";
+ time_t now;
+ int time_left;
- /* determine the current time */
- time(&now);
+ if (expiration_date == UNDEFINED_TIME)
+ return "ok (expires never)";
- time_left = (expiration_date - now);
- if (time_left < 0)
- return strict? "fatal (expired)" : "warning (expired)";
+ /* determine the current time */
+ time(&now);
- if (time_left > 86400*warning_interval)
- return "ok";
- {
- static char buf[35]; /* temporary storage */
- const char* unit = "second";
+ time_left = (expiration_date - now);
+ if (time_left < 0)
+ return strict? "fatal (expired)" : "warning (expired)";
- if (time_left > 172800)
- {
- time_left /= 86400;
- unit = "day";
- }
- else if (time_left > 7200)
- {
- time_left /= 3600;
- unit = "hour";
- }
- else if (time_left > 120)
+ if (time_left > 86400*warning_interval)
+ return "ok";
{
- time_left /= 60;
- unit = "minute";
+ static char buf[35]; /* temporary storage */
+ const char* unit = "second";
+
+ if (time_left > 172800)
+ {
+ time_left /= 86400;
+ unit = "day";
+ }
+ else if (time_left > 7200)
+ {
+ time_left /= 3600;
+ unit = "hour";
+ }
+ else if (time_left > 120)
+ {
+ time_left /= 60;
+ unit = "minute";
+ }
+ snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
+ unit, (time_left == 1)?"":"s");
+ return buf;
}
- snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
- unit, (time_left == 1)?"":"s");
- return buf;
- }
}
@@ -374,8 +138,8 @@ check_expiry(time_t expiration_date, int warning_interval, bool strict)
int
file_select(const struct dirent *entry)
{
- return strcmp(entry->d_name, "." ) &&
- strcmp(entry->d_name, "..");
+ return strcmp(entry->d_name, "." ) &&
+ strcmp(entry->d_name, "..");
}
diff --git a/src/pluto/defs.h b/src/pluto/defs.h
index 574ce4a1a..8491f4ae8 100644
--- a/src/pluto/defs.h
+++ b/src/pluto/defs.h
@@ -11,128 +11,77 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: defs.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _DEFS_H
#define _DEFS_H
+#include <string.h>
#include <sys/types.h>
+#include <chunk.h>
+
#ifdef KLIPS
-# define USED_BY_KLIPS /* ignore */
+# define USED_BY_KLIPS /* ignore */
#else
-# define USED_BY_KLIPS UNUSED
+# define USED_BY_KLIPS UNUSED
#endif
#ifdef DEBUG
-# define USED_BY_DEBUG /* ignore */
+# define USED_BY_DEBUG /* ignore */
#else
-# define USED_BY_DEBUG UNUSED
+# define USED_BY_DEBUG UNUSED
#endif
-/* Length of temporary buffers */
-
-#define BUF_LEN 512
-
/* type of serial number of a state object
* Needed in connections.h and state.h; here to simplify dependencies.
*/
typedef unsigned long so_serial_t;
-#define SOS_NOBODY 0 /* null serial number */
-#define SOS_FIRST 1 /* first normal serial number */
+#define SOS_NOBODY 0 /* null serial number */
+#define SOS_FIRST 1 /* first normal serial number */
/* memory allocation */
-extern void *alloc_bytes(size_t size, const char *name);
-#define alloc_thing(thing, name) (alloc_bytes(sizeof(thing), (name)))
+#define clone_thing(orig) clalloc((void *)&(orig), sizeof(orig))
-extern void *clone_bytes(const void *orig, size_t size, const char *name);
-#define clone_thing(orig, name) clone_bytes((const void *)&(orig), sizeof(orig), (name))
-#define clone_str(str, name) \
- ((str) == NULL? NULL : clone_bytes((str), strlen((str))+1, (name)))
+#define clone_str(str) \
+ ((str) == NULL? NULL : strdup(str))
+
+#define replace(p, q) \
+ { free(p); (p) = (q); }
-#ifdef LEAK_DETECTIVE
- extern void pfree(void *ptr);
- extern void report_leaks(void);
-#else
-# define pfree(ptr) free(ptr) /* ordinary stdc free */
-#endif
-#define pfreeany(p) { if ((p) != NULL) pfree(p); }
-#define replace(p, q) { pfreeany(p); (p) = (q); }
-
-
-/* chunk is a simple pointer-and-size abstraction */
-
-struct chunk {
- u_char *ptr;
- size_t len;
- };
-typedef struct chunk chunk_t;
-
-#define setchunk(ch, addr, size) { (ch).ptr = (addr); (ch).len = (size); }
-#define strchunk(str) { str, sizeof(str) }
-/* NOTE: freeanychunk, unlike pfreeany, NULLs .ptr */
-#define freeanychunk(ch) { pfreeany((ch).ptr); (ch).ptr = NULL; }
-#define clonetochunk(ch, addr, size, name) \
- { (ch).ptr = clone_bytes((addr), (ch).len = (size), name); }
-#define clonereplacechunk(ch, addr, size, name) \
- { pfreeany((ch).ptr); clonetochunk(ch, addr, size, name); }
#define chunkcpy(dst, chunk) \
- { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
-#define same_chunk(a, b) \
- ( (a).len == (b).len && memcmp((a).ptr, (b).ptr, (b).len) == 0 )
+ { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
extern char* temporary_cyclic_buffer(void);
-extern const char* concatenate_paths(const char *a, const char *b);
-
-extern const chunk_t empty_chunk;
-
-/* compare two chunks */
-extern int cmp_chunk(chunk_t a, chunk_t b);
+extern char* concatenate_paths(char *a, char *b);
/* move a chunk to a memory position and free it after insertion */
extern void mv_chunk(u_char **pos, chunk_t content);
-/* write the binary contents of a chunk_t to a file */
-extern bool write_chunk(const char *filename, const char *label, chunk_t ch
- ,mode_t mask, bool force);
-
-/* display a date either in local or UTC time */
-extern char* timetoa(const time_t *time, bool utc);
-
/* warns a predefined interval before expiry */
extern const char* check_expiry(time_t expiration_date,
- int warning_interval, bool strict);
+ int warning_interval, bool strict);
-#define MAX_PROMPT_PASS_TRIALS 5
-#define PROMPT_PASS_LEN 64
+#define MAX_PROMPT_PASS_TRIALS 5
+#define PROMPT_PASS_LEN 64
/* struct used to prompt for a secret passphrase
* from a console with file descriptor fd
*/
typedef struct {
- char secret[PROMPT_PASS_LEN+1];
- bool prompt;
- int fd;
+ char secret[PROMPT_PASS_LEN+1];
+ bool prompt;
+ int fd;
} prompt_pass_t;
-/* no time defined in time_t */
-#define UNDEFINED_TIME 0
-
-/* size of timetoa string buffer */
-#define TIMETOA_BUF 30
-
/* filter eliminating the directory entries '.' and '..' */
typedef struct dirent dirent_t;
extern int file_select(const dirent_t *entry);
/* cleanly exit Pluto */
-
extern void exit_pluto(int /*status*/) NEVER_RETURNS;
-
/* zero all bytes */
#define zero(x) memset((x), '\0', sizeof(*(x)))
diff --git a/src/pluto/demux.c b/src/pluto/demux.c
index 04728a4a8..3cfc909af 100644
--- a/src/pluto/demux.c
+++ b/src/pluto/demux.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: demux.c 3686 2008-03-28 11:48:14Z martin $
*/
/* Ordering Constraints on Payloads
@@ -110,8 +108,8 @@
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
-#include <sys/time.h> /* only used for belt-and-suspenders select call */
-#include <sys/poll.h> /* only used for forensic poll call */
+#include <sys/time.h> /* only used for belt-and-suspenders select call */
+#include <sys/poll.h> /* only used for forensic poll call */
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
@@ -119,9 +117,9 @@
#include <sys/queue.h>
#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
-# include <asm/types.h> /* for __u8, __u32 */
+# include <asm/types.h> /* for __u8, __u32 */
# include <linux/errqueue.h>
-# include <sys/uio.h> /* struct iovec */
+# include <sys/uio.h> /* struct iovec */
#endif
#include <freeswan.h>
@@ -132,15 +130,13 @@
#include "connections.h"
#include "state.h"
#include "packet.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
#include "ike_alg.h"
#include "log.h"
-#include "demux.h" /* needs packet.h */
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "demux.h" /* needs packet.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "timer.h"
-#include "whack.h" /* requires connections.h */
+#include "whack.h" /* requires connections.h */
#include "server.h"
#include "nat_traversal.h"
#include "vendor.h"
@@ -173,14 +169,14 @@ u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
*/
struct state_microcode {
- enum state_kind state, next_state;
- lset_t flags;
- lset_t req_payloads; /* required payloads (allows just one) */
- lset_t opt_payloads; /* optional payloads (any mumber) */
- /* if not ISAKMP_NEXT_NONE, process_packet will emit HDR with this as np */
- u_int8_t first_out_payload;
- enum event_type timeout_event;
- state_transition_fn *processor;
+ enum state_kind state, next_state;
+ lset_t flags;
+ lset_t req_payloads; /* required payloads (allows just one) */
+ lset_t opt_payloads; /* optional payloads (any mumber) */
+ /* if not ISAKMP_NEXT_NONE, process_packet will emit HDR with this as np */
+ u_int8_t first_out_payload;
+ enum event_type timeout_event;
+ state_transition_fn *processor;
};
/* State Microcode Flags, in several groups */
@@ -190,19 +186,21 @@ struct state_microcode {
* Note: SMF_ALL_AUTH matches 0 for those circumstances when no auth
* has been set.
*/
-#define SMF_ALL_AUTH LRANGE(0, OAKLEY_AUTH_ROOF-1)
-#define SMF_PSK_AUTH LELEM(OAKLEY_PRESHARED_KEY)
-#define SMF_DS_AUTH (LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG))
-#define SMF_PKE_AUTH (LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC))
-#define SMF_RPKE_AUTH (LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV))
+#define SMF_ALL_AUTH LRANGE(0, OAKLEY_AUTH_ROOF-1)
+#define SMF_PSK_AUTH LELEM(OAKLEY_PRESHARED_KEY)
+#define SMF_DS_AUTH (LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG) | \
+ LELEM(OAKLEY_ECDSA_SIG) | LELEM(OAKLEY_ECDSA_256) | \
+ LELEM(OAKLEY_ECDSA_384) | LELEM(OAKLEY_ECDSA_521))
+#define SMF_PKE_AUTH (LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC))
+#define SMF_RPKE_AUTH (LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV))
/* misc flags */
-#define SMF_INITIATOR LELEM(OAKLEY_AUTH_ROOF + 0)
-#define SMF_FIRST_ENCRYPTED_INPUT LELEM(OAKLEY_AUTH_ROOF + 1)
-#define SMF_INPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 2)
-#define SMF_OUTPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 3)
-#define SMF_RETRANSMIT_ON_DUPLICATE LELEM(OAKLEY_AUTH_ROOF + 4)
+#define SMF_INITIATOR LELEM(OAKLEY_AUTH_ROOF + 0)
+#define SMF_FIRST_ENCRYPTED_INPUT LELEM(OAKLEY_AUTH_ROOF + 1)
+#define SMF_INPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 2)
+#define SMF_OUTPUT_ENCRYPTED LELEM(OAKLEY_AUTH_ROOF + 3)
+#define SMF_RETRANSMIT_ON_DUPLICATE LELEM(OAKLEY_AUTH_ROOF + 4)
#define SMF_ENCRYPTED (SMF_INPUT_ENCRYPTED | SMF_OUTPUT_ENCRYPTED)
@@ -210,14 +208,14 @@ struct state_microcode {
#define SMF_REPLY LELEM(OAKLEY_AUTH_ROOF + 5)
/* this state completes P1, so any pending P2 negotiations should start */
-#define SMF_RELEASE_PENDING_P2 LELEM(OAKLEY_AUTH_ROOF + 6)
+#define SMF_RELEASE_PENDING_P2 LELEM(OAKLEY_AUTH_ROOF + 6)
/* end of flags */
-static state_transition_fn /* forward declaration */
- unexpected,
- informational;
+static state_transition_fn /* forward declaration */
+ unexpected,
+ informational;
/* state_microcode_table is a table of all state_microcode tuples.
* It must be in order of state (the first element).
@@ -228,288 +226,288 @@ static state_transition_fn /* forward declaration */
*/
static const struct state_microcode
- *ike_microcode_index[STATE_IKE_ROOF - STATE_IKE_FLOOR];
+ *ike_microcode_index[STATE_IKE_ROOF - STATE_IKE_FLOOR];
static const struct state_microcode state_microcode_table[] = {
#define PT(n) ISAKMP_NEXT_##n
#define P(n) LELEM(PT(n))
- /***** Phase 1 Main Mode *****/
-
- /* No state for main_outI1: --> HDR, SA */
-
- /* STATE_MAIN_R0: I1 --> R1
- * HDR, SA --> HDR, SA
- */
- { STATE_MAIN_R0, STATE_MAIN_R1
- , SMF_ALL_AUTH | SMF_REPLY
- , P(SA), P(VID) | P(CR), PT(NONE)
- , EVENT_RETRANSMIT, main_inI1_outR1},
-
- /* STATE_MAIN_I1: R1 --> I2
- * HDR, SA --> auth dependent
- * SMF_PSK_AUTH, SMF_DS_AUTH: --> HDR, KE, Ni
- * SMF_PKE_AUTH:
- * --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * SMF_RPKE_AUTH:
- * --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * Note: since we don't know auth at start, we cannot differentiate
- * microcode entries based on it.
- */
- { STATE_MAIN_I1, STATE_MAIN_I2
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY
- , P(SA), P(VID) | P(CR), PT(NONE) /* don't know yet */
- , EVENT_RETRANSMIT, main_inR1_outI2 },
-
- /* STATE_MAIN_R1: I2 --> R2
- * SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
- * SMF_PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * SMF_RPKE_AUTH:
- * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- */
- { STATE_MAIN_R1, STATE_MAIN_R2
- , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY
- , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(KE)
- , EVENT_RETRANSMIT, main_inI2_outR2 },
-
- { STATE_MAIN_R1, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_REPLY
- , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH), PT(KE)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- { STATE_MAIN_R1, STATE_UNDEFINED
- , SMF_RPKE_AUTH | SMF_REPLY
- , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT), PT(NONCE)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- /* for states from here on, output message must be encrypted */
-
- /* STATE_MAIN_I2: R2 --> I3
- * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
- * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
- * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * --> HDR*, HASH_I
- * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- * --> HDR*, HASH_I
- */
- { STATE_MAIN_I2, STATE_MAIN_I3
- , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
- , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(ID)
- , EVENT_RETRANSMIT, main_inR2_outI3 },
-
- { STATE_MAIN_I2, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
- , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR), PT(HASH)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- { STATE_MAIN_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
- , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR), PT(HASH)
- , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
-
- /* for states from here on, input message must be encrypted */
-
- /* STATE_MAIN_R2: I3 --> R3
- * SMF_PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
- * SMF_DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
- * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
- */
- { STATE_MAIN_R2, STATE_MAIN_R3
- , SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, main_inI3_outR3 },
-
- { STATE_MAIN_R2, STATE_MAIN_R3
- , SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
- , EVENT_SA_REPLACE, main_inI3_outR3 },
-
- { STATE_MAIN_R2, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
- | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
- /* STATE_MAIN_I3: R3 --> done
- * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done
- * SMF_DS_AUTH: HDR*, IDr1, [ CERT, ] SIG_R --> done
- * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_R --> done
- * May initiate quick mode by calling quick_outI1
- */
- { STATE_MAIN_I3, STATE_MAIN_I4
- , SMF_PSK_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, main_inR3 },
-
- { STATE_MAIN_I3, STATE_MAIN_I4
- , SMF_DS_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
- , EVENT_SA_REPLACE, main_inR3 },
-
- { STATE_MAIN_I3, STATE_UNDEFINED
- , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR
- | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(HASH), P(VID) | P(CR), PT(NONE)
- , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
-
- /* STATE_MAIN_R3: can only get here due to packet loss */
- { STATE_MAIN_R3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
- , LEMPTY, LEMPTY
- , PT(NONE), EVENT_NULL, unexpected },
-
- /* STATE_MAIN_I4: can only get here due to packet loss */
- { STATE_MAIN_I4, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED
- , LEMPTY, LEMPTY
- , PT(NONE), EVENT_NULL, unexpected },
-
-
- /***** Phase 2 Quick Mode *****/
-
- /* No state for quick_outI1:
- * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
- */
-
- /* STATE_QUICK_R0:
- * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
- * Installs inbound IPsec SAs.
- * Because it may suspend for asynchronous DNS, first_out_payload
- * is set to NONE to suppress early emission of HDR*.
- * ??? it is legal to have multiple SAs, but we don't support it yet.
- */
- { STATE_QUICK_R0, STATE_QUICK_R1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(NONE)
- , EVENT_RETRANSMIT, quick_inI1_outR1 },
-
- /* STATE_QUICK_I1:
- * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
- * HDR*, HASH(3)
- * Installs inbound and outbound IPsec SAs, routing, etc.
- * ??? it is legal to have multiple SAs, but we don't support it yet.
- */
- { STATE_QUICK_I1, STATE_QUICK_I2
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY
- , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(HASH)
- , EVENT_SA_REPLACE, quick_inR1_outI2 },
-
- /* STATE_QUICK_R1: HDR*, HASH(3) --> done
- * Installs outbound IPsec SAs, routing, etc.
- */
- { STATE_QUICK_R1, STATE_QUICK_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(HASH), LEMPTY, PT(NONE)
- , EVENT_SA_REPLACE, quick_inI2 },
-
- /* STATE_QUICK_I2: can only happen due to lost packet */
- { STATE_QUICK_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- /* STATE_QUICK_R2: can only happen due to lost packet */
- { STATE_QUICK_R2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
-
- /***** informational messages *****/
-
- /* STATE_INFO: */
- { STATE_INFO, STATE_UNDEFINED
- , SMF_ALL_AUTH
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, informational },
-
- /* STATE_INFO_PROTECTED: */
- { STATE_INFO_PROTECTED, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(HASH), LEMPTY, PT(NONE)
- , EVENT_NULL, informational },
-
- /* XAUTH state transitions */
- { STATE_XAUTH_I0, STATE_XAUTH_I1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_RETRANSMIT, xauth_inI0 },
-
- { STATE_XAUTH_R1, STATE_XAUTH_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_RETRANSMIT, xauth_inR1 },
-
- { STATE_XAUTH_I1, STATE_XAUTH_I2
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, xauth_inI1 },
-
- { STATE_XAUTH_R2, STATE_XAUTH_R3
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(NONE)
- , EVENT_SA_REPLACE, xauth_inR2 },
-
- { STATE_XAUTH_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- { STATE_XAUTH_R3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- /* ModeCfg pull mode state transitions */
-
- { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR0 },
-
- { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI1 },
-
- { STATE_MODE_CFG_R1, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
-
- { STATE_MODE_CFG_I2, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
+ /***** Phase 1 Main Mode *****/
+
+ /* No state for main_outI1: --> HDR, SA */
+
+ /* STATE_MAIN_R0: I1 --> R1
+ * HDR, SA --> HDR, SA
+ */
+ { STATE_MAIN_R0, STATE_MAIN_R1
+ , SMF_ALL_AUTH | SMF_REPLY
+ , P(SA), P(VID) | P(CR), PT(NONE)
+ , EVENT_RETRANSMIT, main_inI1_outR1},
+
+ /* STATE_MAIN_I1: R1 --> I2
+ * HDR, SA --> auth dependent
+ * SMF_PSK_AUTH, SMF_DS_AUTH: --> HDR, KE, Ni
+ * SMF_PKE_AUTH:
+ * --> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
+ * SMF_RPKE_AUTH:
+ * --> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
+ * Note: since we don't know auth at start, we cannot differentiate
+ * microcode entries based on it.
+ */
+ { STATE_MAIN_I1, STATE_MAIN_I2
+ , SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY
+ , P(SA), P(VID) | P(CR), PT(NONE) /* don't know yet */
+ , EVENT_RETRANSMIT, main_inR1_outI2 },
+
+ /* STATE_MAIN_R1: I2 --> R2
+ * SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr
+ * SMF_PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
+ * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
+ * SMF_RPKE_AUTH:
+ * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
+ * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
+ */
+ { STATE_MAIN_R1, STATE_MAIN_R2
+ , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY
+ , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(KE)
+ , EVENT_RETRANSMIT, main_inI2_outR2 },
+
+ { STATE_MAIN_R1, STATE_UNDEFINED
+ , SMF_PKE_AUTH | SMF_REPLY
+ , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH), PT(KE)
+ , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
+
+ { STATE_MAIN_R1, STATE_UNDEFINED
+ , SMF_RPKE_AUTH | SMF_REPLY
+ , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT), PT(NONCE)
+ , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
+
+ /* for states from here on, output message must be encrypted */
+
+ /* STATE_MAIN_I2: R2 --> I3
+ * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I
+ * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I
+ * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
+ * --> HDR*, HASH_I
+ * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
+ * --> HDR*, HASH_I
+ */
+ { STATE_MAIN_I2, STATE_MAIN_I3
+ , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
+ , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(ID)
+ , EVENT_RETRANSMIT, main_inR2_outI3 },
+
+ { STATE_MAIN_I2, STATE_UNDEFINED
+ , SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
+ , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR), PT(HASH)
+ , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
+
+ { STATE_MAIN_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY
+ , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR), PT(HASH)
+ , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },
+
+ /* for states from here on, input message must be encrypted */
+
+ /* STATE_MAIN_R2: I3 --> R3
+ * SMF_PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R
+ * SMF_DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R
+ * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R
+ */
+ { STATE_MAIN_R2, STATE_MAIN_R3
+ , SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
+ | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
+ , EVENT_SA_REPLACE, main_inI3_outR3 },
+
+ { STATE_MAIN_R2, STATE_MAIN_R3
+ , SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
+ | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
+ , EVENT_SA_REPLACE, main_inI3_outR3 },
+
+ { STATE_MAIN_R2, STATE_UNDEFINED
+ , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED
+ | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(HASH), P(VID) | P(CR), PT(NONE)
+ , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
+
+ /* STATE_MAIN_I3: R3 --> done
+ * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done
+ * SMF_DS_AUTH: HDR*, IDr1, [ CERT, ] SIG_R --> done
+ * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_R --> done
+ * May initiate quick mode by calling quick_outI1
+ */
+ { STATE_MAIN_I3, STATE_MAIN_I4
+ , SMF_PSK_AUTH | SMF_INITIATOR
+ | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)
+ , EVENT_SA_REPLACE, main_inR3 },
+
+ { STATE_MAIN_I3, STATE_MAIN_I4
+ , SMF_DS_AUTH | SMF_INITIATOR
+ | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)
+ , EVENT_SA_REPLACE, main_inR3 },
+
+ { STATE_MAIN_I3, STATE_UNDEFINED
+ , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR
+ | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(HASH), P(VID) | P(CR), PT(NONE)
+ , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },
+
+ /* STATE_MAIN_R3: can only get here due to packet loss */
+ { STATE_MAIN_R3, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
+ , LEMPTY, LEMPTY
+ , PT(NONE), EVENT_NULL, unexpected },
+
+ /* STATE_MAIN_I4: can only get here due to packet loss */
+ { STATE_MAIN_I4, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY
+ , PT(NONE), EVENT_NULL, unexpected },
+
+
+ /***** Phase 2 Quick Mode *****/
+
+ /* No state for quick_outI1:
+ * --> HDR*, HASH(1), SA, Nr [, KE ] [, IDci, IDcr ]
+ */
+
+ /* STATE_QUICK_R0:
+ * HDR*, HASH(1), SA, Ni [, KE ] [, IDci, IDcr ] -->
+ * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ]
+ * Installs inbound IPsec SAs.
+ * Because it may suspend for asynchronous DNS, first_out_payload
+ * is set to NONE to suppress early emission of HDR*.
+ * ??? it is legal to have multiple SAs, but we don't support it yet.
+ */
+ { STATE_QUICK_R0, STATE_QUICK_R1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
+ , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(NONE)
+ , EVENT_RETRANSMIT, quick_inI1_outR1 },
+
+ /* STATE_QUICK_I1:
+ * HDR*, HASH(2), SA, Nr [, KE ] [, IDci, IDcr ] -->
+ * HDR*, HASH(3)
+ * Installs inbound and outbound IPsec SAs, routing, etc.
+ * ??? it is legal to have multiple SAs, but we don't support it yet.
+ */
+ { STATE_QUICK_I1, STATE_QUICK_I2
+ , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_REPLY
+ , P(HASH) | P(SA) | P(NONCE), /* P(SA) | */ P(KE) | P(ID) | P(NATOA_RFC), PT(HASH)
+ , EVENT_SA_REPLACE, quick_inR1_outI2 },
+
+ /* STATE_QUICK_R1: HDR*, HASH(3) --> done
+ * Installs outbound IPsec SAs, routing, etc.
+ */
+ { STATE_QUICK_R1, STATE_QUICK_R2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , P(HASH), LEMPTY, PT(NONE)
+ , EVENT_SA_REPLACE, quick_inI2 },
+
+ /* STATE_QUICK_I2: can only happen due to lost packet */
+ { STATE_QUICK_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ /* STATE_QUICK_R2: can only happen due to lost packet */
+ { STATE_QUICK_R2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+
+ /***** informational messages *****/
+
+ /* STATE_INFO: */
+ { STATE_INFO, STATE_UNDEFINED
+ , SMF_ALL_AUTH
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, informational },
+
+ /* STATE_INFO_PROTECTED: */
+ { STATE_INFO_PROTECTED, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , P(HASH), LEMPTY, PT(NONE)
+ , EVENT_NULL, informational },
+
+ /* XAUTH state transitions */
+ { STATE_XAUTH_I0, STATE_XAUTH_I1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_RETRANSMIT, xauth_inI0 },
+
+ { STATE_XAUTH_R1, STATE_XAUTH_R2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_RETRANSMIT, xauth_inR1 },
+
+ { STATE_XAUTH_I1, STATE_XAUTH_I2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, xauth_inI1 },
+
+ { STATE_XAUTH_R2, STATE_XAUTH_R3
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(NONE)
+ , EVENT_SA_REPLACE, xauth_inR2 },
+
+ { STATE_XAUTH_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ { STATE_XAUTH_R3, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ /* ModeCfg pull mode state transitions */
+
+ { STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inR0 },
+
+ { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inI1 },
+
+ { STATE_MODE_CFG_R1, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ { STATE_MODE_CFG_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
/* ModeCfg push mode state transitions */
- { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI0 },
+ { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inI0 },
- { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR3 },
+ { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inR3 },
- { STATE_MODE_CFG_I3, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
+ { STATE_MODE_CFG_I3, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
- { STATE_MODE_CFG_R4, STATE_UNDEFINED
- , SMF_ALL_AUTH | SMF_ENCRYPTED
- , LEMPTY, LEMPTY, PT(NONE)
- , EVENT_NULL, unexpected },
+ { STATE_MODE_CFG_R4, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
#undef P
#undef PT
@@ -518,23 +516,23 @@ static const struct state_microcode state_microcode_table[] = {
void
init_demux(void)
{
- /* fill ike_microcode_index:
- * make ike_microcode_index[s] point to first entry in
- * state_microcode_table for state s (backward scan makes this easier).
- * Check that table is in order -- catch coding errors.
- * For what it's worth, this routine is idempotent.
- */
- const struct state_microcode *t;
-
- for (t = &state_microcode_table[elemsof(state_microcode_table) - 1];;)
- {
- passert(STATE_IKE_FLOOR <= t->state && t->state < STATE_IKE_ROOF);
- ike_microcode_index[t->state - STATE_IKE_FLOOR] = t;
- if (t == state_microcode_table)
- break;
- t--;
- passert(t[0].state <= t[1].state);
- }
+ /* fill ike_microcode_index:
+ * make ike_microcode_index[s] point to first entry in
+ * state_microcode_table for state s (backward scan makes this easier).
+ * Check that table is in order -- catch coding errors.
+ * For what it's worth, this routine is idempotent.
+ */
+ const struct state_microcode *t;
+
+ for (t = &state_microcode_table[countof(state_microcode_table) - 1];;)
+ {
+ passert(STATE_IKE_FLOOR <= t->state && t->state < STATE_IKE_ROOF);
+ ike_microcode_index[t->state - STATE_IKE_FLOOR] = t;
+ if (t == state_microcode_table)
+ break;
+ t--;
+ passert(t[0].state <= t[1].state);
+ }
}
/* Process any message on the MSG_ERRQUEUE
@@ -586,357 +584,357 @@ init_demux(void)
static bool
check_msg_errqueue(const struct iface *ifp, short interest)
{
- struct pollfd pfd;
+ struct pollfd pfd;
- pfd.fd = ifp->fd;
- pfd.events = interest | POLLPRI | POLLOUT;
+ pfd.fd = ifp->fd;
+ pfd.events = interest | POLLPRI | POLLOUT;
- while (pfd.revents = 0
- , poll(&pfd, 1, -1) > 0 && (pfd.revents & POLLERR))
- {
- u_int8_t buffer[3000]; /* hope that this is big enough */
- union
+ while (pfd.revents = 0
+ , poll(&pfd, 1, -1) > 0 && (pfd.revents & POLLERR))
{
- struct sockaddr sa;
- struct sockaddr_in sa_in4;
- struct sockaddr_in6 sa_in6;
- } from;
+ u_int8_t buffer[3000]; /* hope that this is big enough */
+ union
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sa_in4;
+ struct sockaddr_in6 sa_in6;
+ } from;
- int from_len = sizeof(from);
+ int from_len = sizeof(from);
- int packet_len;
+ int packet_len;
- struct msghdr emh;
- struct iovec eiov;
- union {
- /* force alignment (not documented as necessary) */
- struct cmsghdr ecms;
+ struct msghdr emh;
+ struct iovec eiov;
+ union {
+ /* force alignment (not documented as necessary) */
+ struct cmsghdr ecms;
- /* how much space is enough? */
- unsigned char space[256];
- } ecms_buf;
+ /* how much space is enough? */
+ unsigned char space[256];
+ } ecms_buf;
- struct cmsghdr *cm;
- char fromstr[sizeof(" for message to port 65536") + INET6_ADDRSTRLEN];
- struct state *sender = NULL;
+ struct cmsghdr *cm;
+ char fromstr[sizeof(" for message to port 65536") + INET6_ADDRSTRLEN];
+ struct state *sender = NULL;
- zero(&from.sa);
- from_len = sizeof(from);
+ zero(&from.sa);
+ from_len = sizeof(from);
- emh.msg_name = &from.sa; /* ??? filled in? */
- emh.msg_namelen = sizeof(from);
- emh.msg_iov = &eiov;
- emh.msg_iovlen = 1;
- emh.msg_control = &ecms_buf;
- emh.msg_controllen = sizeof(ecms_buf);
- emh.msg_flags = 0;
+ emh.msg_name = &from.sa; /* ??? filled in? */
+ emh.msg_namelen = sizeof(from);
+ emh.msg_iov = &eiov;
+ emh.msg_iovlen = 1;
+ emh.msg_control = &ecms_buf;
+ emh.msg_controllen = sizeof(ecms_buf);
+ emh.msg_flags = 0;
- eiov.iov_base = buffer; /* see readv(2) */
- eiov.iov_len = sizeof(buffer);
+ eiov.iov_base = buffer; /* see readv(2) */
+ eiov.iov_len = sizeof(buffer);
- packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUE);
+ packet_len = recvmsg(ifp->fd, &emh, MSG_ERRQUEUE);
- if (packet_len == -1)
- {
- log_errno((e, "recvmsg(,, MSG_ERRQUEUE) on %s failed in comm_handle"
- , ifp->rname));
- break;
- }
- else if (packet_len == sizeof(buffer))
- {
- plog("MSG_ERRQUEUE message longer than %lu bytes; truncated"
- , (unsigned long) sizeof(buffer));
- }
- else
- {
- sender = find_sender((size_t) packet_len, buffer);
- }
-
- DBG_cond_dump(DBG_ALL, "rejected packet:\n", buffer, packet_len);
- DBG_cond_dump(DBG_ALL, "control:\n", emh.msg_control, emh.msg_controllen);
- /* ??? Andi Kleen <ak@suse.de> and misc documentation
- * suggests that name will have the original destination
- * of the packet. We seem to see msg_namelen == 0.
- * Andi says that this is a kernel bug and has fixed it.
- * Perhaps in 2.2.18/2.4.0.
- */
- passert(emh.msg_name == &from.sa);
- DBG_cond_dump(DBG_ALL, "name:\n", emh.msg_name
- , emh.msg_namelen);
-
- fromstr[0] = '\0'; /* usual case :-( */
- switch (from.sa.sa_family)
- {
- char as[INET6_ADDRSTRLEN];
-
- case AF_INET:
- if (emh.msg_namelen == sizeof(struct sockaddr_in))
- snprintf(fromstr, sizeof(fromstr)
- , " for message to %s port %u"
- , inet_ntop(from.sa.sa_family
- , &from.sa_in4.sin_addr, as, sizeof(as))
- , ntohs(from.sa_in4.sin_port));
- break;
- case AF_INET6:
- if (emh.msg_namelen == sizeof(struct sockaddr_in6))
- snprintf(fromstr, sizeof(fromstr)
- , " for message to %s port %u"
- , inet_ntop(from.sa.sa_family
- , &from.sa_in6.sin6_addr, as, sizeof(as))
- , ntohs(from.sa_in6.sin6_port));
- break;
- }
-
- for (cm = CMSG_FIRSTHDR(&emh)
- ; cm != NULL
- ; cm = CMSG_NXTHDR(&emh,cm))
- {
- if (cm->cmsg_level == SOL_IP
- && cm->cmsg_type == IP_RECVERR)
- {
- /* ip(7) and recvmsg(2) specify:
- * ee_origin is SO_EE_ORIGIN_ICMP for ICMP
- * or SO_EE_ORIGIN_LOCAL for locally generated errors.
- * ee_type and ee_code are from the ICMP header.
- * ee_info is the discovered MTU for EMSGSIZE errors
- * ee_data is not used.
- *
- * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but
- * means "SO_EE_OFFENDER". The OFFENDER is really
- * the router that complained. As such, the port
- * is meaningless.
- */
+ if (packet_len == -1)
+ {
+ log_errno((e, "recvmsg(,, MSG_ERRQUEUE) on %s failed in comm_handle"
+ , ifp->rname));
+ break;
+ }
+ else if (packet_len == sizeof(buffer))
+ {
+ plog("MSG_ERRQUEUE message longer than %lu bytes; truncated"
+ , (unsigned long) sizeof(buffer));
+ }
+ else
+ {
+ sender = find_sender((size_t) packet_len, buffer);
+ }
- /* ??? cmsg(3) claims that CMSG_DATA returns
- * void *, but RFC 2292 and /usr/include/bits/socket.h
- * say unsigned char *. The manual is being fixed.
+ DBG_cond_dump(DBG_ALL, "rejected packet:\n", buffer, packet_len);
+ DBG_cond_dump(DBG_ALL, "control:\n", emh.msg_control, emh.msg_controllen);
+ /* ??? Andi Kleen <ak@suse.de> and misc documentation
+ * suggests that name will have the original destination
+ * of the packet. We seem to see msg_namelen == 0.
+ * Andi says that this is a kernel bug and has fixed it.
+ * Perhaps in 2.2.18/2.4.0.
*/
- struct sock_extended_err *ee = (void *)CMSG_DATA(cm);
- const char *offstr = "unspecified";
- char offstrspace[INET6_ADDRSTRLEN];
- char orname[50];
+ passert(emh.msg_name == &from.sa);
+ DBG_cond_dump(DBG_ALL, "name:\n", emh.msg_name
+ , emh.msg_namelen);
- if (cm->cmsg_len > CMSG_LEN(sizeof(struct sock_extended_err)))
+ fromstr[0] = '\0'; /* usual case :-( */
+ switch (from.sa.sa_family)
{
- const struct sockaddr *offender = SO_EE_OFFENDER(ee);
-
- switch (offender->sa_family)
- {
- case AF_INET:
- offstr = inet_ntop(offender->sa_family
- , &((const struct sockaddr_in *)offender)->sin_addr
- , offstrspace, sizeof(offstrspace));
- break;
- case AF_INET6:
- offstr = inet_ntop(offender->sa_family
- , &((const struct sockaddr_in6 *)offender)->sin6_addr
- , offstrspace, sizeof(offstrspace));
+ char as[INET6_ADDRSTRLEN];
+
+ case AF_INET:
+ if (emh.msg_namelen == sizeof(struct sockaddr_in))
+ snprintf(fromstr, sizeof(fromstr)
+ , " for message to %s port %u"
+ , inet_ntop(from.sa.sa_family
+ , &from.sa_in4.sin_addr, as, sizeof(as))
+ , ntohs(from.sa_in4.sin_port));
break;
- default:
- offstr = "unknown";
+ case AF_INET6:
+ if (emh.msg_namelen == sizeof(struct sockaddr_in6))
+ snprintf(fromstr, sizeof(fromstr)
+ , " for message to %s port %u"
+ , inet_ntop(from.sa.sa_family
+ , &from.sa_in6.sin6_addr, as, sizeof(as))
+ , ntohs(from.sa_in6.sin6_port));
break;
- }
}
- switch (ee->ee_origin)
+ for (cm = CMSG_FIRSTHDR(&emh)
+ ; cm != NULL
+ ; cm = CMSG_NXTHDR(&emh,cm))
{
- case SO_EE_ORIGIN_NONE:
- snprintf(orname, sizeof(orname), "none");
- break;
- case SO_EE_ORIGIN_LOCAL:
- snprintf(orname, sizeof(orname), "local");
- break;
- case SO_EE_ORIGIN_ICMP:
- snprintf(orname, sizeof(orname)
- , "ICMP type %d code %d (not authenticated)"
- , ee->ee_type, ee->ee_code
- );
- break;
- case SO_EE_ORIGIN_ICMP6:
- snprintf(orname, sizeof(orname)
- , "ICMP6 type %d code %d (not authenticated)"
- , ee->ee_type, ee->ee_code
- );
- break;
- default:
- snprintf(orname, sizeof(orname), "invalid origin %lu"
- , (unsigned long) ee->ee_origin);
- break;
- }
-
- {
- struct state *old_state = cur_state;
-
- cur_state = sender;
-
- /* note dirty trick to suppress ~ at start of format
- * if we know what state to blame.
- */
- if ((packet_len == 1) && (buffer[0] = 0xff)
+ if (cm->cmsg_level == SOL_IP
+ && cm->cmsg_type == IP_RECVERR)
+ {
+ /* ip(7) and recvmsg(2) specify:
+ * ee_origin is SO_EE_ORIGIN_ICMP for ICMP
+ * or SO_EE_ORIGIN_LOCAL for locally generated errors.
+ * ee_type and ee_code are from the ICMP header.
+ * ee_info is the discovered MTU for EMSGSIZE errors
+ * ee_data is not used.
+ *
+ * ??? recvmsg(2) says "SOCK_EE_OFFENDER" but
+ * means "SO_EE_OFFENDER". The OFFENDER is really
+ * the router that complained. As such, the port
+ * is meaningless.
+ */
+
+ /* ??? cmsg(3) claims that CMSG_DATA returns
+ * void *, but RFC 2292 and /usr/include/bits/socket.h
+ * say unsigned char *. The manual is being fixed.
+ */
+ struct sock_extended_err *ee = (void *)CMSG_DATA(cm);
+ const char *offstr = "unspecified";
+ char offstrspace[INET6_ADDRSTRLEN];
+ char orname[50];
+
+ if (cm->cmsg_len > CMSG_LEN(sizeof(struct sock_extended_err)))
+ {
+ const struct sockaddr *offender = SO_EE_OFFENDER(ee);
+
+ switch (offender->sa_family)
+ {
+ case AF_INET:
+ offstr = inet_ntop(offender->sa_family
+ , &((const struct sockaddr_in *)offender)->sin_addr
+ , offstrspace, sizeof(offstrspace));
+ break;
+ case AF_INET6:
+ offstr = inet_ntop(offender->sa_family
+ , &((const struct sockaddr_in6 *)offender)->sin6_addr
+ , offstrspace, sizeof(offstrspace));
+ break;
+ default:
+ offstr = "unknown";
+ break;
+ }
+ }
+
+ switch (ee->ee_origin)
+ {
+ case SO_EE_ORIGIN_NONE:
+ snprintf(orname, sizeof(orname), "none");
+ break;
+ case SO_EE_ORIGIN_LOCAL:
+ snprintf(orname, sizeof(orname), "local");
+ break;
+ case SO_EE_ORIGIN_ICMP:
+ snprintf(orname, sizeof(orname)
+ , "ICMP type %d code %d (not authenticated)"
+ , ee->ee_type, ee->ee_code
+ );
+ break;
+ case SO_EE_ORIGIN_ICMP6:
+ snprintf(orname, sizeof(orname)
+ , "ICMP6 type %d code %d (not authenticated)"
+ , ee->ee_type, ee->ee_code
+ );
+ break;
+ default:
+ snprintf(orname, sizeof(orname), "invalid origin %lu"
+ , (unsigned long) ee->ee_origin);
+ break;
+ }
+
+ {
+ struct state *old_state = cur_state;
+
+ cur_state = sender;
+
+ /* note dirty trick to suppress ~ at start of format
+ * if we know what state to blame.
+ */
+ if ((packet_len == 1) && (buffer[0] = 0xff)
#ifdef DEBUG
- && ((cur_debugging & DBG_NATT) == 0)
+ && ((cur_debugging & DBG_NATT) == 0)
#endif
- ) {
- /* don't log NAT-T keepalive related errors unless NATT debug is
- * enabled
- */
- }
- else
- plog((sender != NULL) + "~"
- "ERROR: asynchronous network error report on %s"
- "%s"
- ", complainant %s"
- ": %s"
- " [errno %lu, origin %s"
- /* ", pad %d, info %ld" */
- /* ", data %ld" */
- "]"
- , ifp->rname
- , fromstr
- , offstr
- , strerror(ee->ee_errno)
- , (unsigned long) ee->ee_errno
- , orname
- /* , ee->ee_pad, (unsigned long)ee->ee_info */
- /* , (unsigned long)ee->ee_data */
- );
- cur_state = old_state;
+ ) {
+ /* don't log NAT-T keepalive related errors unless NATT debug is
+ * enabled
+ */
+ }
+ else
+ plog((sender != NULL) + "~"
+ "ERROR: asynchronous network error report on %s"
+ "%s"
+ ", complainant %s"
+ ": %s"
+ " [errno %lu, origin %s"
+ /* ", pad %d, info %ld" */
+ /* ", data %ld" */
+ "]"
+ , ifp->rname
+ , fromstr
+ , offstr
+ , strerror(ee->ee_errno)
+ , (unsigned long) ee->ee_errno
+ , orname
+ /* , ee->ee_pad, (unsigned long)ee->ee_info */
+ /* , (unsigned long)ee->ee_data */
+ );
+ cur_state = old_state;
+ }
+ }
+ else
+ {
+ /* .cmsg_len is a kernel_size_t(!), but the value
+ * certainly ought to fit in an unsigned long.
+ */
+ plog("unknown cmsg: level %d, type %d, len %lu"
+ , cm->cmsg_level, cm->cmsg_type
+ , (unsigned long) cm->cmsg_len);
+ }
}
- }
- else
- {
- /* .cmsg_len is a kernel_size_t(!), but the value
- * certainly ought to fit in an unsigned long.
- */
- plog("unknown cmsg: level %d, type %d, len %lu"
- , cm->cmsg_level, cm->cmsg_type
- , (unsigned long) cm->cmsg_len);
- }
}
- }
- return (pfd.revents & interest) != 0;
+ return (pfd.revents & interest) != 0;
}
#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
bool
send_packet(struct state *st, const char *where)
{
- struct connection *c = st->st_connection;
- int port_buf;
- bool err;
- u_int8_t ike_pkt[MAX_OUTPUT_UDP_SIZE];
- u_int8_t *ptr;
- unsigned long len;
-
- if (c->interface->ike_float && st->st_tpacket.len != 1)
- {
- if ((unsigned long) st->st_tpacket.len > (MAX_OUTPUT_UDP_SIZE-sizeof(u_int32_t)))
+ struct connection *c = st->st_connection;
+ int port_buf;
+ bool err;
+ u_int8_t ike_pkt[MAX_OUTPUT_UDP_SIZE];
+ u_int8_t *ptr;
+ unsigned long len;
+
+ if (c->interface->ike_float && st->st_tpacket.len != 1)
{
- DBG_log("send_packet(): really too big");
- return FALSE;
+ if ((unsigned long) st->st_tpacket.len > (MAX_OUTPUT_UDP_SIZE-sizeof(u_int32_t)))
+ {
+ DBG_log("send_packet(): really too big");
+ return FALSE;
+ }
+ ptr = ike_pkt;
+ /** Add Non-ESP marker **/
+ memset(ike_pkt, 0, sizeof(u_int32_t));
+ memcpy(ike_pkt + sizeof(u_int32_t), st->st_tpacket.ptr,
+ (unsigned long)st->st_tpacket.len);
+ len = (unsigned long) st->st_tpacket.len + sizeof(u_int32_t);
}
- ptr = ike_pkt;
- /** Add Non-ESP marker **/
- memset(ike_pkt, 0, sizeof(u_int32_t));
- memcpy(ike_pkt + sizeof(u_int32_t), st->st_tpacket.ptr,
- (unsigned long)st->st_tpacket.len);
- len = (unsigned long) st->st_tpacket.len + sizeof(u_int32_t);
- }
- else
- {
- ptr = st->st_tpacket.ptr;
- len = (unsigned long) st->st_tpacket.len;
- }
-
- DBG(DBG_RAW,
+ else
{
- DBG_log("sending %lu bytes for %s through %s to %s:%u:"
- , (unsigned long) st->st_tpacket.len
- , where
- , c->interface->rname
- , ip_str(&c->spd.that.host_addr)
- , (unsigned)c->spd.that.host_port);
- DBG_dump_chunk(NULL, st->st_tpacket);
- });
-
- /* XXX: Not very clean. We manipulate the port of the ip_address to
- * have a port in the sockaddr*, but we retain the original port
- * and restore it afterwards.
- */
-
- port_buf = portof(&c->spd.that.host_addr);
- setportof(htons(c->spd.that.host_port), &c->spd.that.host_addr);
+ ptr = st->st_tpacket.ptr;
+ len = (unsigned long) st->st_tpacket.len;
+ }
+
+ DBG(DBG_RAW,
+ {
+ DBG_log("sending %lu bytes for %s through %s to %s:%u:"
+ , (unsigned long) st->st_tpacket.len
+ , where
+ , c->interface->rname
+ , ip_str(&c->spd.that.host_addr)
+ , (unsigned)c->spd.that.host_port);
+ DBG_dump_chunk(NULL, st->st_tpacket);
+ });
+
+ /* XXX: Not very clean. We manipulate the port of the ip_address to
+ * have a port in the sockaddr*, but we retain the original port
+ * and restore it afterwards.
+ */
+
+ port_buf = portof(&c->spd.that.host_addr);
+ setportof(htons(c->spd.that.host_port), &c->spd.that.host_addr);
#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- (void) check_msg_errqueue(c->interface, POLLOUT);
+ (void) check_msg_errqueue(c->interface, POLLOUT);
#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
- err = sendto(c->interface->fd
- , ptr, len, 0
- , sockaddrof(&c->spd.that.host_addr)
- , sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)len;
-
- /* restore port */
- setportof(port_buf, &c->spd.that.host_addr);
-
- if (err)
- {
- /* do not log NAT-T Keep Alive packets */
- if (streq(where, "NAT-T Keep Alive"))
- return FALSE;
- log_errno((e, "sendto on %s to %s:%u failed in %s"
- , c->interface->rname
- , ip_str(&c->spd.that.host_addr)
- , (unsigned)c->spd.that.host_port
- , where));
- return FALSE;
- }
- else
- {
- return TRUE;
- }
+ err = sendto(c->interface->fd
+ , ptr, len, 0
+ , sockaddrof(&c->spd.that.host_addr)
+ , sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)len;
+
+ /* restore port */
+ setportof(port_buf, &c->spd.that.host_addr);
+
+ if (err)
+ {
+ /* do not log NAT-T Keep Alive packets */
+ if (streq(where, "NAT-T Keep Alive"))
+ return FALSE;
+ log_errno((e, "sendto on %s to %s:%u failed in %s"
+ , c->interface->rname
+ , ip_str(&c->spd.that.host_addr)
+ , (unsigned)c->spd.that.host_port
+ , where));
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
}
static stf_status
unexpected(struct msg_digest *md)
{
- loglog(RC_LOG_SERIOUS, "unexpected message received in state %s"
- , enum_name(&state_names, md->st->st_state));
- return STF_IGNORE;
+ loglog(RC_LOG_SERIOUS, "unexpected message received in state %s"
+ , enum_name(&state_names, md->st->st_state));
+ return STF_IGNORE;
}
static stf_status
informational(struct msg_digest *md UNUSED)
{
- struct payload_digest *const n_pld = md->chain[ISAKMP_NEXT_N];
-
- /* If the Notification Payload is not null... */
- if (n_pld != NULL)
- {
- pb_stream *const n_pbs = &n_pld->pbs;
- struct isakmp_notification *const n = &n_pld->payload.notification;
- int disp_len;
- char disp_buf[200];
-
- /* Switch on Notification Type (enum) */
- switch (n->isan_type)
- {
- case R_U_THERE:
- return dpd_inI_outR(md->st, n, n_pbs);
-
- case R_U_THERE_ACK:
- return dpd_inR(md->st, n, n_pbs);
- default:
- if (pbs_left(n_pbs) >= sizeof(disp_buf)-1)
- disp_len = sizeof(disp_buf)-1;
- else
- disp_len = pbs_left(n_pbs);
- memcpy(disp_buf, n_pbs->cur, disp_len);
- disp_buf[disp_len] = '\0';
- break;
- }
- }
- return STF_IGNORE;
+ struct payload_digest *const n_pld = md->chain[ISAKMP_NEXT_N];
+
+ /* If the Notification Payload is not null... */
+ if (n_pld != NULL)
+ {
+ pb_stream *const n_pbs = &n_pld->pbs;
+ struct isakmp_notification *const n = &n_pld->payload.notification;
+ int disp_len;
+ char disp_buf[200];
+
+ /* Switch on Notification Type (enum) */
+ switch (n->isan_type)
+ {
+ case R_U_THERE:
+ return dpd_inI_outR(md->st, n, n_pbs);
+
+ case R_U_THERE_ACK:
+ return dpd_inR(md->st, n, n_pbs);
+ default:
+ if (pbs_left(n_pbs) >= sizeof(disp_buf)-1)
+ disp_len = sizeof(disp_buf)-1;
+ else
+ disp_len = pbs_left(n_pbs);
+ memcpy(disp_buf, n_pbs->cur, disp_len);
+ disp_buf[disp_len] = '\0';
+ break;
+ }
+ }
+ return STF_IGNORE;
}
/* message digest allocation and deallocation */
@@ -947,54 +945,57 @@ static struct msg_digest *md_pool = NULL;
void
free_md_pool(void)
{
- for (;;)
- {
- struct msg_digest *md = md_pool;
+ for (;;)
+ {
+ struct msg_digest *md = md_pool;
- if (md == NULL)
- break;
- md_pool = md->next;
- pfree(md);
- }
+ if (md == NULL)
+ break;
+ md_pool = md->next;
+ free(md);
+ }
}
static struct msg_digest *
-alloc_md(void)
+malloc_md(void)
{
- struct msg_digest *md = md_pool;
-
- /* convenient initializer:
- * - all pointers NULL
- * - .note = NOTHING_WRONG
- * - .encrypted = FALSE
- */
- static const struct msg_digest blank_md;
-
- if (md == NULL)
- md = alloc_thing(struct msg_digest, "msg_digest");
- else
- md_pool = md->next;
-
- *md = blank_md;
- md->digest_roof = md->digest;
-
- /* note: although there may be multiple msg_digests at once
- * (due to suspended state transitions), there is a single
- * global reply_buffer. It will need to be saved and restored.
- */
- init_pbs(&md->reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
- return md;
+ struct msg_digest *md = md_pool;
+
+ /* convenient initializer:
+ * - all pointers NULL
+ * - .note = NOTHING_WRONG
+ * - .encrypted = FALSE
+ */
+ static const struct msg_digest blank_md;
+
+ if (md == NULL)
+ {
+ md = malloc_thing(struct msg_digest);
+ zero(md);
+ }
+ else
+ md_pool = md->next;
+
+ *md = blank_md;
+ md->digest_roof = md->digest;
+
+ /* note: although there may be multiple msg_digests at once
+ * (due to suspended state transitions), there is a single
+ * global reply_buffer. It will need to be saved and restored.
+ */
+ init_pbs(&md->reply, reply_buffer, sizeof(reply_buffer), "reply packet");
+
+ return md;
}
void
release_md(struct msg_digest *md)
{
- freeanychunk(md->raw_packet);
- pfreeany(md->packet_pbs.start);
- md->packet_pbs.start = NULL;
- md->next = md_pool;
- md_pool = md;
+ chunk_free(&md->raw_packet);
+ free(md->packet_pbs.start);
+ md->packet_pbs.start = NULL;
+ md->next = md_pool;
+ md_pool = md;
}
/* wrapper for read_packet and process_packet
@@ -1013,35 +1014,35 @@ release_md(struct msg_digest *md)
void
comm_handle(const struct iface *ifp)
{
- static struct msg_digest *md;
+ static struct msg_digest *md;
#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- /* Even though select(2) says that there is a message,
- * it might only be a MSG_ERRQUEUE message. At least
- * sometimes that leads to a hanging recvfrom. To avoid
- * what appears to be a kernel bug, check_msg_errqueue
- * uses poll(2) and tells us if there is anything for us
- * to read.
- *
- * This is early enough that teardown isn't required:
- * just return on failure.
- */
- if (!check_msg_errqueue(ifp, POLLIN))
- return; /* no normal message to read */
+ /* Even though select(2) says that there is a message,
+ * it might only be a MSG_ERRQUEUE message. At least
+ * sometimes that leads to a hanging recvfrom. To avoid
+ * what appears to be a kernel bug, check_msg_errqueue
+ * uses poll(2) and tells us if there is anything for us
+ * to read.
+ *
+ * This is early enough that teardown isn't required:
+ * just return on failure.
+ */
+ if (!check_msg_errqueue(ifp, POLLIN))
+ return; /* no normal message to read */
#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */
- md = alloc_md();
- md->iface = ifp;
+ md = malloc_md();
+ md->iface = ifp;
- if (read_packet(md))
- process_packet(&md);
+ if (read_packet(md))
+ process_packet(&md);
- if (md != NULL)
- release_md(md);
+ if (md != NULL)
+ release_md(md);
- cur_state = NULL;
- reset_cur_connection();
- cur_from = NULL;
+ cur_state = NULL;
+ reset_cur_connection();
+ cur_from = NULL;
}
/* read the message.
@@ -1052,177 +1053,177 @@ comm_handle(const struct iface *ifp)
static bool
read_packet(struct msg_digest *md)
{
- const struct iface *ifp = md->iface;
- int packet_len;
- u_int8_t *buffer;
- u_int8_t *buffer_nat;
- union
- {
- struct sockaddr sa;
- struct sockaddr_in sa_in4;
- struct sockaddr_in6 sa_in6;
- } from;
- int from_len = sizeof(from);
- err_t from_ugh = NULL;
- static const char undisclosed[] = "unknown source";
-
- happy(anyaddr(addrtypeof(&ifp->addr), &md->sender));
- zero(&from.sa);
- ioctl(ifp->fd, FIONREAD, &packet_len);
- buffer = alloc_bytes(packet_len, "buffer read packet");
- packet_len = recvfrom(ifp->fd, buffer, packet_len, 0
- , &from.sa, &from_len);
-
- /* First: digest the from address.
- * We presume that nothing here disturbs errno.
- */
- if (packet_len == -1
- && from_len == sizeof(from)
- && all_zero((const void *)&from.sa, sizeof(from)))
- {
- /* "from" is untouched -- not set by recvfrom */
- from_ugh = undisclosed;
- }
- else if (from_len
- < (int) (offsetof(struct sockaddr, sa_family) + sizeof(from.sa.sa_family)))
- {
- from_ugh = "truncated";
- }
- else
- {
- const struct af_info *afi = aftoinfo(from.sa.sa_family);
-
- if (afi == NULL)
+ const struct iface *ifp = md->iface;
+ int packet_len;
+ u_int8_t *buffer;
+ u_int8_t *buffer_nat;
+ union
{
- from_ugh = "unexpected Address Family";
+ struct sockaddr sa;
+ struct sockaddr_in sa_in4;
+ struct sockaddr_in6 sa_in6;
+ } from;
+ int from_len = sizeof(from);
+ err_t from_ugh = NULL;
+ static const char undisclosed[] = "unknown source";
+
+ happy(anyaddr(addrtypeof(&ifp->addr), &md->sender));
+ zero(&from.sa);
+ ioctl(ifp->fd, FIONREAD, &packet_len);
+ buffer = malloc(packet_len);
+ packet_len = recvfrom(ifp->fd, buffer, packet_len, 0
+ , &from.sa, &from_len);
+
+ /* First: digest the from address.
+ * We presume that nothing here disturbs errno.
+ */
+ if (packet_len == -1
+ && from_len == sizeof(from)
+ && all_zero((const void *)&from.sa, sizeof(from)))
+ {
+ /* "from" is untouched -- not set by recvfrom */
+ from_ugh = undisclosed;
}
- else if (from_len != (int)afi->sa_sz)
+ else if (from_len
+ < (int) (offsetof(struct sockaddr, sa_family) + sizeof(from.sa.sa_family)))
{
- from_ugh = "wrong length";
+ from_ugh = "truncated";
}
else
{
- switch (from.sa.sa_family)
- {
- case AF_INET:
- from_ugh = initaddr((void *) &from.sa_in4.sin_addr
- , sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender);
- md->sender_port = ntohs(from.sa_in4.sin_port);
- break;
- case AF_INET6:
- from_ugh = initaddr((void *) &from.sa_in6.sin6_addr
- , sizeof(from.sa_in6.sin6_addr), AF_INET6, &md->sender);
- md->sender_port = ntohs(from.sa_in6.sin6_port);
- break;
- }
+ const struct af_info *afi = aftoinfo(from.sa.sa_family);
+
+ if (afi == NULL)
+ {
+ from_ugh = "unexpected Address Family";
+ }
+ else if (from_len != (int)afi->sa_sz)
+ {
+ from_ugh = "wrong length";
+ }
+ else
+ {
+ switch (from.sa.sa_family)
+ {
+ case AF_INET:
+ from_ugh = initaddr((void *) &from.sa_in4.sin_addr
+ , sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender);
+ md->sender_port = ntohs(from.sa_in4.sin_port);
+ break;
+ case AF_INET6:
+ from_ugh = initaddr((void *) &from.sa_in6.sin6_addr
+ , sizeof(from.sa_in6.sin6_addr), AF_INET6, &md->sender);
+ md->sender_port = ntohs(from.sa_in6.sin6_port);
+ break;
+ }
+ }
}
- }
- /* now we report any actual I/O error */
- if (packet_len == -1)
- {
- if (from_ugh == undisclosed
- && errno == ECONNREFUSED)
+ /* now we report any actual I/O error */
+ if (packet_len == -1)
{
- /* Tone down scary message for vague event:
- * We get "connection refused" in response to some
- * datagram we sent, but we cannot tell which one.
- */
- plog("some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)");
+ if (from_ugh == undisclosed
+ && errno == ECONNREFUSED)
+ {
+ /* Tone down scary message for vague event:
+ * We get "connection refused" in response to some
+ * datagram we sent, but we cannot tell which one.
+ */
+ plog("some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)");
+ }
+ else if (from_ugh != NULL)
+ {
+ log_errno((e, "recvfrom on %s failed; Pluto cannot decode source sockaddr in rejection: %s"
+ , ifp->rname, from_ugh));
+ }
+ else
+ {
+ log_errno((e, "recvfrom on %s from %s:%u failed"
+ , ifp->rname
+ , ip_str(&md->sender), (unsigned)md->sender_port));
+ }
+
+ return FALSE;
}
else if (from_ugh != NULL)
{
- log_errno((e, "recvfrom on %s failed; Pluto cannot decode source sockaddr in rejection: %s"
- , ifp->rname, from_ugh));
- }
- else
- {
- log_errno((e, "recvfrom on %s from %s:%u failed"
- , ifp->rname
- , ip_str(&md->sender), (unsigned)md->sender_port));
+ plog("recvfrom on %s returned misformed source sockaddr: %s"
+ , ifp->rname, from_ugh);
+ return FALSE;
}
+ cur_from = &md->sender;
+ cur_from_port = md->sender_port;
- return FALSE;
- }
- else if (from_ugh != NULL)
- {
- plog("recvfrom on %s returned misformed source sockaddr: %s"
- , ifp->rname, from_ugh);
- return FALSE;
- }
- cur_from = &md->sender;
- cur_from_port = md->sender_port;
-
- if (ifp->ike_float == TRUE)
- {
- u_int32_t non_esp;
-
- if (packet_len < (int)sizeof(u_int32_t))
- {
- plog("recvfrom %s:%u too small packet (%d)"
- , ip_str(cur_from), (unsigned) cur_from_port, packet_len);
- return FALSE;
- }
- memcpy(&non_esp, buffer, sizeof(u_int32_t));
- if (non_esp != 0)
+ if (ifp->ike_float == TRUE)
{
- plog("recvfrom %s:%u has no Non-ESP marker"
- , ip_str(cur_from), (unsigned) cur_from_port);
- return FALSE;
+ u_int32_t non_esp;
+
+ if (packet_len < (int)sizeof(u_int32_t))
+ {
+ plog("recvfrom %s:%u too small packet (%d)"
+ , ip_str(cur_from), (unsigned) cur_from_port, packet_len);
+ return FALSE;
+ }
+ memcpy(&non_esp, buffer, sizeof(u_int32_t));
+ if (non_esp != 0)
+ {
+ plog("recvfrom %s:%u has no Non-ESP marker"
+ , ip_str(cur_from), (unsigned) cur_from_port);
+ return FALSE;
+ }
+ packet_len -= sizeof(u_int32_t);
+ buffer_nat = malloc(packet_len);
+ memcpy(buffer_nat, buffer + sizeof(u_int32_t), packet_len);
+ free(buffer);
+ buffer = buffer_nat;
}
- packet_len -= sizeof(u_int32_t);
- buffer_nat = alloc_bytes(packet_len, "buffer read packet");
- memcpy(buffer_nat, buffer + sizeof(u_int32_t), packet_len);
- pfree(buffer);
- buffer = buffer_nat;
- }
-
- /* Clone actual message contents
- * and set up md->packet_pbs to describe it.
- */
- init_pbs(&md->packet_pbs, buffer, packet_len, "packet");
-
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL,
- {
- DBG_log(BLANK_FORMAT);
- DBG_log("*received %d bytes from %s:%u on %s"
- , (int) pbs_room(&md->packet_pbs)
- , ip_str(cur_from), (unsigned) cur_from_port
- , ifp->rname);
- });
- DBG(DBG_RAW,
- DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)));
+ /* Clone actual message contents
+ * and set up md->packet_pbs to describe it.
+ */
+ init_pbs(&md->packet_pbs, buffer, packet_len, "packet");
- if ((pbs_room(&md->packet_pbs)==1) && (md->packet_pbs.start[0]==0xff))
- {
- /**
- * NAT-T Keep-alive packets should be discarded by kernel ESPinUDP
- * layer. But bogus keep-alive packets (sent with a non-esp marker)
- * can reach this point. Complain and discard them.
- */
- DBG(DBG_NATT,
- DBG_log("NAT-T keep-alive (bogus ?) should not reach this point. "
- "Ignored. Sender: %s:%u", ip_str(cur_from),
- (unsigned) cur_from_port);
- )
- return FALSE;
- }
+ DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL,
+ {
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received %d bytes from %s:%u on %s"
+ , (int) pbs_room(&md->packet_pbs)
+ , ip_str(cur_from), (unsigned) cur_from_port
+ , ifp->rname);
+ });
+
+ DBG(DBG_RAW,
+ DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)));
-#define IKEV2_VERSION_OFFSET 17
-#define IKEV2_VERSION 0x20
+ if ((pbs_room(&md->packet_pbs)==1) && (md->packet_pbs.start[0]==0xff))
+ {
+ /**
+ * NAT-T Keep-alive packets should be discarded by kernel ESPinUDP
+ * layer. But bogus keep-alive packets (sent with a non-esp marker)
+ * can reach this point. Complain and discard them.
+ */
+ DBG(DBG_NATT,
+ DBG_log("NAT-T keep-alive (bogus ?) should not reach this point. "
+ "Ignored. Sender: %s:%u", ip_str(cur_from),
+ (unsigned) cur_from_port);
+ )
+ return FALSE;
+ }
- /* ignore IKEv2 packets - they will be handled by charon */
- if (pbs_room(&md->packet_pbs) > IKEV2_VERSION_OFFSET
- && md->packet_pbs.start[IKEV2_VERSION_OFFSET] == IKEV2_VERSION)
- {
- DBG(DBG_CONTROLMORE,
- DBG_log(" ignoring IKEv2 packet")
- )
- return FALSE;
- }
+#define IKEV2_VERSION_OFFSET 17
+#define IKEV2_VERSION 0x20
+
+ /* ignore IKEv2 packets - they will be handled by charon */
+ if (pbs_room(&md->packet_pbs) > IKEV2_VERSION_OFFSET
+ && md->packet_pbs.start[IKEV2_VERSION_OFFSET] == IKEV2_VERSION)
+ {
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" ignoring IKEv2 packet")
+ )
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
/* process an input packet, possibly generating a reply.
@@ -1233,860 +1234,881 @@ read_packet(struct msg_digest *md)
static void
process_packet(struct msg_digest **mdp)
{
- struct msg_digest *md = *mdp;
- const struct state_microcode *smc;
- bool new_iv_set = FALSE;
- bool restore_iv = FALSE;
- u_char new_iv[MAX_DIGEST_LEN];
- u_int new_iv_len = 0;
+ struct msg_digest *md = *mdp;
+ const struct state_microcode *smc;
+ bool new_iv_set = FALSE;
+ bool restore_iv = FALSE;
+ u_char new_iv[MAX_DIGEST_LEN];
+ u_int new_iv_len = 0;
- struct state *st = NULL;
- enum state_kind from_state = STATE_UNDEFINED; /* state we started in */
+ struct state *st = NULL;
+ enum state_kind from_state = STATE_UNDEFINED; /* state we started in */
#define SEND_NOTIFICATION(t) { \
- if (st) send_notification_from_state(st, from_state, t); \
- else send_notification_from_md(md, t); }
+ if (st) send_notification_from_state(st, from_state, t); \
+ else send_notification_from_md(md, t); }
- if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs, &md->message_pbs))
- {
- /* Identify specific failures:
- * - bad ISAKMP major/minor version numbers
- */
- if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size)
+ if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs, &md->message_pbs))
{
- struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur;
- if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION)
- {
- SEND_NOTIFICATION(INVALID_MAJOR_VERSION);
- return;
- }
- else if ((hdr->isa_version & ISA_MIN_MASK) != ISAKMP_MINOR_VERSION)
- {
- SEND_NOTIFICATION(INVALID_MINOR_VERSION);
+ /* Identify specific failures:
+ * - bad ISAKMP major/minor version numbers
+ */
+ if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size)
+ {
+ struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur;
+ if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION)
+ {
+ SEND_NOTIFICATION(INVALID_MAJOR_VERSION);
+ return;
+ }
+ else if ((hdr->isa_version & ISA_MIN_MASK) != ISAKMP_MINOR_VERSION)
+ {
+ SEND_NOTIFICATION(INVALID_MINOR_VERSION);
+ return;
+ }
+ }
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
return;
- }
}
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- if (md->packet_pbs.roof != md->message_pbs.roof)
- {
- plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
- , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
+
+ if (md->packet_pbs.roof != md->message_pbs.roof)
+ {
+ plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
+ , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
#ifdef CISCO_QUIRKS
- if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
- plog("Cisco VPN client appends 16 surplus NULL bytes");
- else
+ if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
+ plog("Cisco VPN client appends 16 surplus NULL bytes");
+ else
#endif
- return;
- }
+ return;
+ }
- switch (md->hdr.isa_xchg)
- {
+ switch (md->hdr.isa_xchg)
+ {
#ifdef NOTYET
- case ISAKMP_XCHG_NONE:
- case ISAKMP_XCHG_BASE:
+ case ISAKMP_XCHG_NONE:
+ case ISAKMP_XCHG_BASE:
#endif
- case ISAKMP_XCHG_IDPROT: /* part of a Main Mode exchange */
- if (md->hdr.isa_msgid != MAINMODE_MSGID)
- {
- plog("Message ID was 0x%08lx but should be zero in Main Mode",
- (unsigned long) md->hdr.isa_msgid);
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
-
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("Initiator Cookie must not be zero in Main Mode message");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
+ case ISAKMP_XCHG_IDPROT: /* part of a Main Mode exchange */
+ if (md->hdr.isa_msgid != MAINMODE_MSGID)
+ {
+ plog("Message ID was 0x%08lx but should be zero in Main Mode",
+ (unsigned long) md->hdr.isa_msgid);
+ SEND_NOTIFICATION(INVALID_MESSAGE_ID);
+ return;
+ }
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- /* initial message from initiator
- * ??? what if this is a duplicate of another message?
- */
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- plog("initial Main Mode message is invalid:"
- " its Encrypted Flag is on");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
- }
+ if (is_zero_cookie(md->hdr.isa_icookie))
+ {
+ plog("Initiator Cookie must not be zero in Main Mode message");
+ SEND_NOTIFICATION(INVALID_COOKIE);
+ return;
+ }
- /* don't build a state until the message looks tasty */
- from_state = STATE_MAIN_R0;
- }
- else
- {
- /* not an initial message */
+ if (is_zero_cookie(md->hdr.isa_rcookie))
+ {
+ /* initial message from initiator
+ * ??? what if this is a duplicate of another message?
+ */
+ if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
+ {
+ plog("initial Main Mode message is invalid:"
+ " its Encrypted Flag is on");
+ SEND_NOTIFICATION(INVALID_FLAGS);
+ return;
+ }
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
+ /* don't build a state until the message looks tasty */
+ from_state = STATE_MAIN_R0;
+ }
+ else
+ {
+ /* not an initial message */
- if (st == NULL)
- {
- /* perhaps this is a first message from the responder
- * and contains a responder cookie that we've not yet seen.
- */
- st = find_state(md->hdr.isa_icookie, zero_cookie
- , &md->sender, md->hdr.isa_msgid);
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, md->hdr.isa_msgid);
- if (st == NULL)
- {
- plog("Main Mode message is part of an unknown exchange");
- /* XXX Could send notification back */
- return;
+ if (st == NULL)
+ {
+ /* perhaps this is a first message from the responder
+ * and contains a responder cookie that we've not yet seen.
+ */
+ st = find_state(md->hdr.isa_icookie, zero_cookie
+ , &md->sender, md->hdr.isa_msgid);
+
+ if (st == NULL)
+ {
+ plog("Main Mode message is part of an unknown exchange");
+ /* XXX Could send notification back */
+ return;
+ }
+ }
+ set_cur_state(st);
+ from_state = st->st_state;
}
- }
- set_cur_state(st);
- from_state = st->st_state;
- }
- break;
+ break;
#ifdef NOTYET
- case ISAKMP_XCHG_AO:
- case ISAKMP_XCHG_AGGR:
+ case ISAKMP_XCHG_AO:
+ case ISAKMP_XCHG_AGGR:
#endif
- case ISAKMP_XCHG_INFO: /* an informational exchange */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, MAINMODE_MSGID);
+ case ISAKMP_XCHG_INFO: /* an informational exchange */
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, MAINMODE_MSGID);
- if (st != NULL)
- set_cur_state(st);
+ if (st != NULL)
+ set_cur_state(st);
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- if (st == NULL)
- {
- plog("Informational Exchange is for an unknown (expired?) SA");
- /* XXX Could send notification back */
- return;
- }
+ if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
+ {
+ if (st == NULL)
+ {
+ plog("Informational Exchange is for an unknown (expired?) SA");
+ /* XXX Could send notification back */
+ return;
+ }
- if (!IS_ISAKMP_ENCRYPTED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "encrypted Informational Exchange message is invalid"
- " because no key is known");
- /* XXX Could send notification back */
- return;
- }
+ if (!IS_ISAKMP_ENCRYPTED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS, "encrypted Informational Exchange message is invalid"
+ " because no key is known");
+ /* XXX Could send notification back */
+ return;
+ }
- if (md->hdr.isa_msgid == MAINMODE_MSGID)
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
- " it has a Message ID of 0");
- /* XXX Could send notification back */
- return;
- }
-
- if (!reserve_msgid(st, md->hdr.isa_msgid))
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
- " it has a previously used Message ID (0x%08lx)"
- , (unsigned long)md->hdr.isa_msgid);
- /* XXX Could send notification back */
- return;
- }
+ if (md->hdr.isa_msgid == MAINMODE_MSGID)
+ {
+ loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
+ " it has a Message ID of 0");
+ /* XXX Could send notification back */
+ return;
+ }
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- memcpy(st->st_ph1_iv, st->st_new_iv, st->st_new_iv_len);
- st->st_ph1_iv_len = st->st_new_iv_len;
-
- /* backup new_iv */
- new_iv_len = st->st_new_iv_len;
- passert(new_iv_len <= MAX_DIGEST_LEN)
- memcpy(new_iv, st->st_new_iv, new_iv_len);
- restore_iv = TRUE;
- }
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
-
- from_state = STATE_INFO_PROTECTED;
- }
- else
- {
- if (st != NULL && IS_ISAKMP_ENCRYPTED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "Informational Exchange message"
- " must be encrypted");
- /* XXX Could send notification back */
- return;
- }
- from_state = STATE_INFO;
- }
- break;
+ if (!reserve_msgid(st, md->hdr.isa_msgid))
+ {
+ loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because"
+ " it has a previously used Message ID (0x%08lx)"
+ , (unsigned long)md->hdr.isa_msgid);
+ /* XXX Could send notification back */
+ return;
+ }
- case ISAKMP_XCHG_QUICK: /* part of a Quick Mode exchange */
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("Quick Mode message is invalid because"
- " it has an Initiator Cookie of 0");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ memcpy(st->st_ph1_iv, st->st_new_iv, st->st_new_iv_len);
+ st->st_ph1_iv_len = st->st_new_iv_len;
+
+ /* backup new_iv */
+ new_iv_len = st->st_new_iv_len;
+ passert(new_iv_len <= MAX_DIGEST_LEN)
+ memcpy(new_iv, st->st_new_iv, new_iv_len);
+ restore_iv = TRUE;
+ }
+ init_phase2_iv(st, &md->hdr.isa_msgid);
+ new_iv_set = TRUE;
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- plog("Quick Mode message is invalid because"
- " it has a Responder Cookie of 0");
- SEND_NOTIFICATION(INVALID_COOKIE);
- return;
- }
+ from_state = STATE_INFO_PROTECTED;
+ }
+ else
+ {
+ if (st != NULL && IS_ISAKMP_ENCRYPTED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS, "Informational Exchange message"
+ " must be encrypted");
+ /* XXX Could send notification back */
+ return;
+ }
+ from_state = STATE_INFO;
+ }
+ break;
- if (md->hdr.isa_msgid == MAINMODE_MSGID)
- {
- plog("Quick Mode message is invalid because"
- " it has a Message ID of 0");
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
+ case ISAKMP_XCHG_QUICK: /* part of a Quick Mode exchange */
+ if (is_zero_cookie(md->hdr.isa_icookie))
+ {
+ plog("Quick Mode message is invalid because"
+ " it has an Initiator Cookie of 0");
+ SEND_NOTIFICATION(INVALID_COOKIE);
+ return;
+ }
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
+ if (is_zero_cookie(md->hdr.isa_rcookie))
+ {
+ plog("Quick Mode message is invalid because"
+ " it has a Responder Cookie of 0");
+ SEND_NOTIFICATION(INVALID_COOKIE);
+ return;
+ }
- if (st == NULL)
- {
- /* No appropriate Quick Mode state.
- * See if we have a Main Mode state.
- * ??? what if this is a duplicate of another message?
- */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, MAINMODE_MSGID);
-
- if (st == NULL)
- {
- plog("Quick Mode message is for a non-existent (expired?)"
- " ISAKMP SA");
- /* XXX Could send notification back */
- return;
- }
+ if (md->hdr.isa_msgid == MAINMODE_MSGID)
+ {
+ plog("Quick Mode message is invalid because"
+ " it has a Message ID of 0");
+ SEND_NOTIFICATION(INVALID_MESSAGE_ID);
+ return;
+ }
- set_cur_state(st);
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, md->hdr.isa_msgid);
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "Quick Mode message is unacceptable because"
- " it is for an incomplete ISAKMP SA");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
- return;
- }
-
- /* only accept this new Quick Mode exchange if it has a unique message ID */
- if (!reserve_msgid(st, md->hdr.isa_msgid))
- {
- loglog(RC_LOG_SERIOUS, "Quick Mode I1 message is unacceptable because"
- " it uses a previously used Message ID 0x%08lx"
- " (perhaps this is a duplicated packet)"
- , (unsigned long) md->hdr.isa_msgid);
- SEND_NOTIFICATION(INVALID_MESSAGE_ID);
- return;
- }
+ if (st == NULL)
+ {
+ /* No appropriate Quick Mode state.
+ * See if we have a Main Mode state.
+ * ??? what if this is a duplicate of another message?
+ */
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, MAINMODE_MSGID);
- /* Quick Mode Initial IV */
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
+ if (st == NULL)
+ {
+ plog("Quick Mode message is for a non-existent (expired?)"
+ " ISAKMP SA");
+ /* XXX Could send notification back */
+ return;
+ }
- from_state = STATE_QUICK_R0;
- }
- else
- {
- set_cur_state(st);
- from_state = st->st_state;
- }
+ set_cur_state(st);
- break;
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS, "Quick Mode message is unacceptable because"
+ " it is for an incomplete ISAKMP SA");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
+ return;
+ }
- case ISAKMP_XCHG_MODE_CFG:
- if (is_zero_cookie(md->hdr.isa_icookie))
- {
- plog("ModeCfg message is invalid because"
- " it has an Initiator Cookie of 0");
- /* XXX Could send notification back */
- return;
- }
+ /* only accept this new Quick Mode exchange if it has a unique message ID */
+ if (!reserve_msgid(st, md->hdr.isa_msgid))
+ {
+ loglog(RC_LOG_SERIOUS, "Quick Mode I1 message is unacceptable because"
+ " it uses a previously used Message ID 0x%08lx"
+ " (perhaps this is a duplicated packet)"
+ , (unsigned long) md->hdr.isa_msgid);
+ SEND_NOTIFICATION(INVALID_MESSAGE_ID);
+ return;
+ }
- if (is_zero_cookie(md->hdr.isa_rcookie))
- {
- plog("ModeCfg message is invalid because"
- " it has a Responder Cookie of 0");
- /* XXX Could send notification back */
- return;
- }
+ /* Quick Mode Initial IV */
+ init_phase2_iv(st, &md->hdr.isa_msgid);
+ new_iv_set = TRUE;
- if (md->hdr.isa_msgid == 0)
- {
- plog("ModeCfg message is invalid because"
- " it has a Message ID of 0");
- /* XXX Could send notification back */
- return;
- }
+ from_state = STATE_QUICK_R0;
+ }
+ else
+ {
+ set_cur_state(st);
+ from_state = st->st_state;
+ }
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, md->hdr.isa_msgid);
+ break;
- if (st == NULL)
- {
- bool has_xauth_policy;
-
- /* No appropriate ModeCfg state.
- * See if we have a Main Mode state.
- * ??? what if this is a duplicate of another message?
- */
- st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
- , &md->sender, 0);
-
- if (st == NULL)
- {
- plog("ModeCfg message is for a non-existent (expired?)"
- " ISAKMP SA");
- /* XXX Could send notification back */
- return;
- }
+ case ISAKMP_XCHG_MODE_CFG:
+ if (is_zero_cookie(md->hdr.isa_icookie))
+ {
+ plog("ModeCfg message is invalid because"
+ " it has an Initiator Cookie of 0");
+ /* XXX Could send notification back */
+ return;
+ }
+
+ if (is_zero_cookie(md->hdr.isa_rcookie))
+ {
+ plog("ModeCfg message is invalid because"
+ " it has a Responder Cookie of 0");
+ /* XXX Could send notification back */
+ return;
+ }
+
+ if (md->hdr.isa_msgid == 0)
+ {
+ plog("ModeCfg message is invalid because"
+ " it has a Message ID of 0");
+ /* XXX Could send notification back */
+ return;
+ }
- set_cur_state(st);
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, md->hdr.isa_msgid);
- /* the XAUTH_STATUS message might have a new msgid */
- if (st->st_state == STATE_XAUTH_I1)
- {
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
- from_state = st->st_state;
+ if (st == NULL)
+ {
+ bool has_xauth_policy;
+
+ /* No appropriate ModeCfg state.
+ * See if we have a Main Mode state.
+ * ??? what if this is a duplicate of another message?
+ */
+ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie
+ , &md->sender, 0);
+
+ if (st == NULL)
+ {
+ plog("ModeCfg message is for a non-existent (expired?)"
+ " ISAKMP SA");
+ /* XXX Could send notification back */
+ return;
+ }
+
+ set_cur_state(st);
+
+ /* the XAUTH_STATUS message might have a new msgid */
+ if (st->st_state == STATE_XAUTH_I1)
+ {
+ init_phase2_iv(st, &md->hdr.isa_msgid);
+ new_iv_set = TRUE;
+ from_state = st->st_state;
+ break;
+ }
+
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
+ " it is for an incomplete ISAKMP SA (state=%s)"
+ , enum_name(&state_names, st->st_state));
+ /* XXX Could send notification back */
+ return;
+ }
+ init_phase2_iv(st, &md->hdr.isa_msgid);
+ new_iv_set = TRUE;
+
+ /*
+ * okay, now we have to figure out if we are receiving a bogus
+ * new message in an oustanding XAUTH server conversation
+ * (i.e. a reply to our challenge)
+ * (this occurs with some broken other implementations).
+ *
+ * or if receiving for the first time, an XAUTH challenge.
+ *
+ * or if we are getting a MODECFG request.
+ *
+ * we distinguish these states because we can not both be an
+ * XAUTH server and client, and our policy tells us which
+ * one we are.
+ *
+ * to complicate further, it is normal to start a new msgid
+ * when going from one state to another, or when restarting
+ * the challenge.
+ *
+ */
+
+ has_xauth_policy = (st->st_connection->policy
+ & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
+ != LEMPTY;
+
+ if (has_xauth_policy && !st->st_xauth.started
+ && IS_PHASE1(st->st_state))
+ {
+ from_state = STATE_XAUTH_I0;
+ }
+ else if (st->st_connection->spd.that.modecfg
+ && IS_PHASE1(st->st_state))
+ {
+ from_state = STATE_MODE_CFG_R0;
+ }
+ else if (st->st_connection->spd.this.modecfg
+ && IS_PHASE1(st->st_state))
+ {
+ from_state = STATE_MODE_CFG_I0;
+ }
+ else
+ {
+ /* XXX check if we are being a mode config server here */
+ plog("received ModeCfg message when in state %s, and we aren't mode config client"
+ , enum_name(&state_names, st->st_state));
+ return;
+ }
+ }
+ else
+ {
+ set_cur_state(st);
+ from_state = st->st_state;
+ }
break;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
- " it is for an incomplete ISAKMP SA (state=%s)"
- , enum_name(&state_names, st->st_state));
- /* XXX Could send notification back */
- return;
- }
- init_phase2_iv(st, &md->hdr.isa_msgid);
- new_iv_set = TRUE;
-
- /*
- * okay, now we have to figure out if we are receiving a bogus
- * new message in an oustanding XAUTH server conversation
- * (i.e. a reply to our challenge)
- * (this occurs with some broken other implementations).
- *
- * or if receiving for the first time, an XAUTH challenge.
- *
- * or if we are getting a MODECFG request.
- *
- * we distinguish these states because we can not both be an
- * XAUTH server and client, and our policy tells us which
- * one we are.
- *
- * to complicate further, it is normal to start a new msgid
- * when going from one state to another, or when restarting
- * the challenge.
- *
- */
-
- has_xauth_policy = (st->st_connection->policy
- & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
- != LEMPTY;
-
- if (has_xauth_policy && !st->st_xauth.started
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_XAUTH_I0;
- }
- else if (st->st_connection->spd.that.modecfg
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_MODE_CFG_R0;
- }
- else if (st->st_connection->spd.this.modecfg
- && IS_PHASE1(st->st_state))
- {
- from_state = STATE_MODE_CFG_I0;
- }
- else
- {
- /* XXX check if we are being a mode config server here */
- plog("received ModeCfg message when in state %s, and we aren't mode config client"
- , enum_name(&state_names, st->st_state));
- return;
- }
- }
- else
- {
- set_cur_state(st);
- from_state = st->st_state;
- }
- break;
#ifdef NOTYET
- case ISAKMP_XCHG_NGRP:
- case ISAKMP_XCHG_ACK_INFO:
+ case ISAKMP_XCHG_NGRP:
+ case ISAKMP_XCHG_ACK_INFO:
#endif
- default:
- plog("unsupported exchange type %s in message"
- , enum_show(&exchange_names, md->hdr.isa_xchg));
- SEND_NOTIFICATION(UNSUPPORTED_EXCHANGE_TYPE);
- return;
- }
-
- /* We have found a from_state, and perhaps a state object.
- * If we need to build a new state object,
- * we wait until the packet has been sanity checked.
- */
-
- /* We don't support the Commit Flag. It is such a bad feature.
- * It isn't protected -- neither encrypted nor authenticated.
- * A man in the middle turns it on, leading to DoS.
- * We just ignore it, with a warning.
- * By placing the check here, we could easily add a policy bit
- * to a connection to suppress the warning. This might be useful
- * because the Commit Flag is expected from some peers.
- */
- if (md->hdr.isa_flags & ISAKMP_FLAG_COMMIT)
- {
- plog("IKE message has the Commit Flag set but Pluto doesn't implement this feature; ignoring flag");
- }
-
- /* Set smc to describe this state's properties.
- * Look up the appropriate microcode based on state and
- * possibly Oakley Auth type.
- */
- passert(STATE_IKE_FLOOR <= from_state && from_state <= STATE_IKE_ROOF);
- smc = ike_microcode_index[from_state - STATE_IKE_FLOOR];
-
- if (st != NULL)
- {
- u_int16_t auth;
-
- switch (st->st_oakley.auth)
- {
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- auth = OAKLEY_PRESHARED_KEY;
- break;
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- auth = OAKLEY_RSA_SIG;
- break;
default:
- auth = st->st_oakley.auth;
+ plog("unsupported exchange type %s in message"
+ , enum_show(&exchange_names, md->hdr.isa_xchg));
+ SEND_NOTIFICATION(UNSUPPORTED_EXCHANGE_TYPE);
+ return;
}
-
- while (!LHAS(smc->flags, auth))
+
+ /* We have found a from_state, and perhaps a state object.
+ * If we need to build a new state object,
+ * we wait until the packet has been sanity checked.
+ */
+
+ /* We don't support the Commit Flag. It is such a bad feature.
+ * It isn't protected -- neither encrypted nor authenticated.
+ * A man in the middle turns it on, leading to DoS.
+ * We just ignore it, with a warning.
+ * By placing the check here, we could easily add a policy bit
+ * to a connection to suppress the warning. This might be useful
+ * because the Commit Flag is expected from some peers.
+ */
+ if (md->hdr.isa_flags & ISAKMP_FLAG_COMMIT)
{
- smc++;
- passert(smc->state == from_state);
+ plog("IKE message has the Commit Flag set but Pluto doesn't implement this feature; ignoring flag");
}
- }
-
- /* Ignore a packet if the state has a suspended state transition
- * Probably a duplicated packet but the original packet is not yet
- * recorded in st->st_rpacket, so duplicate checking won't catch.
- * ??? Should the packet be recorded earlier to improve diagnosis?
- */
- if (st != NULL && st->st_suspended_md != NULL)
- {
- loglog(RC_LOG, "discarding packet received during DNS lookup in %s"
- , enum_name(&state_names, st->st_state));
- return;
- }
-
- /* Detect and handle duplicated packets.
- * This won't work for the initial packet of an exchange
- * because we won't have a state object to remember it.
- * If we are in a non-receiving state (terminal), and the preceding
- * state did transmit, then the duplicate may indicate that that
- * transmission wasn't received -- retransmit it.
- * Otherwise, just discard it.
- * ??? Notification packets are like exchanges -- I hope that
- * they are idempotent!
- */
- if (st != NULL
- && st->st_rpacket.ptr != NULL
- && st->st_rpacket.len == pbs_room(&md->packet_pbs)
- && memcmp(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len) == 0)
- {
- if (smc->flags & SMF_RETRANSMIT_ON_DUPLICATE)
+
+ /* Set smc to describe this state's properties.
+ * Look up the appropriate microcode based on state and
+ * possibly Oakley Auth type.
+ */
+ passert(STATE_IKE_FLOOR <= from_state && from_state <= STATE_IKE_ROOF);
+ smc = ike_microcode_index[from_state - STATE_IKE_FLOOR];
+
+ if (st != NULL)
{
- if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
- {
- st->st_retransmit++;
- loglog(RC_RETRANSMISSION
- , "retransmitting in response to duplicate packet; already %s"
- , enum_name(&state_names, st->st_state));
- send_packet(st, "retransmit in response to duplicate");
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "discarding duplicate packet -- exhausted retransmission; already %s"
- , enum_name(&state_names, st->st_state));
- }
+ u_int16_t auth;
+
+ switch (st->st_oakley.auth)
+ {
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ auth = OAKLEY_PRESHARED_KEY;
+ break;
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ auth = OAKLEY_RSA_SIG;
+ break;
+ default:
+ auth = st->st_oakley.auth;
+ }
+
+ while (!LHAS(smc->flags, auth))
+ {
+ smc++;
+ passert(smc->state == from_state);
+ }
}
- else
+
+ /* Ignore a packet if the state has a suspended state transition
+ * Probably a duplicated packet but the original packet is not yet
+ * recorded in st->st_rpacket, so duplicate checking won't catch.
+ * ??? Should the packet be recorded earlier to improve diagnosis?
+ */
+ if (st != NULL && st->st_suspended_md != NULL)
{
- loglog(RC_LOG_SERIOUS, "discarding duplicate packet; already %s"
- , enum_name(&state_names, st->st_state));
+ loglog(RC_LOG, "discarding packet received during DNS lookup in %s"
+ , enum_name(&state_names, st->st_state));
+ return;
}
- return;
- }
-
- if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
- {
- DBG(DBG_CRYPT, DBG_log("received encrypted packet from %s:%u"
- , ip_str(&md->sender), (unsigned)md->sender_port));
- if (st == NULL)
+ /* Detect and handle duplicated packets.
+ * This won't work for the initial packet of an exchange
+ * because we won't have a state object to remember it.
+ * If we are in a non-receiving state (terminal), and the preceding
+ * state did transmit, then the duplicate may indicate that that
+ * transmission wasn't received -- retransmit it.
+ * Otherwise, just discard it.
+ * ??? Notification packets are like exchanges -- I hope that
+ * they are idempotent!
+ */
+ if (st != NULL
+ && st->st_rpacket.ptr != NULL
+ && st->st_rpacket.len == pbs_room(&md->packet_pbs)
+ && memeq(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len))
{
- plog("discarding encrypted message for an unknown ISAKMP SA");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
- return;
+ if (smc->flags & SMF_RETRANSMIT_ON_DUPLICATE)
+ {
+ if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
+ {
+ st->st_retransmit++;
+ loglog(RC_RETRANSMISSION
+ , "retransmitting in response to duplicate packet; already %s"
+ , enum_name(&state_names, st->st_state));
+ send_packet(st, "retransmit in response to duplicate");
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "discarding duplicate packet -- exhausted retransmission; already %s"
+ , enum_name(&state_names, st->st_state));
+ }
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "discarding duplicate packet; already %s"
+ , enum_name(&state_names, st->st_state));
+ }
+ return;
}
- if (st->st_skeyid_e.ptr == (u_char *) NULL)
+
+ if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION)
{
- loglog(RC_LOG_SERIOUS, "discarding encrypted message"
- " because we haven't yet negotiated keying materiel");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
- }
+ DBG(DBG_CRYPT, DBG_log("received encrypted packet from %s:%u"
+ , ip_str(&md->sender), (unsigned)md->sender_port));
- /* Mark as encrypted */
- md->encrypted = TRUE;
+ if (st == NULL)
+ {
+ plog("discarding encrypted message for an unknown ISAKMP SA");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */);
+ return;
+ }
+ if (st->st_skeyid_e.ptr == (u_char *) NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "discarding encrypted message"
+ " because we haven't yet negotiated keying materiel");
+ SEND_NOTIFICATION(INVALID_FLAGS);
+ return;
+ }
- DBG(DBG_CRYPT, DBG_log("decrypting %u bytes using algorithm %s"
- , (unsigned) pbs_left(&md->message_pbs)
- , enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
+ /* Mark as encrypted */
+ md->encrypted = TRUE;
- /* do the specified decryption
- *
- * IV is from st->st_iv or (if new_iv_set) st->st_new_iv.
- * The new IV is placed in st->st_new_iv
- *
- * See RFC 2409 "IKE" Appendix B
- *
- * XXX The IV should only be updated really if the packet
- * is successfully processed.
- * We should keep this value, check for a success return
- * value from the parsing routines and then replace.
- *
- * Each post phase 1 exchange generates IVs from
- * the last phase 1 block, not the last block sent.
- */
- {
- const struct encrypt_desc *e = st->st_oakley.encrypter;
+ DBG(DBG_CRYPT, DBG_log("decrypting %u bytes using algorithm %s"
+ , (unsigned) pbs_left(&md->message_pbs)
+ , enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
- if (pbs_left(&md->message_pbs) % e->enc_blocksize != 0)
- {
- loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- /* XXX Detect weak keys */
-
- /* grab a copy of raw packet (for duplicate packet detection) */
- clonetochunk(md->raw_packet, md->packet_pbs.start
- , pbs_room(&md->packet_pbs), "raw packet");
-
- /* Decrypt everything after header */
- if (!new_iv_set)
- {
- /* use old IV */
- passert(st->st_iv_len <= sizeof(st->st_new_iv));
- st->st_new_iv_len = st->st_iv_len;
- memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
- }
- crypto_cbc_encrypt(e, FALSE, md->message_pbs.cur,
- pbs_left(&md->message_pbs) , st);
- if (restore_iv)
- {
- memcpy(st->st_new_iv, new_iv, new_iv_len);
- st->st_new_iv_len = new_iv_len;
- }
- }
+ /* do the specified decryption
+ *
+ * IV is from st->st_iv or (if new_iv_set) st->st_new_iv.
+ * The new IV is placed in st->st_new_iv
+ *
+ * See RFC 2409 "IKE" Appendix B
+ *
+ * XXX The IV should only be updated really if the packet
+ * is successfully processed.
+ * We should keep this value, check for a success return
+ * value from the parsing routines and then replace.
+ *
+ * Each post phase 1 exchange generates IVs from
+ * the last phase 1 block, not the last block sent.
+ */
+ {
+ size_t crypter_block_size;
+ encryption_algorithm_t enc_alg;
+ crypter_t *crypter;
+ chunk_t data, iv;
+ char *new_iv;
+
+ enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
+ crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
+ crypter_block_size = crypter->get_block_size(crypter);
+
+ if (pbs_left(&md->message_pbs) % crypter_block_size != 0)
+ {
+ loglog(RC_LOG_SERIOUS, "malformed message: not a multiple of encryption blocksize");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
- DBG_cond_dump(DBG_CRYPT, "decrypted:\n", md->message_pbs.cur
- , md->message_pbs.roof - md->message_pbs.cur);
+ /* XXX Detect weak keys */
- DBG_cond_dump(DBG_CRYPT, "next IV:"
- , st->st_new_iv, st->st_new_iv_len);
- }
- else
- {
- /* packet was not encryped -- should it have been? */
+ /* grab a copy of raw packet (for duplicate packet detection) */
+ md->raw_packet = chunk_create(md->packet_pbs.start, pbs_room(&md->packet_pbs));
+ md->raw_packet = chunk_clone(md->raw_packet);
- if (smc->flags & SMF_INPUT_ENCRYPTED)
- {
- loglog(RC_LOG_SERIOUS, "packet rejected: should have been encrypted");
- SEND_NOTIFICATION(INVALID_FLAGS);
- return;
+ data = chunk_create(md->message_pbs.cur, pbs_left(&md->message_pbs));
+
+ /* Decrypt everything after header */
+ if (!new_iv_set)
+ {
+ /* use old IV */
+ passert(st->st_iv_len <= sizeof(st->st_new_iv));
+ st->st_new_iv_len = st->st_iv_len;
+ memcpy(st->st_new_iv, st->st_iv, st->st_new_iv_len);
+ }
+
+ /* form iv by truncation */
+ st->st_new_iv_len = crypter_block_size;
+ iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
+ new_iv = alloca(crypter_block_size);
+ memcpy(new_iv, data.ptr + data.len - crypter_block_size,
+ crypter_block_size);
+
+ crypter->set_key(crypter, st->st_enc_key);
+ crypter->decrypt(crypter, data, iv, NULL);
+ crypter->destroy(crypter);
+
+ memcpy(st->st_new_iv, new_iv, crypter_block_size);
+ if (restore_iv)
+ {
+ memcpy(st->st_new_iv, new_iv, new_iv_len);
+ st->st_new_iv_len = new_iv_len;
+ }
+ }
+
+ DBG_cond_dump(DBG_CRYPT, "decrypted:\n", md->message_pbs.cur
+ , md->message_pbs.roof - md->message_pbs.cur);
+
+ DBG_cond_dump(DBG_CRYPT, "next IV:"
+ , st->st_new_iv, st->st_new_iv_len);
}
- }
-
- /* Digest the message.
- * Padding must be removed to make hashing work.
- * Padding comes from encryption (so this code must be after decryption).
- * Padding rules are described before the definition of
- * struct isakmp_hdr in packet.h.
- */
- {
- struct payload_digest *pd = md->digest;
- int np = md->hdr.isa_np;
- lset_t needed = smc->req_payloads;
- const char *excuse
- = LIN(SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT, smc->flags)
- ? "probable authentication failure (mismatch of preshared secrets?): "
- : "";
-
- while (np != ISAKMP_NEXT_NONE)
+ else
{
- struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL;
+ /* packet was not encryped -- should it have been? */
- if (pd == &md->digest[PAYLIMIT])
- {
- loglog(RC_LOG_SERIOUS, "more than %d payloads in message; ignored", PAYLIMIT);
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- switch (np)
- {
- case ISAKMP_NEXT_NATD_RFC:
- case ISAKMP_NEXT_NATOA_RFC:
- if (!st || !(st->nat_traversal & NAT_T_WITH_RFC_VALUES))
- {
- /*
- * don't accept NAT-D/NAT-OA reloc directly in message, unless
- * we're using NAT-T RFC
- */
- sd = NULL;
- }
- break;
- }
-
- if (sd == NULL)
- {
- /* payload type is out of range or requires special handling */
- switch (np)
+ if (smc->flags & SMF_INPUT_ENCRYPTED)
{
- case ISAKMP_NEXT_ID:
- sd = IS_PHASE1(from_state)
- ? &isakmp_identification_desc : &isakmp_ipsec_identification_desc;
- break;
- case ISAKMP_NEXT_NATD_DRAFTS:
- np = ISAKMP_NEXT_NATD_RFC; /* NAT-D relocated */
- sd = payload_descs[np];
- break;
- case ISAKMP_NEXT_NATOA_DRAFTS:
- np = ISAKMP_NEXT_NATOA_RFC; /* NAT-OA relocated */
- sd = payload_descs[np];
- break;
- default:
- loglog(RC_LOG_SERIOUS, "%smessage ignored because it contains an unknown or"
- " unexpected payload type (%s) at the outermost level"
- , excuse, enum_show(&payload_names, np));
- SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
- return;
+ loglog(RC_LOG_SERIOUS, "packet rejected: should have been encrypted");
+ SEND_NOTIFICATION(INVALID_FLAGS);
+ return;
}
- }
-
- {
- lset_t s = LELEM(np);
+ }
- if (LDISJOINT(s
- , needed | smc->opt_payloads| LELEM(ISAKMP_NEXT_N) | LELEM(ISAKMP_NEXT_D)))
+ /* Digest the message.
+ * Padding must be removed to make hashing work.
+ * Padding comes from encryption (so this code must be after decryption).
+ * Padding rules are described before the definition of
+ * struct isakmp_hdr in packet.h.
+ */
+ {
+ struct payload_digest *pd = md->digest;
+ int np = md->hdr.isa_np;
+ lset_t needed = smc->req_payloads;
+ const char *excuse
+ = LIN(SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT, smc->flags)
+ ? "probable authentication failure (mismatch of preshared secrets?): "
+ : "";
+
+ while (np != ISAKMP_NEXT_NONE)
{
- loglog(RC_LOG_SERIOUS, "%smessage ignored because it "
- "contains an unexpected payload type (%s)"
- , excuse, enum_show(&payload_names, np));
- SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
- return;
+ struct_desc *sd = np < ISAKMP_NEXT_ROOF? payload_descs[np] : NULL;
+
+ if (pd == &md->digest[PAYLIMIT])
+ {
+ loglog(RC_LOG_SERIOUS, "more than %d payloads in message; ignored", PAYLIMIT);
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
+
+ switch (np)
+ {
+ case ISAKMP_NEXT_NATD_RFC:
+ case ISAKMP_NEXT_NATOA_RFC:
+ if (!st || !(st->nat_traversal & NAT_T_WITH_RFC_VALUES))
+ {
+ /*
+ * don't accept NAT-D/NAT-OA reloc directly in message, unless
+ * we're using NAT-T RFC
+ */
+ sd = NULL;
+ }
+ break;
+ }
+
+ if (sd == NULL)
+ {
+ /* payload type is out of range or requires special handling */
+ switch (np)
+ {
+ case ISAKMP_NEXT_ID:
+ sd = IS_PHASE1(from_state)
+ ? &isakmp_identification_desc : &isakmp_ipsec_identification_desc;
+ break;
+ case ISAKMP_NEXT_NATD_DRAFTS:
+ np = ISAKMP_NEXT_NATD_RFC; /* NAT-D relocated */
+ sd = payload_descs[np];
+ break;
+ case ISAKMP_NEXT_NATOA_DRAFTS:
+ np = ISAKMP_NEXT_NATOA_RFC; /* NAT-OA relocated */
+ sd = payload_descs[np];
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "%smessage ignored because it contains an unknown or"
+ " unexpected payload type (%s) at the outermost level"
+ , excuse, enum_show(&payload_names, np));
+ SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
+ return;
+ }
+ }
+
+ {
+ lset_t s = LELEM(np);
+
+ if (LDISJOINT(s
+ , needed | smc->opt_payloads| LELEM(ISAKMP_NEXT_N) | LELEM(ISAKMP_NEXT_D)))
+ {
+ loglog(RC_LOG_SERIOUS, "%smessage ignored because it "
+ "contains an unexpected payload type (%s)"
+ , excuse, enum_show(&payload_names, np));
+ SEND_NOTIFICATION(INVALID_PAYLOAD_TYPE);
+ return;
+ }
+ needed &= ~s;
+ }
+
+ if (!in_struct(&pd->payload, sd, &md->message_pbs, &pd->pbs))
+ {
+ loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse);
+ if (md->hdr.isa_xchg != ISAKMP_XCHG_INFO)
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
+
+ /* place this payload at the end of the chain for this type */
+ {
+ struct payload_digest **p;
+
+ for (p = &md->chain[np]; *p != NULL; p = &(*p)->next)
+ ;
+ *p = pd;
+ pd->next = NULL;
+ }
+
+ np = pd->payload.generic.isag_np;
+ pd++;
+
+ /* since we've digested one payload happily, it is probably
+ * the case that any decryption worked. So we will not suggest
+ * encryption failure as an excuse for subsequent payload
+ * problems.
+ */
+ excuse = "";
}
- needed &= ~s;
- }
-
- if (!in_struct(&pd->payload, sd, &md->message_pbs, &pd->pbs))
- {
- loglog(RC_LOG_SERIOUS, "%smalformed payload in packet", excuse);
- if (md->hdr.isa_xchg != ISAKMP_XCHG_INFO)
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
-
- /* place this payload at the end of the chain for this type */
- {
- struct payload_digest **p;
-
- for (p = &md->chain[np]; *p != NULL; p = &(*p)->next)
- ;
- *p = pd;
- pd->next = NULL;
- }
-
- np = pd->payload.generic.isag_np;
- pd++;
-
- /* since we've digested one payload happily, it is probably
- * the case that any decryption worked. So we will not suggest
- * encryption failure as an excuse for subsequent payload
- * problems.
- */
- excuse = "";
- }
- md->digest_roof = pd;
+ md->digest_roof = pd;
- DBG(DBG_PARSING,
- if (pbs_left(&md->message_pbs) != 0)
- DBG_log("removing %d bytes of padding", (int) pbs_left(&md->message_pbs)));
+ DBG(DBG_PARSING,
+ if (pbs_left(&md->message_pbs) != 0)
+ DBG_log("removing %d bytes of padding", (int) pbs_left(&md->message_pbs)));
- md->message_pbs.roof = md->message_pbs.cur;
+ md->message_pbs.roof = md->message_pbs.cur;
- /* check that all mandatory payloads appeared */
+ /* check that all mandatory payloads appeared */
- if (needed != 0)
- {
- loglog(RC_LOG_SERIOUS, "message for %s is missing payloads %s"
- , enum_show(&state_names, from_state)
- , bitnamesof(payload_name, needed));
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
+ if (needed != 0)
+ {
+ loglog(RC_LOG_SERIOUS, "message for %s is missing payloads %s"
+ , enum_show(&state_names, from_state)
+ , bitnamesof(payload_name, needed));
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
}
- }
- /* more sanity checking: enforce most ordering constraints */
+ /* more sanity checking: enforce most ordering constraints */
- if (IS_PHASE1(from_state))
- {
- /* rfc2409: The Internet Key Exchange (IKE), 5 Exchanges:
- * "The SA payload MUST precede all other payloads in a phase 1 exchange."
- */
- if (md->chain[ISAKMP_NEXT_SA] != NULL
- && md->hdr.isa_np != ISAKMP_NEXT_SA)
+ if (IS_PHASE1(from_state))
{
- loglog(RC_LOG_SERIOUS, "malformed Phase 1 message: does not start with an SA payload");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
+ /* rfc2409: The Internet Key Exchange (IKE), 5 Exchanges:
+ * "The SA payload MUST precede all other payloads in a phase 1 exchange."
+ */
+ if (md->chain[ISAKMP_NEXT_SA] != NULL
+ && md->hdr.isa_np != ISAKMP_NEXT_SA)
+ {
+ loglog(RC_LOG_SERIOUS, "malformed Phase 1 message: does not start with an SA payload");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
}
- }
- else if (IS_QUICK(from_state))
- {
- /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode
- *
- * "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
- * header and a SA payload MUST immediately follow the HASH."
- * [NOTE: there may be more than one SA payload, so this is not
- * totally reasonable. Probably all SAs should be so constrained.]
- *
- * "If ISAKMP is acting as a client negotiator on behalf of another
- * party, the identities of the parties MUST be passed as IDci and
- * then IDcr."
- *
- * "With the exception of the HASH, SA, and the optional ID payloads,
- * there are no payload ordering restrictions on Quick Mode."
- */
-
- if (md->hdr.isa_np != ISAKMP_NEXT_HASH)
+ else if (IS_QUICK(from_state))
{
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: does not start with a HASH payload");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
- }
+ /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode
+ *
+ * "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP
+ * header and a SA payload MUST immediately follow the HASH."
+ * [NOTE: there may be more than one SA payload, so this is not
+ * totally reasonable. Probably all SAs should be so constrained.]
+ *
+ * "If ISAKMP is acting as a client negotiator on behalf of another
+ * party, the identities of the parties MUST be passed as IDci and
+ * then IDcr."
+ *
+ * "With the exception of the HASH, SA, and the optional ID payloads,
+ * there are no payload ordering restrictions on Quick Mode."
+ */
- {
- struct payload_digest *p;
- int i;
+ if (md->hdr.isa_np != ISAKMP_NEXT_HASH)
+ {
+ loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: does not start with a HASH payload");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
- for (p = md->chain[ISAKMP_NEXT_SA], i = 1; p != NULL
- ; p = p->next, i++)
- {
- if (p != &md->digest[i])
{
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: SA payload is in wrong position");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
+ struct payload_digest *p;
+ int i;
+
+ for (p = md->chain[ISAKMP_NEXT_SA], i = 1; p != NULL
+ ; p = p->next, i++)
+ {
+ if (p != &md->digest[i])
+ {
+ loglog(RC_LOG_SERIOUS, "malformed Quick Mode message: SA payload is in wrong position");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
+ }
+ }
+
+ /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode:
+ * "If ISAKMP is acting as a client negotiator on behalf of another
+ * party, the identities of the parties MUST be passed as IDci and
+ * then IDcr."
+ */
+ {
+ struct payload_digest *id = md->chain[ISAKMP_NEXT_ID];
+
+ if (id != NULL)
+ {
+ if (id->next == NULL || id->next->next != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
+ " if any ID payload is present,"
+ " there must be exactly two");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
+ if (id+1 != id->next)
+ {
+ loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
+ " the ID payloads are not adjacent");
+ SEND_NOTIFICATION(PAYLOAD_MALFORMED);
+ return;
+ }
+ }
}
- }
}
- /* rfc2409: The Internet Key Exchange (IKE), 5.5 Phase 2 - Quick Mode:
- * "If ISAKMP is acting as a client negotiator on behalf of another
- * party, the identities of the parties MUST be passed as IDci and
- * then IDcr."
+ /* Ignore payloads that we don't handle:
+ * Delete, Notification, VendorID
*/
+ /* XXX Handle deletions */
+ /* XXX Handle Notifications */
+ /* XXX Handle VID payloads */
{
- struct payload_digest *id = md->chain[ISAKMP_NEXT_ID];
+ struct payload_digest *p;
- if (id != NULL)
- {
- if (id->next == NULL || id->next->next != NULL)
+ for (p = md->chain[ISAKMP_NEXT_N]; p != NULL; p = p->next)
{
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
- " if any ID payload is present,"
- " there must be exactly two");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
+ if (p->payload.notification.isan_type != R_U_THERE
+ && p->payload.notification.isan_type != R_U_THERE_ACK)
+ {
+ loglog(RC_LOG_SERIOUS, "ignoring informational payload, type %s"
+ , enum_show(&notification_names, p->payload.notification.isan_type));
+ }
+ DBG_cond_dump(DBG_PARSING, "info:", p->pbs.cur, pbs_left(&p->pbs));
}
- if (id+1 != id->next)
+
+ for (p = md->chain[ISAKMP_NEXT_D]; p != NULL; p = p->next)
{
- loglog(RC_LOG_SERIOUS, "malformed Quick Mode message:"
- " the ID payloads are not adjacent");
- SEND_NOTIFICATION(PAYLOAD_MALFORMED);
- return;
+ accept_delete(st, md, p);
+ DBG_cond_dump(DBG_PARSING, "del:", p->pbs.cur, pbs_left(&p->pbs));
}
- }
- }
- }
-
- /* Ignore payloads that we don't handle:
- * Delete, Notification, VendorID
- */
- /* XXX Handle deletions */
- /* XXX Handle Notifications */
- /* XXX Handle VID payloads */
- {
- struct payload_digest *p;
-
- for (p = md->chain[ISAKMP_NEXT_N]; p != NULL; p = p->next)
- {
- if (p->payload.notification.isan_type != R_U_THERE
- && p->payload.notification.isan_type != R_U_THERE_ACK)
- {
- loglog(RC_LOG_SERIOUS, "ignoring informational payload, type %s"
- , enum_show(&notification_names, p->payload.notification.isan_type));
- }
- DBG_cond_dump(DBG_PARSING, "info:", p->pbs.cur, pbs_left(&p->pbs));
- }
-
- for (p = md->chain[ISAKMP_NEXT_D]; p != NULL; p = p->next)
- {
- accept_delete(st, md, p);
- DBG_cond_dump(DBG_PARSING, "del:", p->pbs.cur, pbs_left(&p->pbs));
- }
- for (p = md->chain[ISAKMP_NEXT_VID]; p != NULL; p = p->next)
- {
- handle_vendorid(md, p->pbs.cur, pbs_left(&p->pbs));
+ for (p = md->chain[ISAKMP_NEXT_VID]; p != NULL; p = p->next)
+ {
+ handle_vendorid(md, p->pbs.cur, pbs_left(&p->pbs));
+ }
}
- }
- md->from_state = from_state;
- md->smc = smc;
- md->st = st;
+ md->from_state = from_state;
+ md->smc = smc;
+ md->st = st;
- /* possibly fill in hdr */
- if (smc->first_out_payload != ISAKMP_NEXT_NONE)
- echo_hdr(md, (smc->flags & SMF_OUTPUT_ENCRYPTED) != 0
- , smc->first_out_payload);
+ /* possibly fill in hdr */
+ if (smc->first_out_payload != ISAKMP_NEXT_NONE)
+ echo_hdr(md, (smc->flags & SMF_OUTPUT_ENCRYPTED) != 0
+ , smc->first_out_payload);
- complete_state_transition(mdp, smc->processor(md));
+ complete_state_transition(mdp, smc->processor(md));
}
/* complete job started by the state-specific state transition function */
@@ -2094,406 +2116,406 @@ process_packet(struct msg_digest **mdp)
void
complete_state_transition(struct msg_digest **mdp, stf_status result)
{
- bool has_xauth_policy;
- bool is_xauth_server;
- struct msg_digest *md = *mdp;
- const struct state_microcode *smc = md->smc;
- enum state_kind from_state = md->from_state;
- struct state *st;
-
- cur_state = st = md->st; /* might have changed */
-
- /* If state has DPD support, import it */
- if (st && md->dpd)
- st->st_dpd = TRUE;
-
- switch (result)
- {
- case STF_IGNORE:
- break;
-
- case STF_SUSPEND:
- /* the stf didn't complete its job: don't relase md */
- *mdp = NULL;
- break;
-
- case STF_OK:
- /* advance the state */
- st->st_state = smc->next_state;
-
- /* Delete previous retransmission event.
- * New event will be scheduled below.
- */
- delete_event(st);
-
- /* replace previous receive packet with latest */
-
- pfreeany(st->st_rpacket.ptr);
-
- if (md->encrypted)
- {
- /* if encrypted, duplication already done */
- st->st_rpacket = md->raw_packet;
- md->raw_packet.ptr = NULL;
- }
- else
- {
- clonetochunk(st->st_rpacket
- , md->packet_pbs.start
- , pbs_room(&md->packet_pbs), "raw packet");
- }
-
- /* free previous transmit packet */
- freeanychunk(st->st_tpacket);
-
- /* if requested, send the new reply packet */
- if (smc->flags & SMF_REPLY)
- {
- close_output_pbs(&md->reply); /* good form, but actually a no-op */
-
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "reply packet");
-
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, md->st);
-
- /* actually send the packet
- * Note: this is a great place to implement "impairments"
- * for testing purposes. Suppress or duplicate the
- * send_packet call depending on st->st_state.
- */
- send_packet(st, enum_name(&state_names, from_state));
- }
+ bool has_xauth_policy;
+ bool is_xauth_server;
+ struct msg_digest *md = *mdp;
+ const struct state_microcode *smc = md->smc;
+ enum state_kind from_state = md->from_state;
+ struct state *st;
- /* Schedule for whatever timeout is specified */
- {
- time_t delay = UNDEFINED_TIME;
- enum event_type kind = smc->timeout_event;
- bool agreed_time = FALSE;
- struct connection *c = st->st_connection;
+ cur_state = st = md->st; /* might have changed */
- switch (kind)
- {
- case EVENT_RETRANSMIT: /* Retransmit packet */
- delay = EVENT_RETRANSMIT_DELAY_0;
- break;
-
- case EVENT_SA_REPLACE: /* SA replacement event */
- if (IS_PHASE1(st->st_state))
- {
- /* Note: we will defer to the "negotiated" (dictated)
- * lifetime if we are POLICY_DONT_REKEY.
- * This allows the other side to dictate
- * a time we would not otherwise accept
- * but it prevents us from having to initiate
- * rekeying. The negative consequences seem
- * minor.
+ /* If state has DPD support, import it */
+ if (st && md->dpd)
+ st->st_dpd = TRUE;
+
+ switch (result)
+ {
+ case STF_IGNORE:
+ break;
+
+ case STF_SUSPEND:
+ /* the stf didn't complete its job: don't relase md */
+ *mdp = NULL;
+ break;
+
+ case STF_OK:
+ /* advance the state */
+ st->st_state = smc->next_state;
+
+ /* Delete previous retransmission event.
+ * New event will be scheduled below.
*/
- delay = c->sa_ike_life_seconds;
- if ((c->policy & POLICY_DONT_REKEY)
- || delay >= st->st_oakley.life_seconds)
+ delete_event(st);
+
+ /* replace previous receive packet with latest */
+
+ free(st->st_rpacket.ptr);
+
+ if (md->encrypted)
{
- agreed_time = TRUE;
- delay = st->st_oakley.life_seconds;
+ /* if encrypted, duplication already done */
+ st->st_rpacket = md->raw_packet;
+ md->raw_packet.ptr = NULL;
}
- }
- else
- {
- /* Delay is min of up to four things:
- * each can limit the lifetime.
- */
- delay = c->sa_ipsec_life_seconds;
- if (st->st_ah.present
- && delay >= st->st_ah.attrs.life_seconds)
+ else
{
- agreed_time = TRUE;
- delay = st->st_ah.attrs.life_seconds;
+ st->st_rpacket = chunk_create(md->packet_pbs.start,
+ pbs_room(&md->packet_pbs));
+ st->st_rpacket = chunk_clone(st->st_rpacket);
}
- if (st->st_esp.present
- && delay >= st->st_esp.attrs.life_seconds)
+
+ /* free previous transmit packet */
+ chunk_free(&st->st_tpacket);
+
+ /* if requested, send the new reply packet */
+ if (smc->flags & SMF_REPLY)
{
- agreed_time = TRUE;
- delay = st->st_esp.attrs.life_seconds;
+ close_output_pbs(&md->reply); /* good form, but actually a no-op */
+
+ st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+
+ if (nat_traversal_enabled)
+ nat_traversal_change_port_lookup(md, md->st);
+
+ /* actually send the packet
+ * Note: this is a great place to implement "impairments"
+ * for testing purposes. Suppress or duplicate the
+ * send_packet call depending on st->st_state.
+ */
+ send_packet(st, enum_name(&state_names, from_state));
}
- if (st->st_ipcomp.present
- && delay >= st->st_ipcomp.attrs.life_seconds)
+
+ /* Schedule for whatever timeout is specified */
{
- agreed_time = TRUE;
- delay = st->st_ipcomp.attrs.life_seconds;
+ time_t delay = UNDEFINED_TIME;
+ enum event_type kind = smc->timeout_event;
+ bool agreed_time = FALSE;
+ struct connection *c = st->st_connection;
+
+ switch (kind)
+ {
+ case EVENT_RETRANSMIT: /* Retransmit packet */
+ delay = EVENT_RETRANSMIT_DELAY_0;
+ break;
+
+ case EVENT_SA_REPLACE: /* SA replacement event */
+ if (IS_PHASE1(st->st_state))
+ {
+ /* Note: we will defer to the "negotiated" (dictated)
+ * lifetime if we are POLICY_DONT_REKEY.
+ * This allows the other side to dictate
+ * a time we would not otherwise accept
+ * but it prevents us from having to initiate
+ * rekeying. The negative consequences seem
+ * minor.
+ */
+ delay = c->sa_ike_life_seconds;
+ if ((c->policy & POLICY_DONT_REKEY)
+ || delay >= st->st_oakley.life_seconds)
+ {
+ agreed_time = TRUE;
+ delay = st->st_oakley.life_seconds;
+ }
+ }
+ else
+ {
+ /* Delay is min of up to four things:
+ * each can limit the lifetime.
+ */
+ delay = c->sa_ipsec_life_seconds;
+ if (st->st_ah.present
+ && delay >= st->st_ah.attrs.life_seconds)
+ {
+ agreed_time = TRUE;
+ delay = st->st_ah.attrs.life_seconds;
+ }
+ if (st->st_esp.present
+ && delay >= st->st_esp.attrs.life_seconds)
+ {
+ agreed_time = TRUE;
+ delay = st->st_esp.attrs.life_seconds;
+ }
+ if (st->st_ipcomp.present
+ && delay >= st->st_ipcomp.attrs.life_seconds)
+ {
+ agreed_time = TRUE;
+ delay = st->st_ipcomp.attrs.life_seconds;
+ }
+ }
+
+ /* By default, we plan to rekey.
+ *
+ * If there isn't enough time to rekey, plan to
+ * expire.
+ *
+ * If we are --dontrekey, a lot more rules apply.
+ * If we are the Initiator, use REPLACE_IF_USED.
+ * If we are the Responder, and the dictated time
+ * was unacceptable (too large), plan to REPLACE
+ * (the only way to ratchet down the time).
+ * If we are the Responder, and the dictated time
+ * is acceptable, plan to EXPIRE.
+ *
+ * Important policy lies buried here.
+ * For example, we favour the initiator over the
+ * responder by making the initiator start rekeying
+ * sooner. Also, fuzz is only added to the
+ * initiator's margin.
+ *
+ * Note: for ISAKMP SA, we let the negotiated
+ * time stand (implemented by earlier logic).
+ */
+ if (agreed_time
+ && (c->policy & POLICY_DONT_REKEY))
+ {
+ kind = (smc->flags & SMF_INITIATOR)
+ ? EVENT_SA_REPLACE_IF_USED
+ : EVENT_SA_EXPIRE;
+ }
+ if (kind != EVENT_SA_EXPIRE)
+ {
+ unsigned long marg = c->sa_rekey_margin;
+
+ if (smc->flags & SMF_INITIATOR)
+ marg += marg
+ * c->sa_rekey_fuzz / 100.E0
+ * (rand() / (RAND_MAX + 1.E0));
+ else
+ marg /= 2;
+
+ if ((unsigned long)delay > marg)
+ {
+ delay -= marg;
+ st->st_margin = marg;
+ }
+ else
+ {
+ kind = EVENT_SA_EXPIRE;
+ }
+ }
+ break;
+
+ case EVENT_NULL: /* non-event */
+ case EVENT_REINIT_SECRET: /* Refresh cookie secret */
+ default:
+ bad_case(kind);
+ }
+ event_schedule(kind, delay, st);
}
- }
-
- /* By default, we plan to rekey.
- *
- * If there isn't enough time to rekey, plan to
- * expire.
- *
- * If we are --dontrekey, a lot more rules apply.
- * If we are the Initiator, use REPLACE_IF_USED.
- * If we are the Responder, and the dictated time
- * was unacceptable (too large), plan to REPLACE
- * (the only way to ratchet down the time).
- * If we are the Responder, and the dictated time
- * is acceptable, plan to EXPIRE.
- *
- * Important policy lies buried here.
- * For example, we favour the initiator over the
- * responder by making the initiator start rekeying
- * sooner. Also, fuzz is only added to the
- * initiator's margin.
- *
- * Note: for ISAKMP SA, we let the negotiated
- * time stand (implemented by earlier logic).
- */
- if (agreed_time
- && (c->policy & POLICY_DONT_REKEY))
- {
- kind = (smc->flags & SMF_INITIATOR)
- ? EVENT_SA_REPLACE_IF_USED
- : EVENT_SA_EXPIRE;
- }
- if (kind != EVENT_SA_EXPIRE)
- {
- unsigned long marg = c->sa_rekey_margin;
-
- if (smc->flags & SMF_INITIATOR)
- marg += marg
- * c->sa_rekey_fuzz / 100.E0
- * (rand() / (RAND_MAX + 1.E0));
- else
- marg /= 2;
- if ((unsigned long)delay > marg)
+ /* tell whack and log of progress */
{
- delay -= marg;
- st->st_margin = marg;
+ const char *story = state_story[st->st_state - STATE_MAIN_R0];
+ enum rc_type w = RC_NEW_STATE + st->st_state;
+ char sadetails[128];
+
+ sadetails[0]='\0';
+
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ {
+ char *b = sadetails;
+ const char *ini = " {";
+ const char *fin = "";
+
+ /* -1 is to leave space for "fin" */
+
+ if (st->st_esp.present)
+ {
+ snprintf(b, sizeof(sadetails)-(b-sadetails)-1
+ , "%sESP=>0x%08x <0x%08x"
+ , ini
+ , ntohl(st->st_esp.attrs.spi)
+ , ntohl(st->st_esp.our_spi));
+ ini = " ";
+ fin = "}";
+ }
+ /* advance b to end of string */
+ b = b + strlen(b);
+
+ if (st->st_ah.present)
+ {
+ snprintf(b, sizeof(sadetails)-(b-sadetails)-1
+ , "%sAH=>0x%08x <0x%08x"
+ , ini
+ , ntohl(st->st_ah.attrs.spi)
+ , ntohl(st->st_ah.our_spi));
+ ini = " ";
+ fin = "}";
+ }
+ /* advance b to end of string */
+ b = b + strlen(b);
+
+ if (st->st_ipcomp.present)
+ {
+ snprintf(b, sizeof(sadetails)-(b-sadetails)-1
+ , "%sIPCOMP=>0x%08x <0x%08x"
+ , ini
+ , ntohl(st->st_ipcomp.attrs.spi)
+ , ntohl(st->st_ipcomp.our_spi));
+ ini = " ";
+ fin = "}";
+ }
+ /* advance b to end of string */
+ b = b + strlen(b);
+
+ if (st->nat_traversal)
+ {
+ char oa[ADDRTOT_BUF];
+ addrtot(&st->nat_oa, 0, oa, sizeof(oa));
+ snprintf(b, sizeof(sadetails)-(b-sadetails)-1
+ , "%sNATOA=%s"
+ , ini, oa);
+ ini = " ";
+ fin = "}";
+ }
+
+ /* advance b to end of string */
+ b = b + strlen(b);
+
+ if (st->st_dpd)
+ {
+ snprintf(b, sizeof(sadetails)-(b-sadetails)-1
+ , "%sDPD"
+ , ini);
+ ini = " ";
+ fin = "}";
+ }
+
+ strcat(b, fin);
+ }
+
+ if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ {
+ /* log our success */
+ plog("%s%s", story, sadetails);
+ w = RC_SUCCESS;
+ }
+
+ /* tell whack our progress */
+ whack_log(w
+ , "%s: %s%s"
+ , enum_name(&state_names, st->st_state)
+ , story, sadetails);
}
- else
+
+ has_xauth_policy = (st->st_connection->policy
+ & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
+ != LEMPTY;
+ is_xauth_server = (st->st_connection->policy
+ & POLICY_XAUTH_SERVER)
+ != LEMPTY;
+
+ /* Should we start XAUTH as a server */
+ if (has_xauth_policy && is_xauth_server
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_xauth.started)
{
- kind = EVENT_SA_EXPIRE;
+ DBG(DBG_CONTROL,
+ DBG_log("starting XAUTH server")
+ )
+ xauth_send_request(st);
+ break;
}
- }
- break;
- case EVENT_NULL: /* non-event */
- case EVENT_REINIT_SECRET: /* Refresh cookie secret */
- default:
- bad_case(kind);
- }
- event_schedule(kind, delay, st);
- }
-
- /* tell whack and log of progress */
- {
- const char *story = state_story[st->st_state - STATE_MAIN_R0];
- enum rc_type w = RC_NEW_STATE + st->st_state;
- char sadetails[128];
-
- sadetails[0]='\0';
+ /* Wait for XAUTH request from server */
+ if (has_xauth_policy && !is_xauth_server
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_xauth.started)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("waiting for XAUTH request from server")
+ )
+ break;
+ }
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- char *b = sadetails;
- const char *ini = " {";
- const char *fin = "";
-
- /* -1 is to leave space for "fin" */
-
- if (st->st_esp.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sESP=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_esp.attrs.spi)
- , ntohl(st->st_esp.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_ah.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sAH=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_ah.attrs.spi)
- , ntohl(st->st_ah.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_ipcomp.present)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sIPCOMP=>0x%08x <0x%08x"
- , ini
- , ntohl(st->st_ipcomp.attrs.spi)
- , ntohl(st->st_ipcomp.our_spi));
- ini = " ";
- fin = "}";
- }
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->nat_traversal)
- {
- char oa[ADDRTOT_BUF];
- addrtot(&st->nat_oa, 0, oa, sizeof(oa));
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sNATOA=%s"
- , ini, oa);
- ini = " ";
- fin = "}";
- }
-
- /* advance b to end of string */
- b = b + strlen(b);
-
- if (st->st_dpd)
- {
- snprintf(b, sizeof(sadetails)-(b-sadetails)-1
- , "%sDPD"
- , ini);
- ini = " ";
- fin = "}";
- }
-
- strcat(b, fin);
- }
+ /* Should we start ModeConfig as a client? */
+ if (st->st_connection->spd.this.modecfg
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !(st->st_connection->policy & POLICY_MODECFG_PUSH)
+ && !st->st_modecfg.started)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("starting ModeCfg client in pull mode")
+ )
+ modecfg_send_request(st);
+ break;
+ }
- if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- /* log our success */
- plog("%s%s", story, sadetails);
- w = RC_SUCCESS;
- }
+ /* Should we start ModeConfig as a server? */
+ if (st->st_connection->spd.that.modecfg
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_modecfg.started
+ && (st->st_connection->policy & POLICY_MODECFG_PUSH))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("starting ModeCfg server in push mode")
+ )
+ modecfg_send_set(st);
+ break;
+ }
- /* tell whack our progress */
- whack_log(w
- , "%s: %s%s"
- , enum_name(&state_names, st->st_state)
- , story, sadetails);
- }
-
- has_xauth_policy = (st->st_connection->policy
- & (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
- != LEMPTY;
- is_xauth_server = (st->st_connection->policy
- & POLICY_XAUTH_SERVER)
- != LEMPTY;
-
- /* Should we start XAUTH as a server */
- if (has_xauth_policy && is_xauth_server
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_xauth.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("starting XAUTH server")
- )
- xauth_send_request(st);
- break;
- }
-
- /* Wait for XAUTH request from server */
- if (has_xauth_policy && !is_xauth_server
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_xauth.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("waiting for XAUTH request from server")
- )
- break;
- }
-
- /* Should we start ModeConfig as a client? */
- if (st->st_connection->spd.this.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !(st->st_connection->policy & POLICY_MODECFG_PUSH)
- && !st->st_modecfg.started)
- {
- DBG(DBG_CONTROL,
- DBG_log("starting ModeCfg client in pull mode")
- )
- modecfg_send_request(st);
- break;
- }
-
- /* Should we start ModeConfig as a server? */
- if (st->st_connection->spd.that.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_modecfg.started
- && (st->st_connection->policy & POLICY_MODECFG_PUSH))
- {
- DBG(DBG_CONTROL,
- DBG_log("starting ModeCfg server in push mode")
- )
- modecfg_send_set(st);
- break;
- }
-
- /* Wait for ModeConfig set from server */
- if (st->st_connection->spd.this.modecfg
- && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- && !st->st_modecfg.vars_set)
- {
- DBG(DBG_CONTROL,
- DBG_log("waiting for ModeCfg set from server")
- )
- break;
- }
+ /* Wait for ModeConfig set from server */
+ if (st->st_connection->spd.this.modecfg
+ && IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ && !st->st_modecfg.vars_set)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("waiting for ModeCfg set from server")
+ )
+ break;
+ }
- if (smc->flags & SMF_RELEASE_PENDING_P2)
- {
- /* Initiate any Quick Mode negotiations that
- * were waiting to piggyback on this Keying Channel.
- *
- * ??? there is a potential race condition
- * if we are the responder: the initial Phase 2
- * message might outrun the final Phase 1 message.
- * I think that retransmission will recover.
- */
- unpend(st);
- }
-
- if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
- release_whack(st);
- break;
-
- case STF_INTERNAL_ERROR:
- whack_log(RC_INTERNALERR + md->note
- , "%s: internal error"
- , enum_name(&state_names, st->st_state));
-
- DBG(DBG_CONTROL,
- DBG_log("state transition function for %s had internal error"
- , enum_name(&state_names, from_state)));
- break;
-
- default: /* a shortcut to STF_FAIL, setting md->note */
- passert(result > STF_FAIL);
- md->note = result - STF_FAIL;
- result = STF_FAIL;
- /* FALL THROUGH ... */
- case STF_FAIL:
- /* As it is, we act as if this message never happened:
- * whatever retrying was in place, remains in place.
- */
- whack_log(RC_NOTIFICATION + md->note
- , "%s: %s"
- , enum_name(&state_names, (st == NULL)? STATE_MAIN_R0:st->st_state)
- , enum_name(&notification_names, md->note));
-
- SEND_NOTIFICATION(md->note);
-
- DBG(DBG_CONTROL,
- DBG_log("state transition function for %s failed: %s"
- , enum_name(&state_names, from_state)
- , enum_name(&notification_names, md->note)));
- break;
- }
+ if (smc->flags & SMF_RELEASE_PENDING_P2)
+ {
+ /* Initiate any Quick Mode negotiations that
+ * were waiting to piggyback on this Keying Channel.
+ *
+ * ??? there is a potential race condition
+ * if we are the responder: the initial Phase 2
+ * message might outrun the final Phase 1 message.
+ * I think that retransmission will recover.
+ */
+ unpend(st);
+ }
+
+ if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ release_whack(st);
+ break;
+
+ case STF_INTERNAL_ERROR:
+ whack_log(RC_INTERNALERR + md->note
+ , "%s: internal error"
+ , enum_name(&state_names, st->st_state));
+
+ DBG(DBG_CONTROL,
+ DBG_log("state transition function for %s had internal error"
+ , enum_name(&state_names, from_state)));
+ break;
+
+ default: /* a shortcut to STF_FAIL, setting md->note */
+ passert(result > STF_FAIL);
+ md->note = result - STF_FAIL;
+ result = STF_FAIL;
+ /* FALL THROUGH ... */
+ case STF_FAIL:
+ /* As it is, we act as if this message never happened:
+ * whatever retrying was in place, remains in place.
+ */
+ whack_log(RC_NOTIFICATION + md->note
+ , "%s: %s"
+ , enum_name(&state_names, (st == NULL)? STATE_MAIN_R0:st->st_state)
+ , enum_name(&notification_names, md->note));
+
+ SEND_NOTIFICATION(md->note);
+
+ DBG(DBG_CONTROL,
+ DBG_log("state transition function for %s failed: %s"
+ , enum_name(&state_names, from_state)
+ , enum_name(&notification_names, md->note)));
+ break;
+ }
}
diff --git a/src/pluto/demux.h b/src/pluto/demux.h
index 0348b3579..4faf6e532 100644
--- a/src/pluto/demux.h
+++ b/src/pluto/demux.h
@@ -10,13 +10,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: demux.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include "packet.h"
-struct state; /* forward declaration of tag */
+struct state; /* forward declaration of tag */
extern void init_demux(void);
extern bool send_packet(struct state *st, const char *where);
extern void comm_handle(const struct iface *ifp);
@@ -36,9 +34,9 @@ extern u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];
*/
struct payload_digest {
- pb_stream pbs;
- union payload payload;
- struct payload_digest *next; /* of same kind */
+ pb_stream pbs;
+ union payload payload;
+ struct payload_digest *next; /* of same kind */
};
/* message digest
@@ -46,30 +44,30 @@ struct payload_digest {
*/
struct msg_digest {
- struct msg_digest *next; /* for free list */
- chunk_t raw_packet; /* if encrypted, received packet before decryption */
- const struct iface *iface; /* interface on which message arrived */
- ip_address sender; /* where message came from */
- u_int16_t sender_port; /* host order */
- pb_stream packet_pbs; /* whole packet */
- pb_stream message_pbs; /* message to be processed */
- struct isakmp_hdr hdr; /* message's header */
- bool encrypted; /* was it encrypted? */
- enum state_kind from_state; /* state we started in */
- const struct state_microcode *smc; /* microcode for initial state */
- struct state *st; /* current state object */
- pb_stream reply; /* room for reply */
- pb_stream rbody; /* room for reply body (after header) */
- notification_t note; /* reason for failure */
- bool dpd; /* peer supports RFC 3706 DPD */
- bool openpgp; /* peer supports OpenPGP certificates */
+ struct msg_digest *next; /* for free list */
+ chunk_t raw_packet; /* if encrypted, received packet before decryption */
+ const struct iface *iface; /* interface on which message arrived */
+ ip_address sender; /* where message came from */
+ u_int16_t sender_port; /* host order */
+ pb_stream packet_pbs; /* whole packet */
+ pb_stream message_pbs; /* message to be processed */
+ struct isakmp_hdr hdr; /* message's header */
+ bool encrypted; /* was it encrypted? */
+ enum state_kind from_state; /* state we started in */
+ const struct state_microcode *smc; /* microcode for initial state */
+ struct state *st; /* current state object */
+ pb_stream reply; /* room for reply */
+ pb_stream rbody; /* room for reply body (after header) */
+ notification_t note; /* reason for failure */
+ bool dpd; /* peer supports RFC 3706 DPD */
+ bool openpgp; /* peer supports OpenPGP certificates */
# define PAYLIMIT 40
- struct payload_digest
- digest[PAYLIMIT],
- *digest_roof,
- *chain[ISAKMP_NEXT_ROOF];
- unsigned short nat_traversal_vid;
+ struct payload_digest
+ digest[PAYLIMIT],
+ *digest_roof,
+ *chain[ISAKMP_NEXT_ROOF];
+ unsigned short nat_traversal_vid;
};
extern void release_md(struct msg_digest *md);
@@ -79,11 +77,11 @@ extern void release_md(struct msg_digest *md);
*/
typedef enum {
- STF_IGNORE, /* don't respond */
- STF_SUSPEND, /* unfinished -- don't release resources */
- STF_OK, /* success */
- STF_INTERNAL_ERROR, /* discard everything, we failed */
- STF_FAIL /* discard everything, something failed. notification_t added. */
+ STF_IGNORE, /* don't respond */
+ STF_SUSPEND, /* unfinished -- don't release resources */
+ STF_OK, /* success */
+ STF_INTERNAL_ERROR, /* discard everything, we failed */
+ STF_FAIL /* discard everything, something failed. notification_t added. */
} stf_status;
typedef stf_status state_transition_fn(struct msg_digest *md);
diff --git a/src/pluto/dnskey.c b/src/pluto/dnskey.c
index 8ba0f7b73..ed901ade5 100644
--- a/src/pluto/dnskey.c
+++ b/src/pluto/dnskey.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: dnskey.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdlib.h>
@@ -26,32 +24,34 @@
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
-#include <netdb.h> /* ??? for h_errno */
+#include <netdb.h> /* ??? for h_errno */
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
#include "constants.h"
-#include "adns.h" /* needs <resolv.h> */
+#include "adns.h" /* needs <resolv.h> */
#include "defs.h"
#include "log.h"
#include "id.h"
#include "connections.h"
-#include "keys.h" /* needs connections.h */
+#include "keys.h" /* needs connections.h */
#include "dnskey.h"
#include "packet.h"
#include "timer.h"
/* somebody has to decide */
-#define MAX_TXT_RDATA ((MAX_KEY_BYTES * 8 / 6) + 40) /* somewhat arbitrary overkill */
+#define MAX_TXT_RDATA ((MAX_KEY_BYTES * 8 / 6) + 40) /* somewhat arbitrary overkill */
/* ADNS stuff */
-int adns_qfd = NULL_FD, /* file descriptor for sending queries to adns (O_NONBLOCK) */
- adns_afd = NULL_FD; /* file descriptor for receiving answers from adns */
+int adns_qfd = NULL_FD, /* file descriptor for sending queries to adns (O_NONBLOCK) */
+ adns_afd = NULL_FD; /* file descriptor for receiving answers from adns */
static pid_t adns_pid = 0;
-const char *pluto_adns_option = NULL; /* path from --pluto_adns */
+const char *pluto_adns_option = NULL; /* path from --pluto_adns */
int adns_restart_count;
#define ADNS_RESTART_MAX 20
@@ -59,152 +59,168 @@ int adns_restart_count;
void
init_adns(void)
{
- const char *adns_path = pluto_adns_option;
+ const char *adns_path = pluto_adns_option;
#ifndef USE_LWRES
- static const char adns_name[] = "_pluto_adns";
- const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
+ static const char adns_name[] = "_pluto_adns";
+ const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
#else /* USE_LWRES */
- static const char adns_name[] = "lwdnsq";
- const char *helper_bin_dir = getenv("IPSEC_EXECDIR");
+ static const char adns_name[] = "lwdnsq";
+ const char *helper_bin_dir = getenv("IPSEC_EXECDIR");
#endif /* USE_LWRES */
- char adns_path_space[4096]; /* plenty long? */
- int qfds[2];
- int afds[2];
-
- /* find a pathname to the ADNS program */
- if (adns_path == NULL)
- {
- /* pathname was not specified as an option: build it.
- * First, figure out the directory to be used.
- */
- ssize_t n;
+ char adns_path_space[4096]; /* plenty long? */
+ int qfds[2];
+ int afds[2];
- if (helper_bin_dir != NULL)
+ /* find a pathname to the ADNS program */
+ if (adns_path == NULL)
{
- n = strlen(helper_bin_dir);
- if ((size_t)n <= sizeof(adns_path_space) - sizeof(adns_name))
- {
- strcpy(adns_path_space, helper_bin_dir);
- if (n > 0 && adns_path_space[n -1] != '/')
- adns_path_space[n++] = '/';
- }
- }
- else
- {
- /* The program will be in the same directory as Pluto,
- * so we use the sympolic link /proc/self/exe to
- * tell us of the path prefix.
- */
- n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
-
- if (n < 0)
- exit_log_errno((e
- , "readlink(\"/proc/self/exe\") failed in init_adns()"));
-
- }
-
- if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
- exit_log("path to %s is too long", adns_name);
+ /* pathname was not specified as an option: build it.
+ * First, figure out the directory to be used.
+ */
+ ssize_t n;
- while (n > 0 && adns_path_space[n - 1] != '/')
- n--;
+ if (helper_bin_dir != NULL)
+ {
+ n = strlen(helper_bin_dir);
+ if ((size_t)n <= sizeof(adns_path_space) - sizeof(adns_name))
+ {
+ strcpy(adns_path_space, helper_bin_dir);
+ if (n > 0 && adns_path_space[n -1] != '/')
+ {
+ adns_path_space[n++] = '/';
+ }
+ }
+ }
+ else
+ {
+ /* The program will be in the same directory as Pluto,
+ * so we use the sympolic link /proc/self/exe to
+ * tell us of the path prefix.
+ */
+ n = readlink("/proc/self/exe", adns_path_space, sizeof(adns_path_space));
+
+ if (n < 0)
+ {
+ exit_log_errno((e
+ , "readlink(\"/proc/self/exe\") failed in init_adns()"));
+ }
+ }
- strcpy(adns_path_space + n, adns_name);
- adns_path = adns_path_space;
- }
- if (access(adns_path, X_OK) < 0)
- exit_log_errno((e, "%s missing or not executable", adns_path));
+ if ((size_t)n > sizeof(adns_path_space) - sizeof(adns_name))
+ {
+ exit_log("path to %s is too long", adns_name);
+ }
- if (pipe(qfds) != 0 || pipe(afds) != 0)
- exit_log_errno((e, "pipe(2) failed in init_adns()"));
+ while (n > 0 && adns_path_space[n - 1] != '/')
+ {
+ n--;
+ }
+ strcpy(adns_path_space + n, adns_name);
+ adns_path = adns_path_space;
+ }
+ if (access(adns_path, X_OK) < 0)
+ {
+ exit_log_errno((e, "%s missing or not executable", adns_path));
+ }
- adns_pid = fork();
- switch (adns_pid)
- {
- case -1:
- exit_log_errno((e, "fork() failed in init_adns()"));
+ if (pipe(qfds) != 0 || pipe(afds) != 0)
+ {
+ exit_log_errno((e, "pipe(2) failed in init_adns()"));
+ }
- case 0:
- /* child */
+ adns_pid = fork();
+ switch (adns_pid)
{
- /* Make stdin and stdout our pipes.
- * Take care to handle case where pipes already use these fds.
- */
- if (afds[1] == 0)
- afds[1] = dup(afds[1]); /* avoid being overwritten */
- if (qfds[0] != 0)
- {
- dup2(qfds[0], 0);
+ case -1:
+ exit_log_errno((e, "fork() failed in init_adns()"));
+
+ case 0:
+ /* child */
+ {
+ /* Make stdin and stdout our pipes.
+ * Take care to handle case where pipes already use these fds.
+ */
+ if (afds[1] == 0)
+ {
+ afds[1] = dup(afds[1]); /* avoid being overwritten */
+ }
+ if (qfds[0] != 0)
+ {
+ dup2(qfds[0], 0);
+ close(qfds[0]);
+ }
+ if (afds[1] != 1)
+ {
+ dup2(afds[1], 1);
+ close(qfds[1]);
+ }
+ if (afds[0] > 1)
+ {
+ close(afds[0]);
+ }
+ if (afds[1] > 1)
+ {
+ close(afds[1]);
+ }
+ DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
+
+ execlp(adns_path, adns_name, NULL);
+ exit_log_errno((e, "execlp of %s failed", adns_path));
+ }
+ default:
+ /* parent */
close(qfds[0]);
- }
- if (afds[1] != 1)
- {
- dup2(afds[1], 1);
- close(qfds[1]);
- }
- if (afds[0] > 1)
- close(afds[0]);
- if (afds[1] > 1)
+ adns_qfd = qfds[1];
+ adns_afd = afds[0];
close(afds[1]);
-
- DBG(DBG_DNS, execlp(adns_path, adns_name, "-d", NULL));
-
- execlp(adns_path, adns_name, NULL);
- exit_log_errno((e, "execlp of %s failed", adns_path));
+ fcntl(adns_qfd, F_SETFD, FD_CLOEXEC);
+ fcntl(adns_afd, F_SETFD, FD_CLOEXEC);
+ fcntl(adns_qfd, F_SETFL, O_NONBLOCK);
+ break;
}
-
- default:
- /* parent */
- close(qfds[0]);
- adns_qfd = qfds[1];
- adns_afd = afds[0];
- close(afds[1]);
- fcntl(adns_qfd, F_SETFD, FD_CLOEXEC);
- fcntl(adns_afd, F_SETFD, FD_CLOEXEC);
- fcntl(adns_qfd, F_SETFL, O_NONBLOCK);
- break;
- }
}
void
stop_adns(void)
{
- close_any(adns_qfd);
- adns_qfd = NULL_FD;
- close_any(adns_afd);
- adns_afd = NULL_FD;
-
- if (adns_pid != 0)
- {
- int status;
- pid_t p = waitpid(adns_pid, &status, 0);
+ close_any(adns_qfd);
+ adns_qfd = NULL_FD;
+ close_any(adns_afd);
+ adns_afd = NULL_FD;
- if (p == -1)
- {
- log_errno((e, "waitpid for ADNS process failed"));
- }
- else if (WIFEXITED(status))
+ if (adns_pid != 0)
{
- if (WEXITSTATUS(status) != 0)
- plog("ADNS process exited with status %d"
- , (int) WEXITSTATUS(status));
- }
- else if (WIFSIGNALED(status))
- {
- plog("ADNS process terminated by signal %d", (int)WTERMSIG(status));
- }
- else
- {
- plog("wait for end of ADNS process returned odd status 0x%x\n"
- , status);
+ int status;
+ pid_t p = waitpid(adns_pid, &status, 0);
+
+ if (p == -1)
+ {
+ log_errno((e, "waitpid for ADNS process failed"));
+ }
+ else if (WIFEXITED(status))
+ {
+ if (WEXITSTATUS(status) != 0)
+ {
+ plog("ADNS process exited with status %d"
+ , (int) WEXITSTATUS(status));
+ }
+ }
+ else if (WIFSIGNALED(status))
+ {
+ plog("ADNS process terminated by signal %d", (int)WTERMSIG(status));
+ }
+ else
+ {
+ plog("wait for end of ADNS process returned odd status 0x%x\n"
+ , status);
+ }
}
- }
}
/* tricky macro to pass any hot potato */
-#define TRY(x) { err_t ugh = x; if (ugh != NULL) return ugh; }
+#define TRY(x) { err_t ugh = x; if (ugh != NULL) return ugh; }
/* Process TXT X-IPsec-Server record, accumulating relevant ones
@@ -225,246 +241,270 @@ static const char our_TXT_attr[] = our_TXT_attr_string;
static err_t
decode_iii(u_char **pp, struct id *gw_id)
{
- u_char *p = *pp + strspn(*pp, " \t");
- u_char *e = p + strcspn(p, " \t");
- u_char under = *e;
-
- if (p == e)
- return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
-
- *e = '\0';
- if (*p == '@')
- {
- /* gateway specification in this record is @FQDN */
- err_t ugh = atoid(p, gw_id, FALSE);
-
- if (ugh != NULL)
- return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
- , ugh);
- }
- else
- {
- /* gateway specification is numeric */
- ip_address ip;
- err_t ugh = tnatoaddr(p, e-p
- , strchr(p, ':') == NULL? AF_INET : AF_INET6
- , &ip);
-
- if (ugh != NULL)
- return builddiag("malformed IP address in TXT " our_TXT_attr_string ": %s"
- , ugh);
-
- if (isanyaddr(&ip))
- return "gateway address must not be 0.0.0.0 or 0::0";
-
- iptoid(&ip, gw_id);
- }
-
- *e = under;
- *pp = e + strspn(e, " \t");
-
- return NULL;
+ u_char *p = *pp + strspn(*pp, " \t");
+ u_char *e = p + strcspn(p, " \t");
+ u_char under = *e;
+
+ if (p == e)
+ {
+ return "TXT " our_TXT_attr_string " badly formed (no gateway specified)";
+ }
+ *e = '\0';
+ if (*p == '@')
+ {
+ /* gateway specification in this record is @FQDN */
+ err_t ugh = atoid(p, gw_id, FALSE);
+
+ if (ugh != NULL)
+ {
+ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
+ , ugh);
+ }
+ }
+ else
+ {
+ /* gateway specification is numeric */
+ ip_address ip;
+ err_t ugh = tnatoaddr(p, e-p
+ , strchr(p, ':') == NULL? AF_INET : AF_INET6
+ , &ip);
+
+ if (ugh != NULL)
+ {
+ return builddiag("malformed IP address in TXT " our_TXT_attr_string ": %s"
+ , ugh);
+ }
+ if (isanyaddr(&ip))
+ {
+ return "gateway address must not be 0.0.0.0 or 0::0";
+ }
+ iptoid(&ip, gw_id);
+ }
+
+ *e = under;
+ *pp = e + strspn(e, " \t");
+
+ return NULL;
}
static err_t
process_txt_rr_body(u_char *str
-, bool doit /* should we capture information? */
+, bool doit /* should we capture information? */
, enum dns_auth_level dns_auth_level
, struct adns_continuation *const cr)
{
- const struct id *client_id = &cr->id; /* subject of query */
- u_char *p = str;
- unsigned long pref = 0;
- struct gw_info gi;
+ const struct id *client_id = &cr->id; /* subject of query */
+ u_char *p = str;
+ unsigned long pref = 0;
+ struct gw_info gi;
+
+ p += strspn(p, " \t"); /* ignore leading whitespace */
- p += strspn(p, " \t"); /* ignore leading whitespace */
+ /* is this for us? */
+ if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
+ {
+ return NULL; /* neither interesting nor bad */
+ }
- /* is this for us? */
- if (strncasecmp(p, our_TXT_attr, sizeof(our_TXT_attr)-1) != 0)
- return NULL; /* neither interesting nor bad */
+ p += sizeof(our_TXT_attr) - 1; /* ignore our attribute name */
+ p += strspn(p, " \t"); /* ignore leading whitespace */
- p += sizeof(our_TXT_attr) - 1; /* ignore our attribute name */
- p += strspn(p, " \t"); /* ignore leading whitespace */
+ /* decode '(' nnn ')' */
+ if (*p != '(')
+ {
+ return "X-IPsec-Server missing '('";
+ }
- /* decode '(' nnn ')' */
- if (*p != '(')
- return "X-IPsec-Server missing '('";
+ {
+ char *e;
- {
- char *e;
+ p++;
+ pref = strtoul(p, &e, 0);
+ if ((u_char *)e == p)
+ {
+ return "malformed X-IPsec-Server priority";
+ }
+ p = e + strspn(e, " \t");
- p++;
- pref = strtoul(p, &e, 0);
- if ((u_char *)e == p)
- return "malformed X-IPsec-Server priority";
+ if (*p != ')')
+ {
+ return "X-IPsec-Server priority missing ')'";
+ }
+ p++;
+ p += strspn(p, " \t");
- p = e + strspn(e, " \t");
+ if (pref > 0xFFFF)
+ {
+ return "X-IPsec-Server priority larger than 0xFFFF";
+ }
+ }
- if (*p != ')')
- return "X-IPsec-Server priority missing ')'";
+ /* time for '=' */
+ if (*p != '=')
+ {
+ return "X-IPsec-Server priority missing '='";
+ }
p++;
p += strspn(p, " \t");
- if (pref > 0xFFFF)
- return "X-IPsec-Server priority larger than 0xFFFF";
- }
-
- /* time for '=' */
+ /* Decode iii (Security Gateway ID). */
- if (*p != '=')
- return "X-IPsec-Server priority missing '='";
+ zero(&gi); /* before first use */
- p++;
- p += strspn(p, " \t");
+ TRY(decode_iii(&p, &gi.gw_id)); /* will need to unshare_id_content */
- /* Decode iii (Security Gateway ID). */
-
- zero(&gi); /* before first use */
-
- TRY(decode_iii(&p, &gi.gw_id)); /* will need to unshare_id_content */
-
- if (!cr->sgw_specified)
- {
- /* we don't know the peer's ID (because we are initiating
- * and we don't know who to initiate with.
- * So we're looking for gateway specs with an IP address
- */
- if (!id_is_ipaddr(&gi.gw_id))
+ if (!cr->sgw_specified)
{
- DBG(DBG_DNS,
+ /* we don't know the peer's ID (because we are initiating
+ * and we don't know who to initiate with.
+ * So we're looking for gateway specs with an IP address
+ */
+ if (!id_is_ipaddr(&gi.gw_id))
{
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
-
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
- DBG_log("TXT %s record for %s: security gateway %s;"
- " ignored because gateway's IP is unspecified"
- , our_TXT_attr, cidb, gwidb);
- });
- return NULL; /* we cannot use this record, but it isn't wrong */
+ DBG(DBG_DNS,
+ {
+ char cidb[BUF_LEN];
+ char gwidb[BUF_LEN];
+
+ idtoa(client_id, cidb, sizeof(cidb));
+ idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
+ DBG_log("TXT %s record for %s: security gateway %s;"
+ " ignored because gateway's IP is unspecified"
+ , our_TXT_attr, cidb, gwidb);
+ });
+ return NULL; /* we cannot use this record, but it isn't wrong */
+ }
}
- }
- else
- {
- /* We do know the peer's ID (because we are responding)
- * So we're looking for gateway specs specifying this known ID.
- */
- const struct id *peer_id = &cr->sgw_id;
-
- if (!same_id(peer_id, &gi.gw_id))
+ else
{
- DBG(DBG_DNS,
+ /* We do know the peer's ID (because we are responding)
+ * So we're looking for gateway specs specifying this known ID.
+ */
+ const struct id *peer_id = &cr->sgw_id;
+
+ if (!same_id(peer_id, &gi.gw_id))
{
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
- char pidb[BUF_LEN];
-
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
- idtoa(peer_id, pidb, sizeof(pidb));
- DBG_log("TXT %s record for %s: security gateway %s;"
- " ignored -- looking to confirm %s as gateway"
- , our_TXT_attr, cidb, gwidb, pidb);
- });
- return NULL; /* we cannot use this record, but it isn't wrong */
+ DBG(DBG_DNS,
+ {
+ char cidb[BUF_LEN];
+ char gwidb[BUF_LEN];
+ char pidb[BUF_LEN];
+
+ idtoa(client_id, cidb, sizeof(cidb));
+ idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
+ idtoa(peer_id, pidb, sizeof(pidb));
+ DBG_log("TXT %s record for %s: security gateway %s;"
+ " ignored -- looking to confirm %s as gateway"
+ , our_TXT_attr, cidb, gwidb, pidb);
+ });
+ return NULL; /* we cannot use this record, but it isn't wrong */
+ }
}
- }
-
- if (doit)
- {
- /* really accept gateway */
- struct gw_info **gwip; /* gateway insertion point */
- gi.client_id = *client_id; /* will need to unshare_id_content */
-
- /* decode optional kkk: base 64 encoding of key */
-
- gi.gw_key_present = *p != '\0';
- if (gi.gw_key_present)
+ if (doit)
{
- /* Decode base 64 encoding of key.
- * Similar code is in process_lwdnsq_key.
- */
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- struct RSA_public_key r;
-
- err_t ugh = ttodatav(p, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
-
- if (ugh != NULL)
- return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- ugh = unpack_RSA_public_key(&r, &kbc);
- if (ugh != NULL)
- return builddiag("invalid key data: %s", ugh);
-
- /* now find a key entry to put it in */
- gi.key = public_key_from_rsa(&r);
-
- free_RSA_public_content(&r);
+ /* really accept gateway */
+ struct gw_info **gwip; /* gateway insertion point */
- unreference_key(&cr->last_info);
- cr->last_info = reference_key(gi.key);
- }
-
- /* we're home free! Allocate everything and add to gateways list. */
- gi.refcnt = 1;
- gi.pref = pref;
- gi.key->dns_auth_level = dns_auth_level;
- gi.key->last_tried_time = gi.key->last_worked_time = NO_TIME;
-
- /* find insertion point */
- for (gwip = &cr->gateways_from_dns; *gwip != NULL && (*gwip)->pref < pref; gwip = &(*gwip)->next)
- ;
+ gi.client_id = *client_id; /* will need to unshare_id_content */
- DBG(DBG_DNS,
- {
- char cidb[BUF_LEN];
- char gwidb[BUF_LEN];
+ /* decode optional kkk: base 64 encoding of key */
- idtoa(client_id, cidb, sizeof(cidb));
- idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
+ gi.gw_key_present = *p != '\0';
if (gi.gw_key_present)
{
- DBG_log("gateway for %s is %s with key %s"
- , cidb, gwidb, gi.key->u.rsa.keyid);
+ /* Decode base 64 encoding of key.
+ * Similar code is in process_lwdnsq_key.
+ */
+ u_char buf[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
+ size_t sz;
+ err_t ugh;
+ chunk_t rfc3110_chunk;
+ public_key_t *key;
+
+ ugh = ttodatav(p, 0, 64, buf, sizeof(buf), &sz,
+ diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
+ if (ugh)
+ {
+ return builddiag("malformed key data: %s", ugh);
+ }
+ if (sz > sizeof(buf))
+ {
+ return builddiag("key data larger than %lu bytes",
+ (unsigned long) sizeof(buf));
+ }
+ rfc3110_chunk = chunk_create(buf, sz);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_RFC_3110, rfc3110_chunk,
+ BUILD_END);
+ if (key == NULL)
+ {
+ return builddiag("invalid key data");
+ }
+
+ /* now find a key entry to put it in */
+ gi.key = public_key_from_rsa(key);
+
+ unreference_key(&cr->last_info);
+ cr->last_info = reference_key(gi.key);
}
- else
- {
- DBG_log("gateway for %s is %s; no key specified"
- , cidb, gwidb);
- }
- });
- gi.next = *gwip;
- *gwip = clone_thing(gi, "gateway info");
- unshare_id_content(&(*gwip)->gw_id);
- unshare_id_content(&(*gwip)->client_id);
- }
+ /* we're home free! Allocate everything and add to gateways list. */
+ gi.refcnt = 1;
+ gi.pref = pref;
+ gi.key->dns_auth_level = dns_auth_level;
+ gi.key->last_tried_time = gi.key->last_worked_time = NO_TIME;
+
+ /* find insertion point */
+ for (gwip = &cr->gateways_from_dns; *gwip != NULL && (*gwip)->pref < pref; gwip = &(*gwip)->next)
+ ;
+
+ DBG(DBG_DNS,
+ {
+ char cidb[BUF_LEN];
+ char gwidb[BUF_LEN];
+ identification_t *keyid;
+ public_key_t *pub_key;
+
+ idtoa(client_id, cidb, sizeof(cidb));
+ idtoa(&gi.gw_id, gwidb, sizeof(gwidb));
+ pub_key = gi.key->public_key;
+ keyid = pub_key->get_id(pub_key, ID_PUBKEY_SHA1);
+
+ if (gi.gw_key_present)
+ {
+ DBG_log("gateway for %s is %s with key %Y"
+ , cidb, gwidb, keyid);
+ }
+ else
+ {
+ DBG_log("gateway for %s is %s; no key specified"
+ , cidb, gwidb);
+ }
+ });
+
+ gi.next = *gwip;
+ *gwip = clone_thing(gi);
+ unshare_id_content(&(*gwip)->gw_id);
+ unshare_id_content(&(*gwip)->client_id);
+ }
- return NULL;
+ return NULL;
}
static const char *
rr_typename(int type)
{
- switch (type)
- {
- case T_TXT:
- return "TXT";
- case T_KEY:
- return "KEY";
- default:
- return "???";
- }
+ switch (type)
+ {
+ case T_TXT:
+ return "TXT";
+ case T_KEY:
+ return "KEY";
+ default:
+ return "???";
+ }
}
@@ -476,72 +516,72 @@ process_lwdnsq_key(u_char *str
, enum dns_auth_level dns_auth_level
, struct adns_continuation *const cr)
{
- /* fields of KEY record. See RFC 2535 3.1 KEY RDATA format. */
- unsigned long flags /* 16 bits */
- , protocol /* 8 bits */
- , algorithm; /* 8 bits */
-
- char *rest = str
- , *p
- , *endofnumber;
-
- /* flags */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing flags";
-
- flags = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed flags";
-
- /* protocol */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing protocol";
-
- protocol = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed protocol";
-
- /* algorithm */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing algorithm";
-
- algorithm = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed algorithm";
-
- /* is this key interesting? */
- if (protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
- && algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
- && (flags & 0x8000ul) == 0 /* use for authentication (3.1.2) */
- && (flags & 0x2CF0ul) == 0) /* must be zero */
- {
- /* Decode base 64 encoding of key.
- * Similar code is in process_txt_rr_body.
- */
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- err_t ugh = ttodatav(rest, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_IGNORESPACE);
-
- if (ugh != NULL)
- return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &kbc
- , &cr->keys_from_dns));
-
- /* keep a reference to last one */
- unreference_key(&cr->last_info);
- cr->last_info = reference_key(cr->keys_from_dns->key);
- }
- return NULL;
+ /* fields of KEY record. See RFC 2535 3.1 KEY RDATA format. */
+ unsigned long flags /* 16 bits */
+ , protocol /* 8 bits */
+ , algorithm; /* 8 bits */
+
+ char *rest = str
+ , *p
+ , *endofnumber;
+
+ /* flags */
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq KEY: missing flags";
+
+ flags = strtoul(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq KEY: malformed flags";
+
+ /* protocol */
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq KEY: missing protocol";
+
+ protocol = strtoul(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq KEY: malformed protocol";
+
+ /* algorithm */
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq KEY: missing algorithm";
+
+ algorithm = strtoul(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq KEY: malformed algorithm";
+
+ /* is this key interesting? */
+ if (protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
+ && algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
+ && (flags & 0x8000ul) == 0 /* use for authentication (3.1.2) */
+ && (flags & 0x2CF0ul) == 0) /* must be zero */
+ {
+ /* Decode base 64 encoding of key.
+ * Similar code is in process_txt_rr_body.
+ */
+ u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
+ chunk_t kbc;
+ err_t ugh = ttodatav(rest, 0, 64, kb, sizeof(kb), &kbc.len
+ , diag_space, sizeof(diag_space), TTODATAV_IGNORESPACE);
+
+ if (ugh != NULL)
+ return builddiag("malformed key data: %s", ugh);
+
+ if (kbc.len > sizeof(kb))
+ return builddiag("key data larger than %lu bytes"
+ , (unsigned long) sizeof(kb));
+
+ kbc.ptr = kb;
+ TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &kbc
+ , &cr->keys_from_dns));
+
+ /* keep a reference to last one */
+ unreference_key(&cr->last_info);
+ cr->last_info = reference_key(cr->keys_from_dns->key);
+ }
+ return NULL;
}
# endif /* USE_KEYRR */
@@ -580,158 +620,158 @@ process_lwdnsq_key(u_char *str
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
struct qr_header {
- u_int16_t id; /* 16-bit identifier to match query */
+ u_int16_t id; /* 16-bit identifier to match query */
- u_int16_t stuff; /* packed crud: */
+ u_int16_t stuff; /* packed crud: */
-#define QRS_QR 0x8000 /* QR: on if this is a response */
+#define QRS_QR 0x8000 /* QR: on if this is a response */
-#define QRS_OPCODE_SHIFT 11 /* OPCODE field */
-#define QRS_OPCODE_MASK 0xF
-#define QRSO_QUERY 0 /* standard query */
-#define QRSO_IQUERY 1 /* inverse query */
-#define QRSO_STATUS 2 /* server status request query */
+#define QRS_OPCODE_SHIFT 11 /* OPCODE field */
+#define QRS_OPCODE_MASK 0xF
+#define QRSO_QUERY 0 /* standard query */
+#define QRSO_IQUERY 1 /* inverse query */
+#define QRSO_STATUS 2 /* server status request query */
-#define QRS_AA 0x0400 /* AA: on if Authoritative Answer */
-#define QRS_TC 0x0200 /* TC: on if truncation happened */
-#define QRS_RD 0x0100 /* RD: on if recursion desired */
-#define QRS_RA 0x0080 /* RA: on if recursion available */
-#define QRS_Z 0x0040 /* Z: reserved; must be zero */
-#define QRS_AD 0x0020 /* AD: on if authentic data (RFC 2535) */
-#define QRS_CD 0x0010 /* AD: on if checking disabled (RFC 2535) */
+#define QRS_AA 0x0400 /* AA: on if Authoritative Answer */
+#define QRS_TC 0x0200 /* TC: on if truncation happened */
+#define QRS_RD 0x0100 /* RD: on if recursion desired */
+#define QRS_RA 0x0080 /* RA: on if recursion available */
+#define QRS_Z 0x0040 /* Z: reserved; must be zero */
+#define QRS_AD 0x0020 /* AD: on if authentic data (RFC 2535) */
+#define QRS_CD 0x0010 /* AD: on if checking disabled (RFC 2535) */
-#define QRS_RCODE_SHIFT 0 /* RCODE field: response code */
-#define QRS_RCODE_MASK 0xF
-#define QRSR_OK 0
+#define QRS_RCODE_SHIFT 0 /* RCODE field: response code */
+#define QRS_RCODE_MASK 0xF
+#define QRSR_OK 0
- u_int16_t qdcount; /* number of entries in question section */
- u_int16_t ancount; /* number of resource records in answer section */
- u_int16_t nscount; /* number of name server resource records in authority section */
- u_int16_t arcount; /* number of resource records in additional records section */
+ u_int16_t qdcount; /* number of entries in question section */
+ u_int16_t ancount; /* number of resource records in answer section */
+ u_int16_t nscount; /* number of name server resource records in authority section */
+ u_int16_t arcount; /* number of resource records in additional records section */
};
static field_desc qr_header_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "ID", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "stuff", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "QD Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Answer Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Authority Count", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Additional Count", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_nat, 16/BITS_PER_BYTE, "ID", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "stuff", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "QD Count", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "Answer Count", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "Authority Count", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "Additional Count", NULL },
+ { ft_end, 0, NULL, NULL }
};
static struct_desc qr_header_desc = {
- "Query Response Header",
- qr_header_fields,
- sizeof(struct qr_header)
+ "Query Response Header",
+ qr_header_fields,
+ sizeof(struct qr_header)
};
/* Messages for codes in RCODE (see RFC 1035 4.1.1) */
static const err_t rcode_text[QRS_RCODE_MASK + 1] = {
- NULL, /* not an error */
- "Format error - The name server was unable to interpret the query",
- "Server failure - The name server was unable to process this query"
- " due to a problem with the name server",
- "Name Error - Meaningful only for responses from an authoritative name"
- " server, this code signifies that the domain name referenced in"
- " the query does not exist",
- "Not Implemented - The name server does not support the requested"
- " kind of query",
- "Refused - The name server refuses to perform the specified operation"
- " for policy reasons",
- /* the rest are reserved for future use */
- };
+ NULL, /* not an error */
+ "Format error - The name server was unable to interpret the query",
+ "Server failure - The name server was unable to process this query"
+ " due to a problem with the name server",
+ "Name Error - Meaningful only for responses from an authoritative name"
+ " server, this code signifies that the domain name referenced in"
+ " the query does not exist",
+ "Not Implemented - The name server does not support the requested"
+ " kind of query",
+ "Refused - The name server refuses to perform the specified operation"
+ " for policy reasons",
+ /* the rest are reserved for future use */
+ };
/* throw away a possibly compressed domain name */
static err_t
eat_name(pb_stream *pbs)
{
- u_char name_buf[NS_MAXDNAME + 2];
- u_char *ip = pbs->cur;
- unsigned oi = 0;
- unsigned jump_count = 0;
-
- for (;;)
- {
- u_int8_t b;
+ u_char name_buf[NS_MAXDNAME + 2];
+ u_char *ip = pbs->cur;
+ unsigned oi = 0;
+ unsigned jump_count = 0;
- if (ip >= pbs->roof)
- return "ran out of message while skipping domain name";
-
- b = *ip++;
- if (jump_count == 0)
- pbs->cur = ip;
-
- if (b == 0)
- break;
-
- switch (b & 0xC0)
+ for (;;)
{
- case 0x00:
- /* we grab the next b characters */
- if (oi + b > NS_MAXDNAME)
- return "domain name too long";
+ u_int8_t b;
- if (pbs->roof - ip <= b)
- return "domain name falls off end of message";
+ if (ip >= pbs->roof)
+ return "ran out of message while skipping domain name";
- if (oi != 0)
- name_buf[oi++] = '.';
-
- memcpy(name_buf + oi, ip, b);
- oi += b;
- ip += b;
+ b = *ip++;
if (jump_count == 0)
- pbs->cur = ip;
- break;
-
- case 0xC0:
- {
- unsigned ix;
-
- if (ip >= pbs->roof)
- return "ran out of message in middle of compressed domain name";
-
- ix = ((b & ~0xC0u) << 8) | *ip++;
- if (jump_count == 0)
pbs->cur = ip;
- if (ix >= pbs_room(pbs))
- return "impossible compressed domain name";
+ if (b == 0)
+ break;
- /* Avoid infinite loop.
- * There can be no more jumps than there are bytes
- * in the packet. Not a tight limit, but good enough.
- */
- jump_count++;
- if (jump_count > pbs_room(pbs))
- return "loop in compressed domain name";
-
- ip = pbs->start + ix;
+ switch (b & 0xC0)
+ {
+ case 0x00:
+ /* we grab the next b characters */
+ if (oi + b > NS_MAXDNAME)
+ return "domain name too long";
+
+ if (pbs->roof - ip <= b)
+ return "domain name falls off end of message";
+
+ if (oi != 0)
+ name_buf[oi++] = '.';
+
+ memcpy(name_buf + oi, ip, b);
+ oi += b;
+ ip += b;
+ if (jump_count == 0)
+ pbs->cur = ip;
+ break;
+
+ case 0xC0:
+ {
+ unsigned ix;
+
+ if (ip >= pbs->roof)
+ return "ran out of message in middle of compressed domain name";
+
+ ix = ((b & ~0xC0u) << 8) | *ip++;
+ if (jump_count == 0)
+ pbs->cur = ip;
+
+ if (ix >= pbs_room(pbs))
+ return "impossible compressed domain name";
+
+ /* Avoid infinite loop.
+ * There can be no more jumps than there are bytes
+ * in the packet. Not a tight limit, but good enough.
+ */
+ jump_count++;
+ if (jump_count > pbs_room(pbs))
+ return "loop in compressed domain name";
+
+ ip = pbs->start + ix;
+ }
+ break;
+
+ default:
+ return "invalid code in label";
}
- break;
-
- default:
- return "invalid code in label";
}
- }
- name_buf[oi++] = '\0';
+ name_buf[oi++] = '\0';
- DBG(DBG_DNS, DBG_log("skipping name %s", name_buf));
+ DBG(DBG_DNS, DBG_log("skipping name %s", name_buf));
- return NULL;
+ return NULL;
}
static err_t
eat_name_helpfully(pb_stream *pbs, const char *context)
{
- err_t ugh = eat_name(pbs);
+ err_t ugh = eat_name(pbs);
- return ugh == NULL? ugh
- : builddiag("malformed name within DNS record of %s: %s", context, ugh);
+ return ugh == NULL? ugh
+ : builddiag("malformed name within DNS record of %s: %s", context, ugh);
}
/* non-variable part of 4.1.2 Question Section entry:
@@ -749,20 +789,20 @@ eat_name_helpfully(pb_stream *pbs, const char *context)
*/
struct qs_fixed {
- u_int16_t qtype;
- u_int16_t qclass;
+ u_int16_t qtype;
+ u_int16_t qclass;
};
static field_desc qs_fixed_fields[] = {
- { ft_loose_enum, 16/BITS_PER_BYTE, "QTYPE", &rr_qtype_names },
- { ft_loose_enum, 16/BITS_PER_BYTE, "QCLASS", &rr_class_names },
- { ft_end, 0, NULL, NULL }
+ { ft_loose_enum, 16/BITS_PER_BYTE, "QTYPE", &rr_qtype_names },
+ { ft_loose_enum, 16/BITS_PER_BYTE, "QCLASS", &rr_class_names },
+ { ft_end, 0, NULL, NULL }
};
static struct_desc qs_fixed_desc = {
- "Question Section entry fixed part",
- qs_fixed_fields,
- sizeof(struct qs_fixed)
+ "Question Section entry fixed part",
+ qs_fixed_fields,
+ sizeof(struct qs_fixed)
};
/* 4.1.3. Resource record format:
@@ -789,26 +829,26 @@ static struct_desc qs_fixed_desc = {
*/
struct rr_fixed {
- u_int16_t type;
- u_int16_t class;
- u_int32_t ttl; /* actually signed */
- u_int16_t rdlength;
+ u_int16_t type;
+ u_int16_t class;
+ u_int32_t ttl; /* actually signed */
+ u_int16_t rdlength;
};
static field_desc rr_fixed_fields[] = {
- { ft_loose_enum, 16/BITS_PER_BYTE, "type", &rr_type_names },
- { ft_loose_enum, 16/BITS_PER_BYTE, "class", &rr_class_names },
- { ft_nat, 32/BITS_PER_BYTE, "TTL", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "RD length", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_loose_enum, 16/BITS_PER_BYTE, "type", &rr_type_names },
+ { ft_loose_enum, 16/BITS_PER_BYTE, "class", &rr_class_names },
+ { ft_nat, 32/BITS_PER_BYTE, "TTL", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "RD length", NULL },
+ { ft_end, 0, NULL, NULL }
};
static struct_desc rr_fixed_desc = {
- "Resource Record fixed part",
- rr_fixed_fields,
- /* note: following is tricky: avoids padding problems */
- offsetof(struct rr_fixed, rdlength) + sizeof(u_int16_t)
+ "Resource Record fixed part",
+ rr_fixed_fields,
+ /* note: following is tricky: avoids padding problems */
+ offsetof(struct rr_fixed, rdlength) + sizeof(u_int16_t)
};
/* RFC 1035 3.3.14: TXT RRs have text in the RDATA field.
@@ -830,22 +870,22 @@ static struct_desc rr_fixed_desc = {
*/
struct key_rdata {
- u_int16_t flags;
- u_int8_t protocol;
- u_int8_t algorithm;
+ u_int16_t flags;
+ u_int8_t protocol;
+ u_int8_t algorithm;
};
static field_desc key_rdata_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "flags", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "protocol", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_nat, 16/BITS_PER_BYTE, "flags", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "protocol", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL },
+ { ft_end, 0, NULL, NULL }
};
static struct_desc key_rdata_desc = {
- "KEY RR RData fixed part",
- key_rdata_fields,
- sizeof(struct key_rdata)
+ "KEY RR RData fixed part",
+ key_rdata_fields,
+ sizeof(struct key_rdata)
};
/* RFC 2535 4.1 SIG RDATA format:
@@ -872,30 +912,30 @@ static struct_desc key_rdata_desc = {
*/
struct sig_rdata {
- u_int16_t type_covered;
- u_int8_t algorithm;
- u_int8_t labels;
- u_int32_t original_ttl;
- u_int32_t sig_expiration;
- u_int32_t sig_inception;
- u_int16_t key_tag;
+ u_int16_t type_covered;
+ u_int8_t algorithm;
+ u_int8_t labels;
+ u_int32_t original_ttl;
+ u_int32_t sig_expiration;
+ u_int32_t sig_inception;
+ u_int16_t key_tag;
};
static field_desc sig_rdata_fields[] = {
- { ft_nat, 16/BITS_PER_BYTE, "type_covered", NULL},
- { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL},
- { ft_nat, 8/BITS_PER_BYTE, "labels", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "original ttl", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "sig expiration", NULL},
- { ft_nat, 32/BITS_PER_BYTE, "sig inception", NULL},
- { ft_nat, 16/BITS_PER_BYTE, "key tag", NULL},
- { ft_end, 0, NULL, NULL }
+ { ft_nat, 16/BITS_PER_BYTE, "type_covered", NULL},
+ { ft_nat, 8/BITS_PER_BYTE, "algorithm", NULL},
+ { ft_nat, 8/BITS_PER_BYTE, "labels", NULL},
+ { ft_nat, 32/BITS_PER_BYTE, "original ttl", NULL},
+ { ft_nat, 32/BITS_PER_BYTE, "sig expiration", NULL},
+ { ft_nat, 32/BITS_PER_BYTE, "sig inception", NULL},
+ { ft_nat, 16/BITS_PER_BYTE, "key tag", NULL},
+ { ft_end, 0, NULL, NULL }
};
static struct_desc sig_rdata_desc = {
- "SIG RR RData fixed part",
- sig_rdata_fields,
- sizeof(struct sig_rdata)
+ "SIG RR RData fixed part",
+ sig_rdata_fields,
+ sizeof(struct sig_rdata)
};
/* handle a KEY Resource Record. */
@@ -903,38 +943,37 @@ static struct_desc sig_rdata_desc = {
#ifdef USE_KEYRR
static err_t
process_key_rr(u_char *ptr, size_t len
-, bool doit /* should we capture information? */
+, bool doit /* should we capture information? */
, enum dns_auth_level dns_auth_level
, struct adns_continuation *const cr)
{
- pb_stream pbs;
- struct key_rdata kr;
-
- if (len < sizeof(struct key_rdata))
- return "KEY Resource Record's RD Length is too small";
+ pb_stream pbs;
+ struct key_rdata kr;
- init_pbs(&pbs, ptr, len, "KEY RR");
+ if (len < sizeof(struct key_rdata))
+ return "KEY Resource Record's RD Length is too small";
- if (!in_struct(&kr, &key_rdata_desc, &pbs, NULL))
- return "failed to get fixed part of KEY Resource Record RDATA";
+ init_pbs(&pbs, ptr, len, "KEY RR");
- if (kr.protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
- && kr.algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
- && (kr.flags & 0x8000) == 0 /* use for authentication (3.1.2) */
- && (kr.flags & 0x2CF0) == 0) /* must be zero */
- {
- /* we have what seems to be a tasty key */
+ if (!in_struct(&kr, &key_rdata_desc, &pbs, NULL))
+ return "failed to get fixed part of KEY Resource Record RDATA";
- if (doit)
+ if (kr.protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
+ && kr.algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
+ && (kr.flags & 0x8000) == 0 /* use for authentication (3.1.2) */
+ && (kr.flags & 0x2CF0) == 0) /* must be zero */
{
- chunk_t k;
+ /* we have what seems to be a tasty key */
+
+ if (doit)
+ {
+ chunk_t k = { pbs.cur, pbs_left(&pbs) };
- setchunk(k, pbs.cur, pbs_left(&pbs));
- TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &k
- , &cr->keys_from_dns));
+ TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &k
+ , &cr->keys_from_dns));
+ }
}
- }
- return NULL;
+ return NULL;
}
#endif /* USE_KEYRR */
@@ -946,130 +985,130 @@ process_key_rr(u_char *ptr, size_t len
static err_t
unpack_txt_rdata(u_char *d, size_t dlen, const u_char *s, size_t slen)
{
- size_t i = 0
- , o = 0;
+ size_t i = 0
+ , o = 0;
- while (i < slen)
- {
- size_t cl = s[i++];
+ while (i < slen)
+ {
+ size_t cl = s[i++];
- if (i + cl > slen)
- return "TXT rr RDATA representation malformed";
+ if (i + cl > slen)
+ return "TXT rr RDATA representation malformed";
- if (o + cl >= dlen)
- return "TXT rr RDATA too large";
+ if (o + cl >= dlen)
+ return "TXT rr RDATA too large";
- memcpy(d + o, s + i, cl);
- i += cl;
- o += cl;
- }
- d[o] = '\0';
- if (strlen(d) != o)
- return "TXT rr RDATA contains a NUL";
+ memcpy(d + o, s + i, cl);
+ i += cl;
+ o += cl;
+ }
+ d[o] = '\0';
+ if (strlen(d) != o)
+ return "TXT rr RDATA contains a NUL";
- return NULL;
+ return NULL;
}
static err_t
process_txt_rr(u_char *rdata, size_t rdlen
-, bool doit /* should we capture information? */
+, bool doit /* should we capture information? */
, enum dns_auth_level dns_auth_level
, struct adns_continuation *const cr)
{
- u_char str[RSA_MAX_ENCODING_BYTES * 8 / 6 + 20]; /* space for unpacked RDATA */
+ u_char str[RSA_MAX_ENCODING_BYTES * 8 / 6 + 20]; /* space for unpacked RDATA */
- TRY(unpack_txt_rdata(str, sizeof(str), rdata, rdlen));
- return process_txt_rr_body(str, doit, dns_auth_level, cr);
+ TRY(unpack_txt_rdata(str, sizeof(str), rdata, rdlen));
+ return process_txt_rr_body(str, doit, dns_auth_level, cr);
}
static err_t
process_answer_section(pb_stream *pbs
-, bool doit /* should we capture information? */
+, bool doit /* should we capture information? */
, enum dns_auth_level *dns_auth_level
-, u_int16_t ancount /* number of RRs in the answer section */
+, u_int16_t ancount /* number of RRs in the answer section */
, struct adns_continuation *const cr)
{
- const int type = cr->query.type; /* type of RR of interest */
- unsigned c;
+ const int type = cr->query.type; /* type of RR of interest */
+ unsigned c;
- DBG(DBG_DNS, DBG_log("*Answer Section:"));
+ DBG(DBG_DNS, DBG_log("*Answer Section:"));
- for (c = 0; c != ancount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
+ for (c = 0; c != ancount; c++)
+ {
+ struct rr_fixed rrf;
+ size_t tail;
- /* ??? do we need to match the name? */
+ /* ??? do we need to match the name? */
- TRY(eat_name_helpfully(pbs, "Answer Section"));
+ TRY(eat_name_helpfully(pbs, "Answer Section"));
- if (!in_struct(&rrf, &rr_fixed_desc, pbs, NULL))
- return "failed to get fixed part of Answer Section Resource Record";
+ if (!in_struct(&rrf, &rr_fixed_desc, pbs, NULL))
+ return "failed to get fixed part of Answer Section Resource Record";
- if (rrf.rdlength > pbs_left(pbs))
- return "RD Length extends beyond end of message";
+ if (rrf.rdlength > pbs_left(pbs))
+ return "RD Length extends beyond end of message";
- /* ??? should we care about ttl? */
+ /* ??? should we care about ttl? */
- tail = rrf.rdlength;
+ tail = rrf.rdlength;
- if (rrf.type == type && rrf.class == C_IN)
- {
- err_t ugh = NULL;
+ if (rrf.type == type && rrf.class == C_IN)
+ {
+ err_t ugh = NULL;
- switch (type)
- {
+ switch (type)
+ {
#ifdef USE_KEYRR
- case T_KEY:
- ugh = process_key_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
- break;
+ case T_KEY:
+ ugh = process_key_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
+ break;
#endif /* USE_KEYRR */
- case T_TXT:
- ugh = process_txt_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
- break;
- case T_SIG:
- /* Check if SIG RR authenticates what we are learning.
- * The RRset covered by a SIG must have the same owner,
- * class, and type.
- * For us, the class is always C_IN, so that matches.
- * We decode the SIG RR's fixed part to check
- * that the type_covered field matches our query type
- * (this may be redundant).
- * We don't check the owner (apparently this is the
- * name on the record) -- we assume that it matches
- * or we would not have been given this SIG in the
- * Answer Section.
- *
- * We only look on first pass, and only if we've something
- * to learn. This cuts down on useless decoding.
- */
- if (!doit && *dns_auth_level == DAL_UNSIGNED)
- {
- struct sig_rdata sr;
-
- if (!in_struct(&sr, &sig_rdata_desc, pbs, NULL))
- ugh = "failed to get fixed part of SIG Resource Record RDATA";
- else if (sr.type_covered == type)
- *dns_auth_level = DAL_SIGNED;
+ case T_TXT:
+ ugh = process_txt_rr(pbs->cur, tail, doit, *dns_auth_level, cr);
+ break;
+ case T_SIG:
+ /* Check if SIG RR authenticates what we are learning.
+ * The RRset covered by a SIG must have the same owner,
+ * class, and type.
+ * For us, the class is always C_IN, so that matches.
+ * We decode the SIG RR's fixed part to check
+ * that the type_covered field matches our query type
+ * (this may be redundant).
+ * We don't check the owner (apparently this is the
+ * name on the record) -- we assume that it matches
+ * or we would not have been given this SIG in the
+ * Answer Section.
+ *
+ * We only look on first pass, and only if we've something
+ * to learn. This cuts down on useless decoding.
+ */
+ if (!doit && *dns_auth_level == DAL_UNSIGNED)
+ {
+ struct sig_rdata sr;
+
+ if (!in_struct(&sr, &sig_rdata_desc, pbs, NULL))
+ ugh = "failed to get fixed part of SIG Resource Record RDATA";
+ else if (sr.type_covered == type)
+ *dns_auth_level = DAL_SIGNED;
+ }
+ break;
+ default:
+ ugh = builddiag("unexpected RR type %d", type);
+ break;
+ }
+ if (ugh != NULL)
+ return ugh;
}
- break;
- default:
- ugh = builddiag("unexpected RR type %d", type);
- break;
- }
- if (ugh != NULL)
- return ugh;
+ in_raw(NULL, tail, pbs, "RR RDATA");
}
- in_raw(NULL, tail, pbs, "RR RDATA");
- }
- return doit
- && cr->gateways_from_dns == NULL
+ return doit
+ && cr->gateways_from_dns == NULL
#ifdef USE_KEYRR
- && cr->keys_from_dns == NULL
+ && cr->keys_from_dns == NULL
#endif /* USE_KEYRR */
- ? builddiag("no suitable %s record found in DNS", rr_typename(type))
- : NULL;
+ ? builddiag("no suitable %s record found in DNS", rr_typename(type))
+ : NULL;
}
/* process DNS answer -- TXT or KEY query */
@@ -1078,153 +1117,153 @@ static err_t
process_dns_answer(struct adns_continuation *const cr
, u_char ans[], int anslen)
{
- const int type = cr->query.type; /* type of record being sought */
- int r; /* all-purpose return value holder */
- u_int16_t c; /* number of current RR in current answer section */
- pb_stream pbs;
- u_int8_t *ans_start; /* saved position of answer section */
- struct qr_header qr_header;
- enum dns_auth_level dns_auth_level;
+ const int type = cr->query.type; /* type of record being sought */
+ int r; /* all-purpose return value holder */
+ u_int16_t c; /* number of current RR in current answer section */
+ pb_stream pbs;
+ u_int8_t *ans_start; /* saved position of answer section */
+ struct qr_header qr_header;
+ enum dns_auth_level dns_auth_level;
- init_pbs(&pbs, ans, anslen, "Query Response Message");
+ init_pbs(&pbs, ans, anslen, "Query Response Message");
- /* decode and check header */
+ /* decode and check header */
- if (!in_struct(&qr_header, &qr_header_desc, &pbs, NULL))
- return "malformed header";
+ if (!in_struct(&qr_header, &qr_header_desc, &pbs, NULL))
+ return "malformed header";
- /* ID: nothing to do with us */
+ /* ID: nothing to do with us */
- /* stuff -- lots of things */
- if ((qr_header.stuff & QRS_QR) == 0)
- return "not a response?!?";
+ /* stuff -- lots of things */
+ if ((qr_header.stuff & QRS_QR) == 0)
+ return "not a response?!?";
- if (((qr_header.stuff >> QRS_OPCODE_SHIFT) & QRS_OPCODE_MASK) != QRSO_QUERY)
- return "unexpected opcode";
+ if (((qr_header.stuff >> QRS_OPCODE_SHIFT) & QRS_OPCODE_MASK) != QRSO_QUERY)
+ return "unexpected opcode";
- /* I don't think we care about AA */
+ /* I don't think we care about AA */
- if (qr_header.stuff & QRS_TC)
- return "response truncated";
+ if (qr_header.stuff & QRS_TC)
+ return "response truncated";
- /* I don't think we care about RD, RA, or CD */
+ /* I don't think we care about RD, RA, or CD */
- /* AD means "authentic data" */
- dns_auth_level = qr_header.stuff & QRS_AD? DAL_UNSIGNED : DAL_NOTSEC;
+ /* AD means "authentic data" */
+ dns_auth_level = qr_header.stuff & QRS_AD? DAL_UNSIGNED : DAL_NOTSEC;
- if (qr_header.stuff & QRS_Z)
- return "Z bit is not zero";
+ if (qr_header.stuff & QRS_Z)
+ return "Z bit is not zero";
- r = (qr_header.stuff >> QRS_RCODE_SHIFT) & QRS_RCODE_MASK;
- if (r != 0)
- return r < (int)elemsof(rcode_text)? rcode_text[r] : "unknown rcode";
+ r = (qr_header.stuff >> QRS_RCODE_SHIFT) & QRS_RCODE_MASK;
+ if (r != 0)
+ return r < (int)countof(rcode_text)? rcode_text[r] : "unknown rcode";
- if (qr_header.ancount == 0)
- return builddiag("no %s RR found by DNS", rr_typename(type));
+ if (qr_header.ancount == 0)
+ return builddiag("no %s RR found by DNS", rr_typename(type));
- /* end of header checking */
+ /* end of header checking */
- /* Question Section processing */
+ /* Question Section processing */
- /* 4.1.2. Question section format:
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | |
- * / QNAME /
- * / /
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QTYPE |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- * | QCLASS |
- * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
+ /* 4.1.2. Question section format:
+ * 1 1 1 1 1 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | |
+ * / QNAME /
+ * / /
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | QTYPE |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | QCLASS |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ */
- DBG(DBG_DNS, DBG_log("*Question Section:"));
+ DBG(DBG_DNS, DBG_log("*Question Section:"));
- for (c = 0; c != qr_header.qdcount; c++)
- {
- struct qs_fixed qsf;
+ for (c = 0; c != qr_header.qdcount; c++)
+ {
+ struct qs_fixed qsf;
- TRY(eat_name_helpfully(&pbs, "Question Section"));
+ TRY(eat_name_helpfully(&pbs, "Question Section"));
- if (!in_struct(&qsf, &qs_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Question Section";
+ if (!in_struct(&qsf, &qs_fixed_desc, &pbs, NULL))
+ return "failed to get fixed part of Question Section";
- if (qsf.qtype != type)
- return "unexpected QTYPE in Question Section";
+ if (qsf.qtype != type)
+ return "unexpected QTYPE in Question Section";
- if (qsf.qclass != C_IN)
- return "unexpected QCLASS in Question Section";
- }
+ if (qsf.qclass != C_IN)
+ return "unexpected QCLASS in Question Section";
+ }
- /* rest of sections are made up of Resource Records */
+ /* rest of sections are made up of Resource Records */
- /* Answer Section processing -- error checking, noting T_SIG */
+ /* Answer Section processing -- error checking, noting T_SIG */
- ans_start = pbs.cur; /* remember start of answer section */
+ ans_start = pbs.cur; /* remember start of answer section */
- TRY(process_answer_section(&pbs, FALSE, &dns_auth_level
- , qr_header.ancount, cr));
+ TRY(process_answer_section(&pbs, FALSE, &dns_auth_level
+ , qr_header.ancount, cr));
- /* Authority Section processing (just sanity checking) */
+ /* Authority Section processing (just sanity checking) */
- DBG(DBG_DNS, DBG_log("*Authority Section:"));
+ DBG(DBG_DNS, DBG_log("*Authority Section:"));
- for (c = 0; c != qr_header.nscount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
+ for (c = 0; c != qr_header.nscount; c++)
+ {
+ struct rr_fixed rrf;
+ size_t tail;
- TRY(eat_name_helpfully(&pbs, "Authority Section"));
+ TRY(eat_name_helpfully(&pbs, "Authority Section"));
- if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Authority Section Resource Record";
+ if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
+ return "failed to get fixed part of Authority Section Resource Record";
- if (rrf.rdlength > pbs_left(&pbs))
- return "RD Length extends beyond end of message";
+ if (rrf.rdlength > pbs_left(&pbs))
+ return "RD Length extends beyond end of message";
- /* ??? should we care about ttl? */
+ /* ??? should we care about ttl? */
- tail = rrf.rdlength;
+ tail = rrf.rdlength;
- in_raw(NULL, tail, &pbs, "RR RDATA");
- }
+ in_raw(NULL, tail, &pbs, "RR RDATA");
+ }
- /* Additional Section processing (just sanity checking) */
+ /* Additional Section processing (just sanity checking) */
- DBG(DBG_DNS, DBG_log("*Additional Section:"));
+ DBG(DBG_DNS, DBG_log("*Additional Section:"));
- for (c = 0; c != qr_header.arcount; c++)
- {
- struct rr_fixed rrf;
- size_t tail;
+ for (c = 0; c != qr_header.arcount; c++)
+ {
+ struct rr_fixed rrf;
+ size_t tail;
- TRY(eat_name_helpfully(&pbs, "Additional Section"));
+ TRY(eat_name_helpfully(&pbs, "Additional Section"));
- if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
- return "failed to get fixed part of Additional Section Resource Record";
+ if (!in_struct(&rrf, &rr_fixed_desc, &pbs, NULL))
+ return "failed to get fixed part of Additional Section Resource Record";
- if (rrf.rdlength > pbs_left(&pbs))
- return "RD Length extends beyond end of message";
+ if (rrf.rdlength > pbs_left(&pbs))
+ return "RD Length extends beyond end of message";
- /* ??? should we care about ttl? */
+ /* ??? should we care about ttl? */
- tail = rrf.rdlength;
+ tail = rrf.rdlength;
- in_raw(NULL, tail, &pbs, "RR RDATA");
- }
+ in_raw(NULL, tail, &pbs, "RR RDATA");
+ }
- /* done all sections */
+ /* done all sections */
- /* ??? is padding legal, or can we complain if more left in record? */
+ /* ??? is padding legal, or can we complain if more left in record? */
- /* process Answer Section again -- accept contents */
+ /* process Answer Section again -- accept contents */
- pbs.cur = ans_start; /* go back to start of answer section */
+ pbs.cur = ans_start; /* go back to start of answer section */
- return process_answer_section(&pbs, TRUE, &dns_auth_level
- , qr_header.ancount, cr);
+ return process_answer_section(&pbs, TRUE, &dns_auth_level
+ , qr_header.ancount, cr);
}
#endif /* ! USE_LWRES */
@@ -1239,101 +1278,101 @@ build_dns_name(u_char name_buf[NS_MAXDNAME + 2]
, const char *typename USED_BY_DEBUG
, const char *gwname USED_BY_DEBUG)
{
- /* note: all end in "." to suppress relative searches */
- id = resolve_myid(id);
- switch (id->kind)
- {
- case ID_IPV4_ADDR:
- {
- /* XXX: this is really ugly and only temporary until addrtot can
- * generate the correct format
- */
- const unsigned char *b;
- size_t bl USED_BY_DEBUG = addrbytesptr(&id->ip_addr, &b);
-
- passert(bl == 4);
- snprintf(name_buf, NS_MAXDNAME + 2, "%d.%d.%d.%d.in-addr.arpa."
- , b[3], b[2], b[1], b[0]);
- break;
- }
-
- case ID_IPV6_ADDR:
- {
- /* ??? is this correct? */
- const unsigned char *b;
- size_t bl;
- u_char *op = name_buf;
- static const char suffix[] = "IP6.INT.";
-
- for (bl = addrbytesptr(&id->ip_addr, &b); bl-- != 0; )
+ /* note: all end in "." to suppress relative searches */
+ id = resolve_myid(id);
+ switch (id->kind)
+ {
+ case ID_IPV4_ADDR:
{
- if (op + 4 + sizeof(suffix) >= name_buf + NS_MAXDNAME + 1)
- return "IPv6 reverse name too long";
- op += sprintf(op, "%x.%x.", b[bl] & 0xF, b[bl] >> 4);
+ /* XXX: this is really ugly and only temporary until addrtot can
+ * generate the correct format
+ */
+ const unsigned char *b;
+ size_t bl USED_BY_DEBUG = addrbytesptr(&id->ip_addr, &b);
+
+ passert(bl == 4);
+ snprintf(name_buf, NS_MAXDNAME + 2, "%d.%d.%d.%d.in-addr.arpa."
+ , b[3], b[2], b[1], b[0]);
+ break;
}
- strcpy(op, suffix);
- break;
- }
- case ID_FQDN:
- /* strip trailing "." characters, then add one */
+ case ID_IPV6_ADDR:
{
- size_t il = id->name.len;
-
- while (il > 0 && id->name.ptr[il - 1] == '.')
- il--;
- if (il > NS_MAXDNAME)
- return "FQDN too long for domain name";
+ /* ??? is this correct? */
+ const unsigned char *b;
+ size_t bl;
+ u_char *op = name_buf;
+ static const char suffix[] = "IP6.INT.";
- memcpy(name_buf, id->name.ptr, il);
- strcpy(name_buf + il, ".");
+ for (bl = addrbytesptr(&id->ip_addr, &b); bl-- != 0; )
+ {
+ if (op + 4 + sizeof(suffix) >= name_buf + NS_MAXDNAME + 1)
+ return "IPv6 reverse name too long";
+ op += sprintf(op, "%x.%x.", b[bl] & 0xF, b[bl] >> 4);
+ }
+ strcpy(op, suffix);
+ break;
}
- break;
- default:
- return "can only query DNS for key for ID that is a FQDN, IPV4_ADDR, or IPV6_ADDR";
- }
+ case ID_FQDN:
+ /* strip trailing "." characters, then add one */
+ {
+ size_t il = id->name.len;
+
+ while (il > 0 && id->name.ptr[il - 1] == '.')
+ il--;
+ if (il > NS_MAXDNAME)
+ return "FQDN too long for domain name";
- DBG(DBG_CONTROL | DBG_DNS, DBG_log("DNS query %lu for %s for %s (gw: %s)"
- , serial, typename, name_buf, gwname));
- return NULL;
+ memcpy(name_buf, id->name.ptr, il);
+ strcpy(name_buf + il, ".");
+ }
+ break;
+
+ default:
+ return "can only query DNS for key for ID that is a FQDN, IPV4_ADDR, or IPV6_ADDR";
+ }
+
+ DBG(DBG_CONTROL | DBG_DNS, DBG_log("DNS query %lu for %s for %s (gw: %s)"
+ , serial, typename, name_buf, gwname));
+ return NULL;
}
void
gw_addref(struct gw_info *gw)
{
- if (gw != NULL)
- {
- DBG(DBG_DNS, DBG_log("gw_addref: %p refcnt: %d++", gw, gw->refcnt))
- gw->refcnt++;
- }
+ if (gw != NULL)
+ {
+ DBG(DBG_DNS, DBG_log("gw_addref: %p refcnt: %d++", gw, gw->refcnt))
+ gw->refcnt++;
+ }
}
void
gw_delref(struct gw_info **gwp)
{
- struct gw_info *gw = *gwp;
-
- if (gw != NULL)
- {
- DBG(DBG_DNS, DBG_log("gw_delref: %p refcnt: %d--", gw, gw->refcnt));
+ struct gw_info *gw = *gwp;
- passert(gw->refcnt != 0);
- gw->refcnt--;
- if (gw->refcnt == 0)
+ if (gw != NULL)
{
- free_id_content(&gw->client_id);
- free_id_content(&gw->gw_id);
- if (gw->gw_key_present)
- unreference_key(&gw->key);
- gw_delref(&gw->next);
- pfree(gw); /* trickery could make this a tail-call */
+ DBG(DBG_DNS, DBG_log("gw_delref: %p refcnt: %d--", gw, gw->refcnt));
+
+ passert(gw->refcnt != 0);
+ gw->refcnt--;
+ if (gw->refcnt == 0)
+ {
+ free_id_content(&gw->client_id);
+ free_id_content(&gw->gw_id);
+ if (gw->gw_key_present)
+ unreference_key(&gw->key);
+ gw_delref(&gw->next);
+ free(gw); /* trickery could make this a tail-call */
+ }
+ *gwp = NULL;
}
- *gwp = NULL;
- }
}
-static int adns_in_flight = 0; /* queries outstanding */
+static int adns_in_flight = 0; /* queries outstanding */
/* Start an asynchronous DNS query.
*
@@ -1372,123 +1411,123 @@ static int adns_in_flight = 0; /* queries outstanding */
* disestablishing any logging context (whack_log_fd, cur_*).
*/
-static struct adns_continuation *continuations = NULL; /* newest of queue */
-static struct adns_continuation *next_query = NULL; /* oldest not sent */
+static struct adns_continuation *continuations = NULL; /* newest of queue */
+static struct adns_continuation *next_query = NULL; /* oldest not sent */
static struct adns_continuation *
continuation_for_qtid(unsigned long qtid)
{
- struct adns_continuation *cr = NULL;
+ struct adns_continuation *cr = NULL;
- if (qtid != 0)
- for (cr = continuations; cr != NULL && cr->qtid != qtid; cr = cr->previous)
- ;
- return cr;
+ if (qtid != 0)
+ for (cr = continuations; cr != NULL && cr->qtid != qtid; cr = cr->previous)
+ ;
+ return cr;
}
static void
release_adns_continuation(struct adns_continuation *cr)
{
- passert(cr != next_query);
- gw_delref(&cr->gateways_from_dns);
+ passert(cr != next_query);
+ gw_delref(&cr->gateways_from_dns);
#ifdef USE_KEYRR
- free_public_keys(&cr->keys_from_dns);
+ free_public_keys(&cr->keys_from_dns);
#endif /* USE_KEYRR */
- unshare_id_content(&cr->id);
- unshare_id_content(&cr->sgw_id);
-
- /* unlink from doubly-linked list */
- if (cr->next == NULL)
- {
- passert(continuations == cr);
- continuations = cr->previous;
- }
- else
- {
- passert(cr->next->previous == cr);
- cr->next->previous = cr->previous;
- }
-
- if (cr->previous != NULL)
- {
- passert(cr->previous->next == cr);
- cr->previous->next = cr->next;
- }
-
- pfree(cr);
+ unshare_id_content(&cr->id);
+ unshare_id_content(&cr->sgw_id);
+
+ /* unlink from doubly-linked list */
+ if (cr->next == NULL)
+ {
+ passert(continuations == cr);
+ continuations = cr->previous;
+ }
+ else
+ {
+ passert(cr->next->previous == cr);
+ cr->next->previous = cr->previous;
+ }
+
+ if (cr->previous != NULL)
+ {
+ passert(cr->previous->next == cr);
+ cr->previous->next = cr->next;
+ }
+
+ free(cr);
}
err_t
-start_adns_query(const struct id *id /* domain to query */
-, const struct id *sgw_id /* if non-null, any accepted gw_info must match */
-, int type /* T_TXT or T_KEY, selecting rr type of interest */
+start_adns_query(const struct id *id /* domain to query */
+, const struct id *sgw_id /* if non-null, any accepted gw_info must match */
+, int type /* T_TXT or T_KEY, selecting rr type of interest */
, cont_fn_t cont_fn
, struct adns_continuation *cr)
{
- static unsigned long qtid = 1; /* query transaction id; NOTE: static */
- const char *typename = rr_typename(type);
- char gwidb[BUF_LEN];
-
- if(adns_pid == 0
- && adns_restart_count < ADNS_RESTART_MAX)
- {
- plog("ADNS helper was not running. Restarting attempt %d",adns_restart_count);
- init_adns();
- }
-
-
- /* Splice this in at head of doubly-linked list of continuations.
- * Note: this must be done before any release_adns_continuation().
- */
- cr->next = NULL;
- cr->previous = continuations;
- if (continuations != NULL)
- {
- passert(continuations->next == NULL);
- continuations->next = cr;
- }
- continuations = cr;
-
- cr->qtid = qtid++;
- cr->type = type;
- cr->cont_fn = cont_fn;
- cr->id = *id;
- unshare_id_content(&cr->id);
- cr->sgw_specified = sgw_id != NULL;
- cr->sgw_id = cr->sgw_specified? *sgw_id : empty_id;
- unshare_id_content(&cr->sgw_id);
- cr->gateways_from_dns = NULL;
+ static unsigned long qtid = 1; /* query transaction id; NOTE: static */
+ const char *typename = rr_typename(type);
+ char gwidb[BUF_LEN];
+
+ if(adns_pid == 0
+ && adns_restart_count < ADNS_RESTART_MAX)
+ {
+ plog("ADNS helper was not running. Restarting attempt %d",adns_restart_count);
+ init_adns();
+ }
+
+
+ /* Splice this in at head of doubly-linked list of continuations.
+ * Note: this must be done before any release_adns_continuation().
+ */
+ cr->next = NULL;
+ cr->previous = continuations;
+ if (continuations != NULL)
+ {
+ passert(continuations->next == NULL);
+ continuations->next = cr;
+ }
+ continuations = cr;
+
+ cr->qtid = qtid++;
+ cr->type = type;
+ cr->cont_fn = cont_fn;
+ cr->id = *id;
+ unshare_id_content(&cr->id);
+ cr->sgw_specified = sgw_id != NULL;
+ cr->sgw_id = cr->sgw_specified? *sgw_id : empty_id;
+ unshare_id_content(&cr->sgw_id);
+ cr->gateways_from_dns = NULL;
#ifdef USE_KEYRR
- cr->keys_from_dns = NULL;
+ cr->keys_from_dns = NULL;
#endif /* USE_KEYRR */
#ifdef DEBUG
- cr->debugging = cur_debugging;
+ cr->debugging = cur_debugging;
#else
- cr->debugging = LEMPTY;
+ cr->debugging = LEMPTY;
#endif
- idtoa(&cr->sgw_id, gwidb, sizeof(gwidb));
+ idtoa(&cr->sgw_id, gwidb, sizeof(gwidb));
- zero(&cr->query);
+ zero(&cr->query);
- {
- err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid
- , id, typename, gwidb);
-
- if (ugh != NULL)
{
- release_adns_continuation(cr);
- return ugh;
+ err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid
+ , id, typename, gwidb);
+
+ if (ugh != NULL)
+ {
+ release_adns_continuation(cr);
+ return ugh;
+ }
}
- }
- if (next_query == NULL)
- next_query = cr;
+ if (next_query == NULL)
+ next_query = cr;
- unsent_ADNS_queries = TRUE;
+ unsent_ADNS_queries = TRUE;
- return NULL;
+ return NULL;
}
/* send remaining ADNS queries (until pipe full or none left)
@@ -1501,79 +1540,79 @@ bool unsent_ADNS_queries = FALSE;
void
send_unsent_ADNS_queries(void)
{
- static const unsigned char *buf_end = NULL; /* NOTE STATIC */
- static const unsigned char *buf_cur = NULL; /* NOTE STATIC */
+ static const unsigned char *buf_end = NULL; /* NOTE STATIC */
+ static const unsigned char *buf_cur = NULL; /* NOTE STATIC */
- if (adns_qfd == NULL_FD)
- return; /* nothing useful to do */
+ if (adns_qfd == NULL_FD)
+ return; /* nothing useful to do */
- for (;;)
- {
- if (buf_cur != buf_end)
+ for (;;)
{
- static int try = 0; /* NOTE STATIC */
- size_t n = buf_end - buf_cur;
- ssize_t r = write(adns_qfd, buf_cur, n);
-
- if (r == -1)
- {
- switch (errno)
+ if (buf_cur != buf_end)
{
- case EINTR:
- continue; /* try again now */
- case EAGAIN:
- DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));
- break; /* try again later */
- default:
- try++;
- log_errno((e, "error %d writing DNS query", try));
- break; /* try again later */
+ static int try = 0; /* NOTE STATIC */
+ size_t n = buf_end - buf_cur;
+ ssize_t r = write(adns_qfd, buf_cur, n);
+
+ if (r == -1)
+ {
+ switch (errno)
+ {
+ case EINTR:
+ continue; /* try again now */
+ case EAGAIN:
+ DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));
+ break; /* try again later */
+ default:
+ try++;
+ log_errno((e, "error %d writing DNS query", try));
+ break; /* try again later */
+ }
+ unsent_ADNS_queries = TRUE;
+ break; /* done! */
+ }
+ else
+ {
+ passert(r >= 0);
+ try = 0;
+ buf_cur += r;
+ }
}
- unsent_ADNS_queries = TRUE;
- break; /* done! */
- }
- else
- {
- passert(r >= 0);
- try = 0;
- buf_cur += r;
- }
- }
- else
- {
- if (next_query == NULL)
- {
- unsent_ADNS_queries = FALSE;
- break; /* done! */
- }
+ else
+ {
+ if (next_query == NULL)
+ {
+ unsent_ADNS_queries = FALSE;
+ break; /* done! */
+ }
#ifdef USE_LWRES
- next_query->used = FALSE;
- {
- /* NOTE STATIC: */
- static unsigned char qbuf[LWDNSQ_CMDBUF_LEN + 1]; /* room for NUL */
-
- snprintf(qbuf, sizeof(qbuf), "%s %lu %s\n"
- , rr_typename(next_query->type)
- , next_query->qtid
- , next_query->query.name_buf);
- DBG(DBG_DNS, DBG_log("lwdnsq query: %.*s", (int)(strlen(qbuf) - 1), qbuf));
- buf_cur = qbuf;
- buf_end = qbuf + strlen(qbuf);
- }
+ next_query->used = FALSE;
+ {
+ /* NOTE STATIC: */
+ static unsigned char qbuf[LWDNSQ_CMDBUF_LEN + 1]; /* room for NUL */
+
+ snprintf(qbuf, sizeof(qbuf), "%s %lu %s\n"
+ , rr_typename(next_query->type)
+ , next_query->qtid
+ , next_query->query.name_buf);
+ DBG(DBG_DNS, DBG_log("lwdnsq query: %.*s", (int)(strlen(qbuf) - 1), qbuf));
+ buf_cur = qbuf;
+ buf_end = qbuf + strlen(qbuf);
+ }
#else /* !USE_LWRES */
- next_query->query.debugging = next_query->debugging;
- next_query->query.serial = next_query->qtid;
- next_query->query.len = sizeof(next_query->query);
- next_query->query.qmagic = ADNS_Q_MAGIC;
- next_query->query.type = next_query->type;
- buf_cur = (const void *)&next_query->query;
- buf_end = buf_cur + sizeof(next_query->query);
+ next_query->query.debugging = next_query->debugging;
+ next_query->query.serial = next_query->qtid;
+ next_query->query.len = sizeof(next_query->query);
+ next_query->query.qmagic = ADNS_Q_MAGIC;
+ next_query->query.type = next_query->type;
+ buf_cur = (const void *)&next_query->query;
+ buf_end = buf_cur + sizeof(next_query->query);
#endif /* !USE_LWRES */
- next_query = next_query->next;
- adns_in_flight++;
+ next_query = next_query->next;
+ adns_in_flight++;
+ }
}
- }
}
#ifdef USE_LWRES
@@ -1584,379 +1623,379 @@ send_unsent_ADNS_queries(void)
static err_t
process_lwdnsq_answer(char *ts)
{
- err_t ugh = NULL;
- char *rest;
- char *p;
- char *endofnumber;
- struct adns_continuation *cr = NULL;
- unsigned long qtid;
- time_t anstime; /* time of answer */
- char *atype; /* type of answer */
- long ttl; /* ttl of answer; int, but long for conversion */
- bool AuthenticatedData = FALSE;
- static char scratch_null_str[] = ""; /* cannot be const, but isn't written */
-
- /* query transaction id */
- rest = ts;
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: answer missing query transaction ID";
-
- qtid = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed query transaction ID";
-
- cr = continuation_for_qtid(qtid);
- if (qtid != 0 && cr == NULL)
- return "lwdnsq: unrecognized qtid"; /* can't happen! */
-
- /* time */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing time";
-
- anstime = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed time";
-
- /* TTL */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing TTL";
-
- ttl = strtol(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed TTL";
-
- /* type */
- atype = strsep(&rest, " \t");
- if (atype == NULL)
- return "lwdnsq: missing type";
-
- /* if rest is NULL, make it "", otherwise eat whitespace after type */
- rest = rest == NULL? scratch_null_str : rest + strspn(rest, " \t");
-
- if (strncasecmp(atype, "AD-", 3) == 0)
- {
- AuthenticatedData = TRUE;
- atype += 3;
- }
-
- /* deal with each type */
-
- if (cr == NULL)
- {
- /* we don't actually know which this applies to */
- return builddiag("lwdnsq: 0 qtid invalid with %s", atype);
- }
- else if (strcaseeq(atype, "START"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "DONE"))
- {
- if (!cr->used)
+ err_t ugh = NULL;
+ char *rest;
+ char *p;
+ char *endofnumber;
+ struct adns_continuation *cr = NULL;
+ unsigned long qtid;
+ time_t anstime; /* time of answer */
+ char *atype; /* type of answer */
+ long ttl; /* ttl of answer; int, but long for conversion */
+ bool AuthenticatedData = FALSE;
+ static char scratch_null_str[] = ""; /* cannot be const, but isn't written */
+
+ /* query transaction id */
+ rest = ts;
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq: answer missing query transaction ID";
+
+ qtid = strtoul(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq: malformed query transaction ID";
+
+ cr = continuation_for_qtid(qtid);
+ if (qtid != 0 && cr == NULL)
+ return "lwdnsq: unrecognized qtid"; /* can't happen! */
+
+ /* time */
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq: missing time";
+
+ anstime = strtoul(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq: malformed time";
+
+ /* TTL */
+ p = strsep(&rest, " \t");
+ if (p == NULL)
+ return "lwdnsq: missing TTL";
+
+ ttl = strtol(p, &endofnumber, 10);
+ if (*endofnumber != '\0')
+ return "lwdnsq: malformed TTL";
+
+ /* type */
+ atype = strsep(&rest, " \t");
+ if (atype == NULL)
+ return "lwdnsq: missing type";
+
+ /* if rest is NULL, make it "", otherwise eat whitespace after type */
+ rest = rest == NULL? scratch_null_str : rest + strspn(rest, " \t");
+
+ if (strncasecmp(atype, "AD-", 3) == 0)
{
- /* "no results returned by lwdnsq" should not happen */
- cr->cont_fn(cr
- , cr->gateways_from_dns == NULL
+ AuthenticatedData = TRUE;
+ atype += 3;
+ }
+
+ /* deal with each type */
+
+ if (cr == NULL)
+ {
+ /* we don't actually know which this applies to */
+ return builddiag("lwdnsq: 0 qtid invalid with %s", atype);
+ }
+ else if (strcaseeq(atype, "START"))
+ {
+ /* ignore */
+ }
+ else if (strcaseeq(atype, "DONE"))
+ {
+ if (!cr->used)
+ {
+ /* "no results returned by lwdnsq" should not happen */
+ cr->cont_fn(cr
+ , cr->gateways_from_dns == NULL
#ifdef USE_KEYRR
- && cr->keys_from_dns == NULL
+ && cr->keys_from_dns == NULL
#endif /* USE_KEYRR */
- ? "no results returned by lwdnsq" : NULL);
- cr->used = TRUE;
+ ? "no results returned by lwdnsq" : NULL);
+ cr->used = TRUE;
+ }
+ reset_globals();
+ release_adns_continuation(cr);
+ adns_in_flight--;
+ }
+ else if (strcaseeq(atype, "RETRY"))
+ {
+ if (!cr->used)
+ {
+ cr->cont_fn(cr, rest);
+ cr->used = TRUE;
+ }
}
- reset_globals();
- release_adns_continuation(cr);
- adns_in_flight--;
- }
- else if (strcaseeq(atype, "RETRY"))
- {
- if (!cr->used)
+ else if (strcaseeq(atype, "FATAL"))
{
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
+ if (!cr->used)
+ {
+ cr->cont_fn(cr, rest);
+ cr->used = TRUE;
+ }
}
- }
- else if (strcaseeq(atype, "FATAL"))
- {
- if (!cr->used)
+ else if (strcaseeq(atype, "DNSSEC"))
{
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
+ /* ignore */
}
- }
- else if (strcaseeq(atype, "DNSSEC"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "NAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "TXT"))
- {
- char *end = rest + strlen(rest);
- err_t txt_ugh;
-
- if (*rest == '"' && end[-1] == '"')
+ else if (strcaseeq(atype, "NAME"))
{
- /* strip those pesky quotes */
- rest++;
- *--end = '\0';
+ /* ignore */
}
+ else if (strcaseeq(atype, "TXT"))
+ {
+ char *end = rest + strlen(rest);
+ err_t txt_ugh;
+
+ if (*rest == '"' && end[-1] == '"')
+ {
+ /* strip those pesky quotes */
+ rest++;
+ *--end = '\0';
+ }
- txt_ugh = process_txt_rr_body(rest
- , TRUE
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
+ txt_ugh = process_txt_rr_body(rest
+ , TRUE
+ , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
+ , cr);
- if (txt_ugh != NULL)
+ if (txt_ugh != NULL)
+ {
+ DBG(DBG_DNS,
+ DBG_log("error processing TXT resource record (%s) while processing: %s"
+ , txt_ugh, rest));
+ cr->cont_fn(cr, txt_ugh);
+ cr->used = TRUE;
+ }
+ }
+ else if (strcaseeq(atype, "SIG"))
+ {
+ /* record the SIG records for posterity */
+ if (cr->last_info != NULL)
+ {
+ free(cr->last_info->dns_sig);
+ cr->last_info->dns_sig = clone_str(rest);
+ }
+ }
+ else if (strcaseeq(atype, "A"))
+ {
+ /* ignore */
+ }
+ else if (strcaseeq(atype, "AAAA"))
{
- DBG(DBG_DNS,
- DBG_log("error processing TXT resource record (%s) while processing: %s"
- , txt_ugh, rest));
- cr->cont_fn(cr, txt_ugh);
- cr->used = TRUE;
+ /* ignore */
}
- }
- else if (strcaseeq(atype, "SIG"))
- {
- /* record the SIG records for posterity */
- if (cr->last_info != NULL)
+ else if (strcaseeq(atype, "CNAME"))
{
- pfreeany(cr->last_info->dns_sig);
- cr->last_info->dns_sig = clone_str(rest, "sigrecord");
+ /* ignore */
+ }
+ else if (strcaseeq(atype, "CNAMEFROM"))
+ {
+ /* ignore */
+ }
+ else if (strcaseeq(atype, "PTR"))
+ {
+ /* ignore */
}
- }
- else if (strcaseeq(atype, "A"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "AAAA"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAMEFROM"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "PTR"))
- {
- /* ignore */
- }
#ifdef USE_KEYRR
- else if (strcaseeq(atype, "KEY"))
- {
- err_t key_ugh = process_lwdnsq_key(rest
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
-
- if (key_ugh != NULL)
+ else if (strcaseeq(atype, "KEY"))
{
- DBG(DBG_DNS,
- DBG_log("error processing KEY resource record (%s) while processing: %s"
- , key_ugh, rest));
- cr->cont_fn(cr, key_ugh);
- cr->used = TRUE;
+ err_t key_ugh = process_lwdnsq_key(rest
+ , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
+ , cr);
+
+ if (key_ugh != NULL)
+ {
+ DBG(DBG_DNS,
+ DBG_log("error processing KEY resource record (%s) while processing: %s"
+ , key_ugh, rest));
+ cr->cont_fn(cr, key_ugh);
+ cr->used = TRUE;
+ }
}
- }
#endif /* USE_KEYRR */
- else
- {
- ugh = "lwdnsq: unrecognized type";
- }
- return ugh;
+ else
+ {
+ ugh = "lwdnsq: unrecognized type";
+ }
+ return ugh;
}
#endif /* USE_LWRES */
static void
recover_adns_die(void)
{
- struct adns_continuation *cr = NULL;
-
- adns_pid = 0;
- if(adns_restart_count < ADNS_RESTART_MAX) {
- adns_restart_count++;
+ struct adns_continuation *cr = NULL;
+
+ adns_pid = 0;
+ if(adns_restart_count < ADNS_RESTART_MAX) {
+ adns_restart_count++;
- /* next DNS query will restart it */
+ /* next DNS query will restart it */
- /* we have to walk the list of the outstanding requests,
- * and redo them!
- */
+ /* we have to walk the list of the outstanding requests,
+ * and redo them!
+ */
- cr = continuations;
+ cr = continuations;
- /* find the head of the list */
- if(continuations != NULL) {
- for (; cr->previous != NULL; cr = cr->previous);
- }
-
- next_query = cr;
+ /* find the head of the list */
+ if(continuations != NULL) {
+ for (; cr->previous != NULL; cr = cr->previous);
+ }
+
+ next_query = cr;
- if(next_query != NULL) {
- unsent_ADNS_queries = TRUE;
+ if(next_query != NULL) {
+ unsent_ADNS_queries = TRUE;
+ }
}
- }
}
void reset_adns_restart_count(void)
{
- adns_restart_count=0;
+ adns_restart_count=0;
}
void
handle_adns_answer(void)
{
/* These are retained across calls to handle_adns_answer. */
- static size_t buflen = 0; /* bytes in answer buffer */
+ static size_t buflen = 0; /* bytes in answer buffer */
#ifndef USE_LWRES
- static struct adns_answer buf;
+ static struct adns_answer buf;
#else /* USE_LWRES */
- static char buf[LWDNSQ_RESULT_LEN_MAX];
- static char buf_copy[LWDNSQ_RESULT_LEN_MAX];
+ static char buf[LWDNSQ_RESULT_LEN_MAX];
+ static char buf_copy[LWDNSQ_RESULT_LEN_MAX];
#endif /* USE_LWRES */
- ssize_t n;
+ ssize_t n;
- passert(buflen < sizeof(buf));
- n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);
+ passert(buflen < sizeof(buf));
+ n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);
- if (n < 0)
- {
- if (errno != EINTR)
+ if (n < 0)
{
- log_errno((e, "error reading answer from adns"));
- /* ??? how can we recover? */
+ if (errno != EINTR)
+ {
+ log_errno((e, "error reading answer from adns"));
+ /* ??? how can we recover? */
+ }
+ n = 0; /* now n reflects amount read */
}
- n = 0; /* now n reflects amount read */
- }
- else if (n == 0)
- {
- /* EOF */
- if (adns_in_flight != 0)
+ else if (n == 0)
{
- plog("EOF from ADNS with %d queries outstanding (restarts %d)"
- , adns_in_flight, adns_restart_count);
- recover_adns_die();
+ /* EOF */
+ if (adns_in_flight != 0)
+ {
+ plog("EOF from ADNS with %d queries outstanding (restarts %d)"
+ , adns_in_flight, adns_restart_count);
+ recover_adns_die();
+ }
+ if (buflen != 0)
+ {
+ plog("EOF from ADNS with %lu bytes of a partial answer outstanding"
+ "(restarts %d)"
+ , (unsigned long)buflen
+ , adns_restart_count);
+ recover_adns_die();
+ }
+ stop_adns();
+ return;
}
- if (buflen != 0)
+ else
{
- plog("EOF from ADNS with %lu bytes of a partial answer outstanding"
- "(restarts %d)"
- , (unsigned long)buflen
- , adns_restart_count);
- recover_adns_die();
+ passert(adns_in_flight > 0);
}
- stop_adns();
- return;
- }
- else
- {
- passert(adns_in_flight > 0);
- }
-
- buflen += n;
+
+ buflen += n;
#ifndef USE_LWRES
- while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
- {
- /* we've got a tasty answer -- process it */
- err_t ugh;
- struct adns_continuation *cr = continuation_for_qtid(buf.serial); /* assume it works */
- const char *typename = rr_typename(cr->query.type);
- const char *name_buf = cr->query.name_buf;
+ while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
+ {
+ /* we've got a tasty answer -- process it */
+ err_t ugh;
+ struct adns_continuation *cr = continuation_for_qtid(buf.serial); /* assume it works */
+ const char *typename = rr_typename(cr->query.type);
+ const char *name_buf = cr->query.name_buf;
#ifdef USE_KEYRR
- passert(cr->keys_from_dns == NULL);
+ passert(cr->keys_from_dns == NULL);
#endif /* USE_KEYRR */
- passert(cr->gateways_from_dns == NULL);
- adns_in_flight--;
- if (buf.result == -1)
- {
- /* newer resolvers support statp->res_h_errno as well as h_errno.
- * That might be better, but older resolvers don't.
- * See resolver(3), if you have it.
- * The undocumented(!) h_errno values are defined in
- * /usr/include/netdb.h.
- */
- switch (buf.h_errno_val)
- {
- case NO_DATA:
- ugh = builddiag("no %s record for %s", typename, name_buf);
- break;
- case HOST_NOT_FOUND:
- ugh = builddiag("no host %s for %s record", name_buf, typename);
- break;
- default:
- ugh = builddiag("failure querying DNS for %s of %s: %s"
- , typename, name_buf, hstrerror(buf.h_errno_val));
- break;
- }
- }
- else if (buf.result > (int) sizeof(buf.ans))
- {
- ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"
- , (long)buf.result);
- }
- else
- {
- ugh = process_dns_answer(cr, buf.ans, buf.result);
- if (ugh != NULL)
- ugh = builddiag("failure processing %s record of DNS answer for %s: %s"
- , typename, name_buf, ugh);
+ passert(cr->gateways_from_dns == NULL);
+ adns_in_flight--;
+ if (buf.result == -1)
+ {
+ /* newer resolvers support statp->res_h_errno as well as h_errno.
+ * That might be better, but older resolvers don't.
+ * See resolver(3), if you have it.
+ * The undocumented(!) h_errno values are defined in
+ * /usr/include/netdb.h.
+ */
+ switch (buf.h_errno_val)
+ {
+ case NO_DATA:
+ ugh = builddiag("no %s record for %s", typename, name_buf);
+ break;
+ case HOST_NOT_FOUND:
+ ugh = builddiag("no host %s for %s record", name_buf, typename);
+ break;
+ default:
+ ugh = builddiag("failure querying DNS for %s of %s: %s"
+ , typename, name_buf, hstrerror(buf.h_errno_val));
+ break;
+ }
+ }
+ else if (buf.result > (int) sizeof(buf.ans))
+ {
+ ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"
+ , (long)buf.result);
+ }
+ else
+ {
+ ugh = process_dns_answer(cr, buf.ans, buf.result);
+ if (ugh != NULL)
+ ugh = builddiag("failure processing %s record of DNS answer for %s: %s"
+ , typename, name_buf, ugh);
+ }
+ DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,
+ DBG_log(BLANK_FORMAT);
+ if (ugh == NULL)
+ DBG_log("asynch DNS answer %lu for %s of %s"
+ , cr->query.serial, typename, name_buf);
+ else
+ DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);
+ );
+
+ passert(GLOBALS_ARE_RESET());
+ cr->cont_fn(cr, ugh);
+ reset_globals();
+ release_adns_continuation(cr);
+
+ /* shift out answer that we've consumed */
+ buflen -= buf.len;
+ memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
}
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,
- DBG_log(BLANK_FORMAT);
- if (ugh == NULL)
- DBG_log("asynch DNS answer %lu for %s of %s"
- , cr->query.serial, typename, name_buf);
- else
- DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);
- );
-
- passert(GLOBALS_ARE_RESET());
- cr->cont_fn(cr, ugh);
- reset_globals();
- release_adns_continuation(cr);
-
- /* shift out answer that we've consumed */
- buflen -= buf.len;
- memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
- }
#else /* USE_LWRES */
- for (;;)
- {
- err_t ugh;
- char *nlp = memchr(buf, '\n', buflen);
+ for (;;)
+ {
+ err_t ugh;
+ char *nlp = memchr(buf, '\n', buflen);
- if (nlp == NULL)
- break;
+ if (nlp == NULL)
+ break;
- /* we've got a line */
- *nlp++ = '\0';
+ /* we've got a line */
+ *nlp++ = '\0';
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS
- , DBG_log("lwdns: %s", buf));
+ DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS
+ , DBG_log("lwdns: %s", buf));
- /* process lwdnsq_answer may modify buf, so make a copy. */
- buf_copy[0]='\0';
- strncat(buf_copy, buf, sizeof(buf_copy));
+ /* process lwdnsq_answer may modify buf, so make a copy. */
+ buf_copy[0]='\0';
+ strncat(buf_copy, buf, sizeof(buf_copy));
- ugh = process_lwdnsq_answer(buf_copy);
- if (ugh != NULL)
- plog("failure processing lwdnsq output: %s; record: %s"
- , ugh, buf);
+ ugh = process_lwdnsq_answer(buf_copy);
+ if (ugh != NULL)
+ plog("failure processing lwdnsq output: %s; record: %s"
+ , ugh, buf);
- passert(GLOBALS_ARE_RESET());
- reset_globals();
+ passert(GLOBALS_ARE_RESET());
+ reset_globals();
- /* shift out answer that we've consumed */
- buflen -= nlp - buf;
- memmove(buf, nlp, buflen);
- }
+ /* shift out answer that we've consumed */
+ buflen -= nlp - buf;
+ memmove(buf, nlp, buflen);
+ }
#endif /* USE_LWRES */
}
diff --git a/src/pluto/dnskey.h b/src/pluto/dnskey.h
index f69c226c8..976c715bf 100644
--- a/src/pluto/dnskey.h
+++ b/src/pluto/dnskey.h
@@ -10,14 +10,12 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: dnskey.h 3252 2007-10-06 21:24:50Z andreas $
*/
extern int
- adns_qfd, /* file descriptor for sending queries to adns */
- adns_afd; /* file descriptor for receiving answers from adns */
-extern const char *pluto_adns_option; /* path from --pluto_adns */
+ adns_qfd, /* file descriptor for sending queries to adns */
+ adns_afd; /* file descriptor for receiving answers from adns */
+extern const char *pluto_adns_option; /* path from --pluto_adns */
extern void init_adns(void);
extern void stop_adns(void);
extern void handle_adns_answer(void);
@@ -30,55 +28,55 @@ extern void send_unsent_ADNS_queries(void);
* Freed by call to release_adns_continuation.
*/
-struct adns_continuation; /* forward declaration (not far!) */
+struct adns_continuation; /* forward declaration (not far!) */
typedef void (*cont_fn_t)(struct adns_continuation *cr, err_t ugh);
struct adns_continuation {
- unsigned long qtid; /* query transaction id number */
- int type; /* T_TXT or T_KEY, selecting rr type of interest */
- cont_fn_t cont_fn; /* function to carry on suspended work */
- struct id id; /* subject of query */
- bool sgw_specified;
- struct id sgw_id; /* peer, if constrained */
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
- struct gw_info *gateways_from_dns; /* answer, if looking for our TXT rrs */
+ unsigned long qtid; /* query transaction id number */
+ int type; /* T_TXT or T_KEY, selecting rr type of interest */
+ cont_fn_t cont_fn; /* function to carry on suspended work */
+ struct id id; /* subject of query */
+ bool sgw_specified;
+ struct id sgw_id; /* peer, if constrained */
+ lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
+ struct gw_info *gateways_from_dns; /* answer, if looking for our TXT rrs */
#ifdef USE_KEYRR
- struct pubkey_list *keys_from_dns; /* answer, if looking for KEY rrs */
+ struct pubkey_list *keys_from_dns; /* answer, if looking for KEY rrs */
#endif
- struct adns_continuation *previous, *next;
- struct pubkey *last_info; /* the last structure we accumulated */
+ struct adns_continuation *previous, *next;
+ struct pubkey *last_info; /* the last structure we accumulated */
#ifdef USE_LWRES
- bool used; /* have we called the cont_fn yet? */
- struct {
- u_char name_buf[NS_MAXDNAME + 2];
- } query;
+ bool used; /* have we called the cont_fn yet? */
+ struct {
+ u_char name_buf[NS_MAXDNAME + 2];
+ } query;
#else /* ! USE_LWRES */
- struct adns_query query;
+ struct adns_query query;
#endif /* ! USE_LWRES */
};
-extern err_t start_adns_query(const struct id *id /* domain to query */
- , const struct id *sgw_id /* if non-null, any accepted gw_info must match */
- , int type /* T_TXT or T_KEY, selecting rr type of interest */
- , cont_fn_t cont_fn /* continuation function */
- , struct adns_continuation *cr);
+extern err_t start_adns_query(const struct id *id /* domain to query */
+ , const struct id *sgw_id /* if non-null, any accepted gw_info must match */
+ , int type /* T_TXT or T_KEY, selecting rr type of interest */
+ , cont_fn_t cont_fn /* continuation function */
+ , struct adns_continuation *cr);
/* Gateway info gleaned from reverse DNS of client */
struct gw_info {
- unsigned refcnt; /* reference counted! */
- unsigned pref; /* preference: lower is better */
-#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
- struct id client_id; /* id of client of peer */
- struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
- bool gw_key_present;
- struct pubkey *key;
- struct gw_info *next;
+ unsigned refcnt; /* reference counted! */
+ unsigned pref; /* preference: lower is better */
+#define NO_TIME ((time_t) -2) /* time_t value meaning "not_yet" */
+ struct id client_id; /* id of client of peer */
+ struct id gw_id; /* id of peer (if id_is_ipaddr, .ip_addr is address) */
+ bool gw_key_present;
+ struct pubkey *key;
+ struct gw_info *next;
};
extern void gw_addref(struct gw_info *gw)
- , gw_delref(struct gw_info **gwp);
+ , gw_delref(struct gw_info **gwp);
extern void reset_adns_restart_count(void);
diff --git a/src/pluto/dsa.c b/src/pluto/dsa.c
deleted file mode 100644
index c5982fbf4..000000000
--- a/src/pluto/dsa.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/* dsa.c - DSA signature scheme
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <config.h> */
-#endif /* !PLUTO */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PLUTO
-/* #include <assert.h> */
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif
-
-#include "dsa.h"
-
-typedef struct {
- MPI p; /* prime */
- MPI q; /* group order */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
-} DSA_public_key;
-
-
-typedef struct {
- MPI p; /* prime */
- MPI q; /* group order */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
- MPI x; /* secret exponent */
-} DSA_secret_key;
-
-
-static MPI gen_k( MPI q );
-static void test_keys( DSA_secret_key *sk, unsigned qbits );
-static int check_secret_key( DSA_secret_key *sk );
-static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
-static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
-static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-/****************
- * Generate a random secret exponent k less than q
- */
-static MPI
-gen_k( MPI q )
-{
- MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
- unsigned int nbits = mpi_get_nbits(q);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
-
- if( DBG_CIPHER )
- log_debug("choosing a random k ");
- for(;;) {
- if( DBG_CIPHER )
- progress('.');
-
- if( !rndbuf || nbits < 32 ) {
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 1, 1 );
- }
- else { /* change only some of the higher bits */
- /* we could imporove this by directly requesting more memory
- * at the first call to get_random_bits() and use this the here
- * maybe it is easier to do this directly in random.c */
- char *pp = get_random_bits( 32, 1, 1 );
- memcpy( rndbuf,pp, 4 );
- m_free(pp);
- }
- mpi_set_buffer( k, rndbuf, nbytes, 0 );
- if( mpi_test_bit( k, nbits-1 ) )
- mpi_set_highbit( k, nbits-1 );
- else {
- mpi_set_highbit( k, nbits-1 );
- mpi_clear_bit( k, nbits-1 );
- }
-
- if( !(mpi_cmp( k, q ) < 0) ) { /* check: k < q */
- if( DBG_CIPHER )
- progress('+');
- continue; /* no */
- }
- if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
- if( DBG_CIPHER )
- progress('-');
- continue; /* no */
- }
- break; /* okay */
- }
- m_free(rndbuf);
- if( DBG_CIPHER )
- progress('\n');
-
- return k;
-}
-
-
-static void
-test_keys( DSA_secret_key *sk, unsigned qbits )
-{
- DSA_public_key pk;
- MPI test = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
- MPI out1_a = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
- MPI out1_b = mpi_alloc( qbits / BITS_PER_MPI_LIMB );
-
- pk.p = sk->p;
- pk.q = sk->q;
- pk.g = sk->g;
- pk.y = sk->y;
- /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/
- { char *p = get_random_bits( qbits, 0, 0 );
- mpi_set_buffer( test, p, (qbits+7)/8, 0 );
- m_free(p);
- }
-
- sign( out1_a, out1_b, test, sk );
- if( !verify( out1_a, out1_b, test, &pk ) )
- log_fatal("DSA:: sign, verify failed\n");
-
- mpi_free( test );
- mpi_free( out1_a );
- mpi_free( out1_b );
-}
-
-
-
-/****************
- * Generate a DSA key pair with a key of size NBITS
- * Returns: 2 structures filled with all needed values
- * and an array with the n-1 factors of (p-1)
- */
-static void
-generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
-{
- MPI p; /* the prime */
- MPI q; /* the 160 bit prime factor */
- MPI g; /* the generator */
- MPI y; /* g^x mod p */
- MPI x; /* the secret exponent */
- MPI h, e; /* helper */
- unsigned qbits;
- byte *rndbuf;
-
- assert( nbits >= 512 && nbits <= 1024 );
-
- qbits = 160;
- p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors );
- /* get q out of factors */
- q = mpi_copy((*ret_factors)[0]);
- if( mpi_get_nbits(q) != qbits )
- BUG();
-
- /* find a generator g (h and e are helpers)*/
- /* e = (p-1)/q */
- e = mpi_alloc( mpi_get_nlimbs(p) );
- mpi_sub_ui( e, p, 1 );
- mpi_fdiv_q( e, e, q );
- g = mpi_alloc( mpi_get_nlimbs(p) );
- h = mpi_alloc_set_ui( 1 ); /* we start with 2 */
- do {
- mpi_add_ui( h, h, 1 );
- /* g = h^e mod p */
- mpi_powm( g, h, e, p );
- } while( !mpi_cmp_ui( g, 1 ) ); /* continue until g != 1 */
-
- /* select a random number which has these properties:
- * 0 < x < q-1
- * This must be a very good random number because this
- * is the secret part. */
- if( DBG_CIPHER )
- log_debug("choosing a random x ");
- assert( qbits >= 160 );
- x = mpi_alloc_secure( mpi_get_nlimbs(q) );
- mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
- rndbuf = NULL;
- do {
- if( DBG_CIPHER )
- progress('.');
- if( !rndbuf )
- rndbuf = get_random_bits( qbits, 2, 1 );
- else { /* change only some of the higher bits (= 2 bytes)*/
- char *r = get_random_bits( 16, 2, 1 );
- memcpy(rndbuf, r, 16/8 );
- m_free(r);
- }
- mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
- mpi_clear_highbit( x, qbits+1 );
- } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
- m_free(rndbuf);
- mpi_free( e );
- mpi_free( h );
-
- /* y = g^x mod p */
- y = mpi_alloc( mpi_get_nlimbs(p) );
- mpi_powm( y, g, x, p );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump("dsa p= ", p );
- log_mpidump("dsa q= ", q );
- log_mpidump("dsa g= ", g );
- log_mpidump("dsa y= ", y );
- log_mpidump("dsa x= ", x );
- }
-
- /* copy the stuff to the key structures */
- sk->p = p;
- sk->q = q;
- sk->g = g;
- sk->y = y;
- sk->x = x;
-
- /* now we can test our keys (this should never fail!) */
- test_keys( sk, qbits );
-}
-
-
-
-/****************
- * Test whether the secret key is valid.
- * Returns: if this is a valid key.
- */
-static int
-check_secret_key( DSA_secret_key *sk )
-{
- int rc;
- MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
- mpi_powm( y, sk->g, sk->x, sk->p );
- rc = !mpi_cmp( y, sk->y );
- mpi_free( y );
- return rc;
-}
-
-
-
-/****************
- * Make a DSA signature from HASH and put it into r and s.
- */
-
-static void
-sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
-{
- MPI k;
- MPI kinv;
- MPI tmp;
-
- /* select a random k with 0 < k < q */
- k = gen_k( skey->q );
-
- /* r = (a^k mod p) mod q */
- mpi_powm( r, skey->g, k, skey->p );
- mpi_fdiv_r( r, r, skey->q );
-
- /* kinv = k^(-1) mod q */
- kinv = mpi_alloc( mpi_get_nlimbs(k) );
- mpi_invm(kinv, k, skey->q );
-
- /* s = (kinv * ( hash + x * r)) mod q */
- tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
- mpi_mul( tmp, skey->x, r );
- mpi_add( tmp, tmp, hash );
- mpi_mulm( s , kinv, tmp, skey->q );
-
- mpi_free(k);
- mpi_free(kinv);
- mpi_free(tmp);
-}
-
-
-/****************
- * Returns true if the signature composed from R and S is valid.
- */
-static int
-verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
-{
- int rc;
- MPI w, u1, u2, v;
- MPI base[3];
- MPI exp[3];
-
-
- if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
- return 0; /* assertion 0 < r < q failed */
- if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
- return 0; /* assertion 0 < s < q failed */
-
- w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
- v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
-
- /* w = s^(-1) mod q */
- mpi_invm( w, s, pkey->q );
-
- /* u1 = (hash * w) mod q */
- mpi_mulm( u1, hash, w, pkey->q );
-
- /* u2 = r * w mod q */
- mpi_mulm( u2, r, w, pkey->q );
-
- /* v = g^u1 * y^u2 mod p mod q */
- base[0] = pkey->g; exp[0] = u1;
- base[1] = pkey->y; exp[1] = u2;
- base[2] = NULL; exp[2] = NULL;
- mpi_mulpowm( v, base, exp, pkey->p );
- mpi_fdiv_r( v, v, pkey->q );
-
- rc = !mpi_cmp( v, r );
-
- mpi_free(w);
- mpi_free(u1);
- mpi_free(u2);
- mpi_free(v);
- return rc;
-}
-
-
-/*********************************************
- ************** interface ******************
- *********************************************/
-
-int
-dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
-
- generate( &sk, nbits, retfactors );
- skey[0] = sk.p;
- skey[1] = sk.q;
- skey[2] = sk.g;
- skey[3] = sk.y;
- skey[4] = sk.x;
- return 0;
-}
-
-
-int
-dsa_check_secret_key( int algo, MPI *skey )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- if( !check_secret_key( &sk ) )
- return G10ERR_BAD_SECKEY;
-
- return 0;
-}
-
-
-
-int
-dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
-{
- DSA_secret_key sk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- sign( resarr[0], resarr[1], data, &sk );
- return 0;
-}
-
-int
-dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
-{
- DSA_public_key pk;
-
- if( algo != PUBKEY_ALGO_DSA )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1] || !hash
- || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.q = pkey[1];
- pk.g = pkey[2];
- pk.y = pkey[3];
- if( !verify( data[0], data[1], hash, &pk ) )
- return G10ERR_BAD_SIGN;
- return 0;
-}
-
-
-
-unsigned
-dsa_get_nbits( int algo, MPI *pkey )
-{
- if( algo != PUBKEY_ALGO_DSA )
- return 0;
- return mpi_get_nbits( pkey[0] );
-}
-
-
-/****************
- * Return some information about the algorithm. We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- * the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- * 1 set : allows encryption
- */
-const char *
-dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
- int *use )
-{
- *npkey = 4;
- *nskey = 5;
- *nenc = 0;
- *nsig = 2;
-
- switch( algo ) {
- case PUBKEY_ALGO_DSA: *use = PUBKEY_USAGE_SIG; return "DSA";
- default: *use = 0; return NULL;
- }
-}
-
-
diff --git a/src/pluto/dsa.h b/src/pluto/dsa.h
deleted file mode 100644
index 1456d65b6..000000000
--- a/src/pluto/dsa.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* dsa.h - DSA signature scheme
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_DSA_H
-#define G10_DSA_H
-
-int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
-int dsa_check_secret_key( int algo, MPI *skey );
-int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI), void *opaquev );
-unsigned dsa_get_nbits( int algo, MPI *pkey );
-const char *dsa_get_info( int algo, int *npkey, int *nskey,
- int *nenc, int *nsig, int *use );
-
-#endif /*G10_DSA_H*/
diff --git a/src/pluto/elgamal.c b/src/pluto/elgamal.c
deleted file mode 100644
index 0c099bb90..000000000
--- a/src/pluto/elgamal.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/* elgamal.c - ElGamal Public Key encryption
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * For a description of the algorithm, see:
- * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
- * ISBN 0-471-11709-9. Pages 476 ff.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <config.h> */
-#endif /* !PLUTO */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef PLUTO
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif
-
-#include "elgamal.h"
-
-typedef struct {
- MPI p; /* prime */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
-} ELG_public_key;
-
-
-typedef struct {
- MPI p; /* prime */
- MPI g; /* group generator */
- MPI y; /* g^x mod p */
- MPI x; /* secret exponent */
-} ELG_secret_key;
-
-
-static void test_keys( ELG_secret_key *sk, unsigned nbits );
-static MPI gen_k( MPI p );
-static void generate( ELG_secret_key *sk, unsigned nbits, MPI **factors );
-static int check_secret_key( ELG_secret_key *sk );
-static void encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey );
-static void decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey );
-static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
-static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
-
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-static void
-test_keys( ELG_secret_key *sk, unsigned nbits )
-{
- ELG_public_key pk;
- MPI test = mpi_alloc( 0 );
- MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
- MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
- MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
-
- pk.p = sk->p;
- pk.g = sk->g;
- pk.y = sk->y;
-
- /*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/
- { char *p = get_random_bits( nbits, 0, 0 );
- mpi_set_buffer( test, p, (nbits+7)/8, 0 );
- m_free(p);
- }
-
- encrypt( out1_a, out1_b, test, &pk );
- decrypt( out2, out1_a, out1_b, sk );
- if( mpi_cmp( test, out2 ) )
- log_fatal("ElGamal operation: encrypt, decrypt failed\n");
-
- sign( out1_a, out1_b, test, sk );
- if( !verify( out1_a, out1_b, test, &pk ) )
- log_fatal("ElGamal operation: sign, verify failed\n");
-
- mpi_free( test );
- mpi_free( out1_a );
- mpi_free( out1_b );
- mpi_free( out2 );
-}
-
-
-/****************
- * generate a random secret exponent k from prime p, so
- * that k is relatively prime to p-1
- */
-static MPI
-gen_k( MPI p )
-{
- MPI k = mpi_alloc_secure( 0 );
- MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
- MPI p_1 = mpi_copy(p);
- unsigned int nbits = mpi_get_nbits(p);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
-
- if( DBG_CIPHER )
- log_debug("choosing a random k ");
- mpi_sub_ui( p_1, p, 1);
- for(;;) {
- if( DBG_CIPHER )
- progress('.');
- if( !rndbuf || nbits < 32 ) {
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 1, 1 );
- }
- else { /* change only some of the higher bits */
- /* we could imporove this by directly requesting more memory
- * at the first call to get_random_bits() and use this the here
- * maybe it is easier to do this directly in random.c */
- char *pp = get_random_bits( 32, 1, 1 );
- memcpy( rndbuf,pp, 4 );
- m_free(pp);
- }
- mpi_set_buffer( k, rndbuf, nbytes, 0 );
-
- for(;;) {
- /* make sure that the number is of the exact lenght */
- if( mpi_test_bit( k, nbits-1 ) )
- mpi_set_highbit( k, nbits-1 );
- else {
- mpi_set_highbit( k, nbits-1 );
- mpi_clear_bit( k, nbits-1 );
- }
- if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
- if( DBG_CIPHER )
- progress('+');
- break; /* no */
- }
- if( !(mpi_cmp_ui( k, 0 ) > 0) ) { /* check: k > 0 */
- if( DBG_CIPHER )
- progress('-');
- break; /* no */
- }
- if( mpi_gcd( temp, k, p_1 ) )
- goto found; /* okay, k is relatively prime to (p-1) */
- mpi_add_ui( k, k, 1 );
- }
- }
- found:
- m_free(rndbuf);
- if( DBG_CIPHER )
- progress('\n');
- mpi_free(p_1);
- mpi_free(temp);
-
- return k;
-}
-
-/****************
- * Generate a key pair with a key of size NBITS
- * Returns: 2 structures filles with all needed values
- * and an array with n-1 factors of (p-1)
- */
-static void
-generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
-{
- MPI p; /* the prime */
- MPI p_min1;
- MPI g;
- MPI x; /* the secret exponent */
- MPI y;
- MPI temp;
- unsigned qbits;
- byte *rndbuf;
-
- p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
- temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
- if( nbits < 512 )
- qbits = 120;
- else if( nbits <= 1024 )
- qbits = 160;
- else if( nbits <= 2048 )
- qbits = 200;
- else
- qbits = 240;
- g = mpi_alloc(1);
- p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
- mpi_sub_ui(p_min1, p, 1);
-
-
- /* select a random number which has these properties:
- * 0 < x < p-1
- * This must be a very good random number because this is the
- * secret part. The prime is public and may be shared anyway,
- * so a random generator level of 1 is used for the prime.
- */
- x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
- if( DBG_CIPHER )
- log_debug("choosing a random x ");
- rndbuf = NULL;
- do {
- if( DBG_CIPHER )
- progress('.');
- if( rndbuf ) { /* change only some of the higher bits */
- if( nbits < 16 ) {/* should never happen ... */
- m_free(rndbuf);
- rndbuf = get_random_bits( nbits, 2, 1 );
- }
- else {
- char *r = get_random_bits( 16, 2, 1 );
- memcpy(rndbuf, r, 16/8 );
- m_free(r);
- }
- }
- else
- rndbuf = get_random_bits( nbits, 2, 1 );
- mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
- mpi_clear_highbit( x, nbits+1 );
- } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
- m_free(rndbuf);
-
- y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
- mpi_powm( y, g, x, p );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump("elg p= ", p );
- log_mpidump("elg g= ", g );
- log_mpidump("elg y= ", y );
- log_mpidump("elg x= ", x );
- }
-
- /* copy the stuff to the key structures */
- sk->p = p;
- sk->g = g;
- sk->y = y;
- sk->x = x;
-
- /* now we can test our keys (this should never fail!) */
- test_keys( sk, nbits - 64 );
-
- mpi_free( p_min1 );
- mpi_free( temp );
-}
-
-
-/****************
- * Test whether the secret key is valid.
- * Returns: if this is a valid key.
- */
-static int
-check_secret_key( ELG_secret_key *sk )
-{
- int rc;
- MPI y = mpi_alloc( mpi_get_nlimbs(sk->y) );
-
- mpi_powm( y, sk->g, sk->x, sk->p );
- rc = !mpi_cmp( y, sk->y );
- mpi_free( y );
- return rc;
-}
-
-
-static void
-encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
-{
- MPI k;
-
- /* Note: maybe we should change the interface, so that it
- * is possible to check that input is < p and return an
- * error code.
- */
-
- k = gen_k( pkey->p );
- mpi_powm( a, pkey->g, k, pkey->p );
- /* b = (y^k * input) mod p
- * = ((y^k mod p) * (input mod p)) mod p
- * and because input is < p
- * = ((y^k mod p) * input) mod p
- */
- mpi_powm( b, pkey->y, k, pkey->p );
- mpi_mulm( b, b, input, pkey->p );
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg encrypted y= ", pkey->y);
- log_mpidump("elg encrypted p= ", pkey->p);
- log_mpidump("elg encrypted k= ", k);
- log_mpidump("elg encrypted M= ", input);
- log_mpidump("elg encrypted a= ", a);
- log_mpidump("elg encrypted b= ", b);
- }
- #endif
- mpi_free(k);
-}
-
-
-
-
-static void
-decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
-{
- MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
-
- /* output = b/(a^x) mod p */
-
- mpi_powm( t1, a, skey->x, skey->p );
- mpi_invm( t1, t1, skey->p );
- mpi_mulm( output, b, t1, skey->p );
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg decrypted x= ", skey->x);
- log_mpidump("elg decrypted p= ", skey->p);
- log_mpidump("elg decrypted a= ", a);
- log_mpidump("elg decrypted b= ", b);
- log_mpidump("elg decrypted M= ", output);
- }
- #endif
- mpi_free(t1);
-}
-
-
-/****************
- * Make an Elgamal signature out of INPUT
- */
-
-static void
-sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
-{
- MPI k;
- MPI t = mpi_alloc( mpi_get_nlimbs(a) );
- MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
- MPI p_1 = mpi_copy(skey->p);
-
- /*
- * b = (t * inv) mod (p-1)
- * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
- * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
- *
- */
- mpi_sub_ui(p_1, p_1, 1);
- k = gen_k( skey->p );
- mpi_powm( a, skey->g, k, skey->p );
- mpi_mul(t, skey->x, a );
- mpi_subm(t, input, t, p_1 );
- while( mpi_is_neg(t) )
- mpi_add(t, t, p_1);
- mpi_invm(inv, k, p_1 );
- mpi_mulm(b, t, inv, p_1 );
-
- #if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg sign p= ", skey->p);
- log_mpidump("elg sign g= ", skey->g);
- log_mpidump("elg sign y= ", skey->y);
- log_mpidump("elg sign x= ", skey->x);
- log_mpidump("elg sign k= ", k);
- log_mpidump("elg sign M= ", input);
- log_mpidump("elg sign a= ", a);
- log_mpidump("elg sign b= ", b);
- }
- #endif
- mpi_free(k);
- mpi_free(t);
- mpi_free(inv);
- mpi_free(p_1);
-}
-
-
-/****************
- * Returns true if the signature composed of A and B is valid.
- */
-static int
-verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
-{
- int rc;
- MPI t1;
- MPI t2;
- MPI base[4];
- MPI exp[4];
-
- if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
- return 0; /* assertion 0 < a < p failed */
-
- t1 = mpi_alloc( mpi_get_nlimbs(a) );
- t2 = mpi_alloc( mpi_get_nlimbs(a) );
-
- #if 0
- /* t1 = (y^a mod p) * (a^b mod p) mod p */
- mpi_powm( t1, pkey->y, a, pkey->p );
- mpi_powm( t2, a, b, pkey->p );
- mpi_mulm( t1, t1, t2, pkey->p );
-
- /* t2 = g ^ input mod p */
- mpi_powm( t2, pkey->g, input, pkey->p );
-
- rc = !mpi_cmp( t1, t2 );
- #elif 0
- /* t1 = (y^a mod p) * (a^b mod p) mod p */
- base[0] = pkey->y; exp[0] = a;
- base[1] = a; exp[1] = b;
- base[2] = NULL; exp[2] = NULL;
- mpi_mulpowm( t1, base, exp, pkey->p );
-
- /* t2 = g ^ input mod p */
- mpi_powm( t2, pkey->g, input, pkey->p );
-
- rc = !mpi_cmp( t1, t2 );
- #else
- /* t1 = g ^ - input * y ^ a * a ^ b mod p */
- mpi_invm(t2, pkey->g, pkey->p );
- base[0] = t2 ; exp[0] = input;
- base[1] = pkey->y; exp[1] = a;
- base[2] = a; exp[2] = b;
- base[3] = NULL; exp[3] = NULL;
- mpi_mulpowm( t1, base, exp, pkey->p );
- rc = !mpi_cmp_ui( t1, 1 );
-
- #endif
-
- mpi_free(t1);
- mpi_free(t2);
- return rc;
-}
-
-/*********************************************
- ************** interface ******************
- *********************************************/
-
-int
-elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
-
- generate( &sk, nbits, retfactors );
- skey[0] = sk.p;
- skey[1] = sk.g;
- skey[2] = sk.y;
- skey[3] = sk.x;
- return 0;
-}
-
-
-int
-elg_check_secret_key( int algo, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- if( !check_secret_key( &sk ) )
- return G10ERR_BAD_SECKEY;
-
- return 0;
-}
-
-
-
-int
-elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
-{
- ELG_public_key pk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !pkey[0] || !pkey[1] || !pkey[2] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.g = pkey[1];
- pk.y = pkey[2];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( pk.p ) );
- encrypt( resarr[0], resarr[1], data, &pk );
- return 0;
-}
-
-int
-elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1]
- || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- *result = mpi_alloc_secure( mpi_get_nlimbs( sk.p ) );
- decrypt( *result, data[0], data[1], &sk );
- return 0;
-}
-
-int
-elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
-{
- ELG_secret_key sk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] )
- return G10ERR_BAD_MPI;
-
- sk.p = skey[0];
- sk.g = skey[1];
- sk.y = skey[2];
- sk.x = skey[3];
- resarr[0] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- resarr[1] = mpi_alloc( mpi_get_nlimbs( sk.p ) );
- sign( resarr[0], resarr[1], data, &sk );
- return 0;
-}
-
-int
-elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI) UNUSED, void *opaquev UNUSED)
-{
- ELG_public_key pk;
-
- if( !is_ELGAMAL(algo) )
- return G10ERR_PUBKEY_ALGO;
- if( !data[0] || !data[1] || !hash
- || !pkey[0] || !pkey[1] || !pkey[2] )
- return G10ERR_BAD_MPI;
-
- pk.p = pkey[0];
- pk.g = pkey[1];
- pk.y = pkey[2];
- if( !verify( data[0], data[1], hash, &pk ) )
- return G10ERR_BAD_SIGN;
- return 0;
-}
-
-
-
-unsigned
-elg_get_nbits( int algo, MPI *pkey )
-{
- if( !is_ELGAMAL(algo) )
- return 0;
- return mpi_get_nbits( pkey[0] );
-}
-
-
-/****************
- * Return some information about the algorithm. We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- * the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- * 1 set : allows encryption
- * NOTE: This function allows signing also for ELG-E, which is not
- * okay but a bad hack to allow to work with old gpg keys. The real check
- * is done in the gnupg ocde depending on the packet version.
- */
-const char *
-elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
- int *use )
-{
- *npkey = 3;
- *nskey = 4;
- *nenc = 2;
- *nsig = 2;
-
- switch( algo ) {
- case PUBKEY_ALGO_ELGAMAL:
- *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
- return "ELG";
- case PUBKEY_ALGO_ELGAMAL_E:
- *use = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC;
- return "ELG-E";
- default: *use = 0; return NULL;
- }
-}
-
-
diff --git a/src/pluto/elgamal.h b/src/pluto/elgamal.h
deleted file mode 100644
index f104c2a52..000000000
--- a/src/pluto/elgamal.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* elgamal.h
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_ELGAMAL_H
-#define G10_ELGAMAL_H
-
-int elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
-int elg_check_secret_key( int algo, MPI *skey );
-int elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
-int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
-int elg_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
- int (*cmp)(void *, MPI), void *opaquev );
-unsigned elg_get_nbits( int algo, MPI *pkey );
-const char *elg_get_info( int algo, int *npkey, int *nskey,
- int *nenc, int *nsig, int *use );
-
-
-#endif /*G10_ELGAMAL_H*/
diff --git a/src/pluto/fetch.c b/src/pluto/fetch.c
index c8a98cd9b..6f7f1215f 100644
--- a/src/pluto/fetch.c
+++ b/src/pluto/fetch.c
@@ -1,6 +1,6 @@
/* Dynamic fetching of X.509 CRLs
* Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2002-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: fetch.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <stdlib.h>
@@ -25,24 +23,17 @@
#include <pthread.h>
#endif
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif
-
#include <freeswan.h>
-#ifdef LIBLDAP
-#ifndef LDAP_DEPRECATED
-#define LDAP_DEPRECATED 1
-#endif
-#include <ldap.h>
-#endif
+#include <library.h>
+#include <debug.h>
+#include <asn1/asn1.h>
+#include <asn1/pem.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
#include "id.h"
-#include "asn1.h"
#include "pem.h"
#include "x509.h"
#include "ca.h"
@@ -52,13 +43,13 @@
#include "fetch.h"
fetch_req_t empty_fetch_req = {
- NULL , /* next */
- 0 , /* installed */
- 0 , /* trials */
+ NULL , /* next */
+ 0 , /* installed */
+ 0 , /* trials */
{ NULL, 0}, /* issuer */
{ NULL, 0}, /* authKeyID */
{ NULL, 0}, /* authKeySerialNumber */
- NULL /* distributionPoints */
+ NULL /* distributionPoints */
};
/* chained list of crl fetch requests */
@@ -79,189 +70,174 @@ static pthread_mutex_t ocsp_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t fetch_wake_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t fetch_wake_cond = PTHREAD_COND_INITIALIZER;
-/*
+/**
* lock access to my certs and keys
*/
-void
-lock_certs_and_keys(const char *who)
+void lock_certs_and_keys(const char *who)
{
- pthread_mutex_lock(&certs_and_keys_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("certs and keys locked by '%s'", who)
- )
+ pthread_mutex_lock(&certs_and_keys_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("certs and keys locked by '%s'", who)
+ )
}
-/*
- * unlock access to my certs and keys
+/**
+ * Unlock access to my certs and keys
*/
-void
-unlock_certs_and_keys(const char *who)
+void unlock_certs_and_keys(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("certs and keys unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&certs_and_keys_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("certs and keys unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&certs_and_keys_mutex);
}
-/*
- * lock access to the chained authcert list
+/**
+ * Lock access to the chained authcert list
*/
-void
-lock_authcert_list(const char *who)
+void lock_authcert_list(const char *who)
{
- pthread_mutex_lock(&authcert_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("authcert list locked by '%s'", who)
- )
+ pthread_mutex_lock(&authcert_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("authcert list locked by '%s'", who)
+ )
}
-/*
- * unlock access to the chained authcert list
+/**
+ * Unlock access to the chained authcert list
*/
-void
-unlock_authcert_list(const char *who)
+void unlock_authcert_list(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("authcert list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&authcert_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("authcert list unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&authcert_list_mutex);
}
-/*
- * lock access to the chained crl list
+/**
+ * Lock access to the chained crl list
*/
-void
-lock_crl_list(const char *who)
+void lock_crl_list(const char *who)
{
- pthread_mutex_lock(&crl_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("crl list locked by '%s'", who)
- )
+ pthread_mutex_lock(&crl_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("crl list locked by '%s'", who)
+ )
}
-/*
- * unlock access to the chained crl list
+/**
+ * Unlock access to the chained crl list
*/
-void
-unlock_crl_list(const char *who)
+void unlock_crl_list(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("crl list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&crl_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("crl list unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&crl_list_mutex);
}
-/*
- * lock access to the ocsp cache
+/**
+ * Lock access to the ocsp cache
*/
-extern void
-lock_ocsp_cache(const char *who)
+extern void lock_ocsp_cache(const char *who)
{
- pthread_mutex_lock(&ocsp_cache_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp cache locked by '%s'", who)
- )
+ pthread_mutex_lock(&ocsp_cache_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ocsp cache locked by '%s'", who)
+ )
}
-/*
- * unlock access to the ocsp cache
+/**
+ * Unlock access to the ocsp cache
*/
-extern void
-unlock_ocsp_cache(const char *who)
+extern void unlock_ocsp_cache(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp cache unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ocsp_cache_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ocsp cache unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&ocsp_cache_mutex);
}
-/*
- * lock access to the ca info list
+/**
+ * Lock access to the ca info list
*/
-extern void
-lock_ca_info_list(const char *who)
+extern void lock_ca_info_list(const char *who)
{
- pthread_mutex_lock(&ca_info_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ca info list locked by '%s'", who)
- )
+ pthread_mutex_lock(&ca_info_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ca info list locked by '%s'", who)
+ )
}
-/*
- * unlock access to the ca info list
+/**
+ * Unlock access to the ca info list
*/
-extern void
-unlock_ca_info_list(const char *who)
+extern void unlock_ca_info_list(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("ca info list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ca_info_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ca info list unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&ca_info_list_mutex);
}
-/*
- * lock access to the chained crl fetch request list
+/**
+ * Lock access to the chained crl fetch request list
*/
-static void
-lock_crl_fetch_list(const char *who)
+static void lock_crl_fetch_list(const char *who)
{
- pthread_mutex_lock(&crl_fetch_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("crl fetch request list locked by '%s'", who)
- )
+ pthread_mutex_lock(&crl_fetch_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("crl fetch request list locked by '%s'", who)
+ )
}
-/*
- * unlock access to the chained crl fetch request list
+/**
+ * Unlock access to the chained crl fetch request list
*/
-static void
-unlock_crl_fetch_list(const char *who)
+static void unlock_crl_fetch_list(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("crl fetch request list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&crl_fetch_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("crl fetch request list unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&crl_fetch_list_mutex);
}
-/*
- * lock access to the chained ocsp fetch request list
+/**
+ * Lock access to the chained ocsp fetch request list
*/
-static void
-lock_ocsp_fetch_list(const char *who)
+static void lock_ocsp_fetch_list(const char *who)
{
- pthread_mutex_lock(&ocsp_fetch_list_mutex);
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp fetch request list locked by '%s'", who)
- )
+ pthread_mutex_lock(&ocsp_fetch_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ocsp fetch request list locked by '%s'", who)
+ )
}
-/*
- * unlock access to the chained ocsp fetch request list
+/**
+ * Unlock access to the chained ocsp fetch request list
*/
-static void
-unlock_ocsp_fetch_list(const char *who)
+static void unlock_ocsp_fetch_list(const char *who)
{
- DBG(DBG_CONTROLMORE,
- DBG_log("ocsp fetch request list unlocked by '%s'", who)
- )
- pthread_mutex_unlock(&ocsp_fetch_list_mutex);
+ DBG(DBG_CONTROLMORE,
+ DBG_log("ocsp fetch request list unlocked by '%s'", who)
+ )
+ pthread_mutex_unlock(&ocsp_fetch_list_mutex);
}
-/*
- * wakes up the sleeping fetch thread
+/**
+ * Wakes up the sleeping fetch thread
*/
-void
-wake_fetch_thread(const char *who)
+void wake_fetch_thread(const char *who)
{
- if (crl_check_interval > 0)
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("fetch thread wake call by '%s'", who)
- )
- pthread_mutex_lock(&fetch_wake_mutex);
- pthread_cond_signal(&fetch_wake_cond);
- pthread_mutex_unlock(&fetch_wake_mutex);
- }
+ if (crl_check_interval > 0)
+ {
+ DBG(DBG_CONTROLMORE,
+ DBG_log("fetch thread wake call by '%s'", who)
+ )
+ pthread_mutex_lock(&fetch_wake_mutex);
+ pthread_cond_signal(&fetch_wake_cond);
+ pthread_mutex_unlock(&fetch_wake_mutex);
+ }
}
#else /* !THREADS */
#define lock_crl_fetch_list(who) /* do nothing */
@@ -270,817 +246,506 @@ wake_fetch_thread(const char *who)
#define unlock_ocsp_fetch_list(who) /* do nothing */
#endif /* !THREADS */
-/*
- * free the dynamic memory used to store fetch requests
+/**
+ * Free the dynamic memory used to store fetch requests
*/
-static void
-free_fetch_request(fetch_req_t *req)
+static void free_fetch_request(fetch_req_t *req)
{
- pfree(req->issuer.ptr);
- pfreeany(req->authKeySerialNumber.ptr);
- pfreeany(req->authKeyID.ptr);
- free_generalNames(req->distributionPoints, TRUE);
- pfree(req);
-}
-
-/* writes data into a dynamically resizeable chunk_t
- * needed for libcurl responses
- */
-size_t
-write_buffer(void *ptr, size_t size, size_t nmemb, void *data)
-{
- size_t realsize = size * nmemb;
- chunk_t *mem = (chunk_t*)data;
-
- mem->ptr = (u_char *)realloc(mem->ptr, mem->len + realsize);
- if (mem->ptr) {
- memcpy(&(mem->ptr[mem->len]), ptr, realsize);
- mem->len += realsize;
- }
- return realsize;
+ free(req->issuer.ptr);
+ free(req->authKeySerialNumber.ptr);
+ free(req->authKeyID.ptr);
+ free_generalNames(req->distributionPoints, TRUE);
+ free(req);
}
#ifdef THREADS
-/*
- * fetches a binary blob from a url with libcurl
+/**
+ * Fetch an ASN.1 blob coded in PEM or DER format from a URL
*/
-static err_t
-fetch_curl(char *url, chunk_t *blob)
+bool fetch_asn1_blob(char *url, chunk_t *blob)
{
-#ifdef LIBCURL
- char errorbuffer[CURL_ERROR_SIZE] = "";
- chunk_t response = empty_chunk;
- CURLcode res;
-
- /* get it with libcurl */
- CURL *curl = curl_easy_init();
-
- if (curl != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("Trying cURL '%s'", url)
- )
-
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
- {
- blob->len = response.len;
- blob->ptr = alloc_bytes(response.len, "curl blob");
- memcpy(blob->ptr, response.ptr, response.len);
- }
- else
+ DBG1(" fetching crl from '%s' ...", url);
+ if (lib->fetcher->fetch(lib->fetcher, url, blob, FETCH_END) != SUCCESS)
{
- plog("fetching uri (%s) with libcurl failed: %s", url, errorbuffer);
+ DBG1("crl fetching failed");
+ return FALSE;
}
- curl_easy_cleanup(curl);
- /* not using freeanychunk because of realloc (no leak detective) */
- curl_free(response.ptr);
- }
- return strlen(errorbuffer) > 0 ? "libcurl error" : NULL;
-#else /* !LIBCURL */
- return "warning: not compiled with libcurl support";
-#endif /* !LIBCURL */
-}
-
-#ifdef LIBLDAP
-/*
- * parses the result returned by an ldap query
- */
-static err_t
-parse_ldap_result(LDAP * ldap, LDAPMessage *result, chunk_t *blob)
-{
- err_t ugh = NULL;
-
- LDAPMessage * entry = ldap_first_entry(ldap, result);
- if (entry != NULL)
- {
- BerElement *ber = NULL;
- char *attr;
-
- attr = ldap_first_attribute(ldap, entry, &ber);
-
- if (attr != NULL)
+ if (is_asn1(*blob))
{
- struct berval **values = ldap_get_values_len(ldap, entry, attr);
-
- if (values != NULL)
- {
- if (values[0] != NULL)
- {
- blob->len = values[0]->bv_len;
- blob->ptr = alloc_bytes(blob->len, "ldap blob");
- memcpy(blob->ptr, values[0]->bv_val, blob->len);
- if (values[1] != NULL)
- {
- plog("warning: more than one value was fetched from LDAP URL");
- }
- }
- else
- {
- ugh = "no values in attribute";
- }
- ldap_value_free_len(values);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ldap_memfree(attr);
+ DBG2(" fetched blob coded in DER format");
}
else
{
- ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
- }
- ber_free(ber, 0);
- }
- else
- {
- ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
- }
- return ugh;
-}
-
-/*
- * fetches a binary blob from an ldap url
- */
-static err_t
-fetch_ldap_url(char *url, chunk_t *blob)
-{
- LDAPURLDesc *lurl;
- err_t ugh = NULL;
- int rc;
-
- DBG(DBG_CONTROL,
- DBG_log("Trying LDAP URL '%s'", url)
- )
-
- rc = ldap_url_parse(url, &lurl);
-
- if (rc == LDAP_SUCCESS)
- {
- LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port);
-
- if (ldap != NULL)
- {
- int ldap_version = LDAP_VERSION3;
- struct timeval timeout;
+ bool pgp = FALSE;
- timeout.tv_sec = FETCH_CMD_TIMEOUT;
- timeout.tv_usec = 0;
- ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
- ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
-
- rc = ldap_simple_bind_s(ldap, NULL, NULL);
-
- if (rc == LDAP_SUCCESS)
- {
- LDAPMessage *result;
-
- timeout.tv_sec = FETCH_CMD_TIMEOUT;
- timeout.tv_usec = 0;
-
- rc = ldap_search_st(ldap, lurl->lud_dn
- , lurl->lud_scope
- , lurl->lud_filter
- , lurl->lud_attrs
- , 0, &timeout, &result);
-
- if (rc == LDAP_SUCCESS)
+ if (pem_to_bin(blob, chunk_empty, &pgp) != SUCCESS)
{
- ugh = parse_ldap_result(ldap, result, blob);
- ldap_msgfree(result);
+ free(blob->ptr);
+ return FALSE;
+ }
+ if (is_asn1(*blob))
+ {
+ DBG2(" fetched blob coded in PEM format");
}
else
{
- ugh = ldap_err2string(rc);
+ DBG1("crl fetched successfully but data coded in unknown format");
+ free(blob->ptr);
+ return FALSE;
}
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- ldap_unbind_s(ldap);
- }
- else
- {
- ugh = "ldap init";
- }
- ldap_free_urldesc(lurl);
- }
- else
- {
- ugh = ldap_err2string(rc);
- }
- return ugh;
-}
-#else /* !LIBLDAP */
-static err_t
-fetch_ldap_url(char *url, chunk_t *blob)
-{
- return "LDAP URL fetching not activated in pluto source code";
-}
-#endif /* !LIBLDAP */
-
-/*
- * fetch an ASN.1 blob coded in PEM or DER format from a URL
- */
-static err_t
-fetch_asn1_blob(char *url, chunk_t *blob)
-{
- err_t ugh = NULL;
-
- if (strlen(url) >= 4 && strncasecmp(url, "ldap", 4) == 0)
- {
- ugh = fetch_ldap_url(url, blob);
- }
- else
- {
- ugh = fetch_curl(url, blob);
- }
- if (ugh != NULL)
- return ugh;
-
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" fetched blob coded in DER format")
- )
- }
- else
- {
- bool pgp = FALSE;
-
- ugh = pemtobin(blob, NULL, "", &pgp);
- if (ugh == NULL)
- {
- if (is_asn1(*blob))
- {
- DBG(DBG_PARSING,
- DBG_log(" fetched blob coded in PEM format")
- )
- }
- else
- {
- ugh = "blob coded in unknown format";
- pfree(blob->ptr);
- }
- }
- else
- {
- pfree(blob->ptr);
}
- }
- return ugh;
+ return TRUE;
}
-/*
- * complete a distributionPoint URI with ca information
+/**
+ * Complete a distributionPoint URI with ca information
*/
-static char*
-complete_uri(chunk_t distPoint, const char *ldaphost)
+static char* complete_uri(chunk_t distPoint, const char *ldaphost)
{
- char *uri;
- char *ptr = distPoint.ptr;
- size_t len = distPoint.len;
+ char *uri;
+ char *ptr = distPoint.ptr;
+ size_t len = distPoint.len;
- char *symbol = memchr(ptr, ':', len);
+ char *symbol = memchr(ptr, ':', len);
- if (symbol != NULL)
- {
- size_t type_len = symbol - ptr;
-
- if (type_len >= 4 && strncasecmp(ptr, "ldap", 4) == 0)
+ if (symbol != NULL)
{
- ptr = symbol + 1;
- len -= (type_len + 1);
-
- if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
- {
- len -= 2;
- symbol = memchr(ptr, '/', len);
+ size_t type_len = symbol - ptr;
- if (symbol != NULL && symbol - ptr == 0 && ldaphost != NULL)
+ if (type_len >= 4 && strncasecmp(ptr, "ldap", 4) == 0)
{
- uri = alloc_bytes(distPoint.len+strlen(ldaphost)+1, "uri");
-
- /* insert the ldaphost into the uri */
- sprintf(uri, "%.*s%s%.*s"
- , (int)(distPoint.len - len), distPoint.ptr
- , ldaphost
- , (int)len, symbol);
- return uri;
+ ptr = symbol + 1;
+ len -= (type_len + 1);
+
+ if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
+ {
+ len -= 2;
+ symbol = memchr(ptr, '/', len);
+
+ if (symbol != NULL && symbol - ptr == 0 && ldaphost != NULL)
+ {
+ uri = malloc(distPoint.len + strlen(ldaphost) + 1);
+
+ /* insert the ldaphost into the uri */
+ sprintf(uri, "%.*s%s%.*s"
+ , (int)(distPoint.len - len), distPoint.ptr
+ , ldaphost
+ , (int)len, symbol);
+ return uri;
+ }
+ }
}
- }
}
- }
-
- /* default action: copy distributionPoint without change */
- uri = alloc_bytes(distPoint.len+1, "uri");
- sprintf(uri, "%.*s", (int)distPoint.len, distPoint.ptr);
- return uri;
+
+ /* default action: copy distributionPoint without change */
+ uri = malloc(distPoint.len + 1);
+ sprintf(uri, "%.*s", (int)distPoint.len, distPoint.ptr);
+ return uri;
}
-/*
- * try to fetch the crls defined by the fetch requests
+/**
+ * Try to fetch the crls defined by the fetch requests
*/
-static void
-fetch_crls(bool cache_crls)
+static void fetch_crls(bool cache_crls)
{
- fetch_req_t *req;
- fetch_req_t **reqp;
-
- lock_crl_fetch_list("fetch_crls");
- req = crl_fetch_reqs;
- reqp = &crl_fetch_reqs;
-
- while (req != NULL)
- {
- bool valid_crl = FALSE;
- chunk_t blob = empty_chunk;
- generalName_t *gn = req->distributionPoints;
- const char *ldaphost;
- ca_info_t *ca;
+ fetch_req_t *req;
+ fetch_req_t **reqp;
- lock_ca_info_list("fetch_crls");
+ lock_crl_fetch_list("fetch_crls");
+ req = crl_fetch_reqs;
+ reqp = &crl_fetch_reqs;
- ca = get_ca_info(req->issuer, req->authKeySerialNumber, req->authKeyID);
- ldaphost = (ca == NULL)? NULL : ca->ldaphost;
-
- while (gn != NULL)
+ while (req != NULL)
{
- char *uri = complete_uri(gn->name, ldaphost);
+ bool valid_crl = FALSE;
+ chunk_t blob = chunk_empty;
+ generalName_t *gn = req->distributionPoints;
+ const char *ldaphost;
+ ca_info_t *ca;
- err_t ugh = fetch_asn1_blob(uri, &blob);
- pfree(uri);
+ lock_ca_info_list("fetch_crls");
- if (ugh != NULL)
- {
- plog("fetch failed: %s", ugh);
- }
- else
- {
- chunk_t crl_uri;
+ ca = get_ca_info(req->issuer, req->authKeySerialNumber, req->authKeyID);
+ ldaphost = (ca == NULL)? NULL : ca->ldaphost;
- clonetochunk(crl_uri, gn->name.ptr, gn->name.len, "crl uri");
- if (insert_crl(blob, crl_uri, cache_crls))
+ while (gn != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("we have a valid crl")
- )
- valid_crl = TRUE;
- break;
+ char *uri = complete_uri(gn->name, ldaphost);
+
+ if (fetch_asn1_blob(uri, &blob))
+ {
+ chunk_t crl_uri = chunk_clone(gn->name);
+
+ if (insert_crl(blob, crl_uri, cache_crls))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("we have a valid crl")
+ )
+ valid_crl = TRUE;
+ free(uri);
+ break;
+ }
+ }
+ free(uri);
+ gn = gn->next;
}
- }
- gn = gn->next;
- }
- unlock_ca_info_list("fetch_crls");
+ unlock_ca_info_list("fetch_crls");
- if (valid_crl)
- {
- /* delete fetch request */
- fetch_req_t *req_free = req;
+ if (valid_crl)
+ {
+ /* delete fetch request */
+ fetch_req_t *req_free = req;
- req = req->next;
- *reqp = req;
- free_fetch_request(req_free);
- }
- else
- {
- /* try again next time */
- req->trials++;
- reqp = &req->next;
- req = req->next;
+ req = req->next;
+ *reqp = req;
+ free_fetch_request(req_free);
+ }
+ else
+ {
+ /* try again next time */
+ req->trials++;
+ reqp = &req->next;
+ req = req->next;
+ }
}
- }
- unlock_crl_fetch_list("fetch_crls");
+ unlock_crl_fetch_list("fetch_crls");
}
-static void
-fetch_ocsp_status(ocsp_location_t* location)
+static void fetch_ocsp_status(ocsp_location_t* location)
{
-#ifdef LIBCURL
- chunk_t request;
- chunk_t response = empty_chunk;
-
- CURL* curl;
- CURLcode res;
-
- request = build_ocsp_request(location);
+ chunk_t request, response;
+ char *uri;
- DBG(DBG_CONTROL,
- DBG_log("sending ocsp request to location '%.*s'"
- , (int)location->uri.len, location->uri.ptr)
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("OCSP request", request)
- )
-
- /* send via http post using libcurl */
- curl = curl_easy_init();
-
- if (curl != NULL)
- {
- char errorbuffer[CURL_ERROR_SIZE];
- struct curl_slist *headers = NULL;
- char* uri = alloc_bytes(location->uri.len+1, "ocsp uri");
+ request = build_ocsp_request(location);
+ response = chunk_empty;
/* we need a null terminated string for curl */
+ uri = malloc(location->uri.len + 1);
memcpy(uri, location->uri.ptr, location->uri.len);
*(uri + location->uri.len) = '\0';
- /* set content type header */
- headers = curl_slist_append(headers, "Content-Type: application/ocsp-request");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-
- curl_easy_setopt(curl, CURLOPT_URL, uri);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (void*)request.ptr);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, request.len);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
+ DBG1(" requesting ocsp status from '%s' ...", uri);
+ if (lib->fetcher->fetch(lib->fetcher, uri, &response,
+ FETCH_REQUEST_DATA, request,
+ FETCH_REQUEST_TYPE, "application/ocsp-request",
+ FETCH_END) == SUCCESS)
{
- DBG(DBG_CONTROL,
- DBG_log("received ocsp response")
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("OCSP response:\n", response)
- )
- parse_ocsp(location, response);
+ parse_ocsp(location, response);
}
else
{
- plog("failed to fetch ocsp status from '%s': %s", uri, errorbuffer);
+ DBG1("ocsp request to %s failed", uri);
}
- curl_slist_free_all(headers);
- curl_easy_cleanup(curl);
- pfree(uri);
- /* not using freeanychunk because of realloc (no leak detective) */
- curl_free(response.ptr);
- }
- freeanychunk(location->nonce);
- freeanychunk(request);
-
- /* increment the trial counter of the unresolved fetch requests */
- {
- ocsp_certinfo_t *certinfo = location->certinfo;
-
- while (certinfo != NULL)
+
+ free(uri);
+ free(request.ptr);
+ chunk_free(&location->nonce);
+
+ /* increment the trial counter of the unresolved fetch requests */
{
- certinfo->trials++;
- certinfo = certinfo->next;
+ ocsp_certinfo_t *certinfo = location->certinfo;
+
+ while (certinfo != NULL)
+ {
+ certinfo->trials++;
+ certinfo = certinfo->next;
+ }
}
- }
- return;
-#else /* !LIBCURL */
- plog("ocsp error: pluto wasn't compiled with libcurl support");
-#endif /* !LIBCURL */
}
-/*
- * try to fetch the necessary ocsp information
+/**
+ * Try to fetch the necessary ocsp information
*/
-static void
-fetch_ocsp(void)
+static void fetch_ocsp(void)
{
- ocsp_location_t *location;
+ ocsp_location_t *location;
- lock_ocsp_fetch_list("fetch_ocsp");
- location = ocsp_fetch_reqs;
+ lock_ocsp_fetch_list("fetch_ocsp");
+ location = ocsp_fetch_reqs;
- /* fetch the ocps status for all locations */
- while (location != NULL)
- {
- if (location->certinfo != NULL)
- fetch_ocsp_status(location);
- location = location->next;
- }
+ /* fetch the ocps status for all locations */
+ while (location != NULL)
+ {
+ if (location->certinfo != NULL)
+ {
+ fetch_ocsp_status(location);
+ }
+ location = location->next;
+ }
- unlock_ocsp_fetch_list("fetch_ocsp");
+ unlock_ocsp_fetch_list("fetch_ocsp");
}
-static void*
-fetch_thread(void *arg)
+static void* fetch_thread(void *arg)
{
- struct timespec wait_interval;
+ struct timespec wait_interval;
- DBG(DBG_CONTROL,
- DBG_log("fetch thread started")
- )
+ DBG(DBG_CONTROL,
+ DBG_log("fetch thread started")
+ )
- pthread_mutex_lock(&fetch_wake_mutex);
+ pthread_mutex_lock(&fetch_wake_mutex);
- while(1)
- {
- int status;
+ while(1)
+ {
+ int status;
- wait_interval.tv_nsec = 0;
- wait_interval.tv_sec = time(NULL) + crl_check_interval;
+ wait_interval.tv_nsec = 0;
+ wait_interval.tv_sec = time(NULL) + crl_check_interval;
- DBG(DBG_CONTROL,
- DBG_log("next regular crl check in %ld seconds", crl_check_interval)
- )
- status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex
- , &wait_interval);
+ DBG(DBG_CONTROL,
+ DBG_log("next regular crl check in %ld seconds", crl_check_interval)
+ )
+ status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex
+ , &wait_interval);
- if (status == ETIMEDOUT)
- {
- DBG(DBG_CONTROL,
- DBG_log(" ");
- DBG_log("*time to check crls and the ocsp cache")
- )
- check_ocsp();
- check_crls();
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("fetch thread was woken up")
- )
+ if (status == ETIMEDOUT)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log(" ");
+ DBG_log("*time to check crls and the ocsp cache")
+ )
+ check_ocsp();
+ check_crls();
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("fetch thread was woken up")
+ )
+ }
+ fetch_ocsp();
+ fetch_crls(cache_crls);
}
- fetch_ocsp();
- fetch_crls(cache_crls);
- }
}
#endif /* THREADS*/
-/*
- * initializes curl and starts the fetching thread
+/**
+ * Initializes curl and starts the fetching thread
*/
-void
-init_fetch(void)
+void init_fetch(void)
{
-#if defined(LIBCURL) || defined (THREADS)
- int status;
-#endif
-
-#ifdef LIBCURL
- /* init curl */
- status = curl_global_init(CURL_GLOBAL_NOTHING);
- if (status != CURLE_OK)
- {
- plog("libcurl could not be initialized, status = %d", status);
- }
-#endif /* LIBCURL */
-
- if (crl_check_interval > 0)
- {
-#ifdef THREADS
- status = pthread_create( &thread, NULL, fetch_thread, NULL);
- if (status != 0)
+ if (crl_check_interval > 0)
{
- plog("fetching thread could not be started, status = %d", status);
- }
+#ifdef THREADS
+ int status = pthread_create( &thread, NULL, fetch_thread, NULL);
+
+ if (status != 0)
+ {
+ plog("fetching thread could not be started, status = %d", status);
+ }
#else /* !THREADS */
- plog("warning: not compiled with pthread support");
+ plog("warning: not compiled with pthread support");
#endif /* !THREADS */
- }
+ }
}
-void
-free_crl_fetch(void)
+void free_crl_fetch(void)
{
lock_crl_fetch_list("free_crl_fetch");
- while (crl_fetch_reqs != NULL)
- {
- fetch_req_t *req = crl_fetch_reqs;
- crl_fetch_reqs = req->next;
- free_fetch_request(req);
- }
-
- unlock_crl_fetch_list("free_crl_fetch");
-
-#ifdef LIBCURL
- if (crl_check_interval > 0)
- {
- /* cleanup curl */
- curl_global_cleanup();
- }
-#endif /* LIBCURL */
+ while (crl_fetch_reqs != NULL)
+ {
+ fetch_req_t *req = crl_fetch_reqs;
+ crl_fetch_reqs = req->next;
+ free_fetch_request(req);
+ }
+
+ unlock_crl_fetch_list("free_crl_fetch");
}
-/*
- * free the chained list of ocsp requests
+/**
+ * Free the chained list of ocsp requests
*/
-void
-free_ocsp_fetch(void)
+void free_ocsp_fetch(void)
{
- lock_ocsp_fetch_list("free_ocsp_fetch");
- free_ocsp_locations(&ocsp_fetch_reqs);
- unlock_ocsp_fetch_list("free_ocsp_fetch");
+ lock_ocsp_fetch_list("free_ocsp_fetch");
+ free_ocsp_locations(&ocsp_fetch_reqs);
+ unlock_ocsp_fetch_list("free_ocsp_fetch");
}
-/*
- * add additional distribution points
+/**
+ * Add additional distribution points
*/
-void
-add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
+void add_distribution_points(const generalName_t *newPoints ,generalName_t **distributionPoints)
{
- while (newPoints != NULL)
- {
- /* skip empty distribution point */
- if (newPoints->name.len > 0)
- {
- bool add = TRUE;
- generalName_t *gn = *distributionPoints;
-
- while (gn != NULL)
- {
- if (gn->kind == newPoints->kind
- && gn->name.len == newPoints->name.len
- && memcmp(gn->name.ptr, newPoints->name.ptr, gn->name.len) == 0)
- {
- /* skip if the distribution point is already present */
- add = FALSE;
- break;
- }
- gn = gn->next;
- }
-
- if (add)
- {
- /* clone additional distribution point */
- gn = clone_thing(*newPoints, "generalName");
- clonetochunk(gn->name, newPoints->name.ptr, newPoints->name.len
- , "crl uri");
-
- /* insert additional CRL distribution point */
- gn->next = *distributionPoints;
- *distributionPoints = gn;
- }
+ while (newPoints != NULL)
+ {
+ /* skip empty distribution point */
+ if (newPoints->name.len > 0)
+ {
+ bool add = TRUE;
+ generalName_t *gn = *distributionPoints;
+
+ while (gn != NULL)
+ {
+ if (gn->kind == newPoints->kind
+ && gn->name.len == newPoints->name.len
+ && memeq(gn->name.ptr, newPoints->name.ptr, gn->name.len))
+ {
+ /* skip if the distribution point is already present */
+ add = FALSE;
+ break;
+ }
+ gn = gn->next;
+ }
+
+ if (add)
+ {
+ /* clone additional distribution point */
+ gn = clone_thing(*newPoints);
+ gn->name = chunk_clone(newPoints->name);
+
+ /* insert additional CRL distribution point */
+ gn->next = *distributionPoints;
+ *distributionPoints = gn;
+ }
+ }
+ newPoints = newPoints->next;
}
- newPoints = newPoints->next;
- }
}
-fetch_req_t*
-build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
-, chunk_t authKeyID, const generalName_t *gn)
+fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber,
+ chunk_t authKeyID, const generalName_t *gn)
{
- fetch_req_t *req = alloc_thing(fetch_req_t, "fetch request");
- *req = empty_fetch_req;
-
- /* note current time */
- req->installed = time(NULL);
-
- /* clone fields */
- clonetochunk(req->issuer, issuer.ptr, issuer.len, "issuer");
- if (authKeySerialNumber.ptr != NULL)
- {
- clonetochunk(req->authKeySerialNumber, authKeySerialNumber.ptr
- , authKeySerialNumber.len, "authKeySerialNumber");
- }
- if (authKeyID.ptr != NULL)
- {
- clonetochunk(req->authKeyID, authKeyID.ptr, authKeyID.len, "authKeyID");
- }
-
- /* copy distribution points */
- add_distribution_points(gn, &req->distributionPoints);
-
- return req;
+ fetch_req_t *req = malloc_thing(fetch_req_t);
+ *req = empty_fetch_req;
+
+ /* note current time */
+ req->installed = time(NULL);
+
+ /* clone fields */
+ req->issuer = chunk_clone(issuer);
+ req->authKeySerialNumber = chunk_clone(authKeySerialNumber);
+ req->authKeyID = chunk_clone(authKeyID);
+
+ /* copy distribution points */
+ add_distribution_points(gn, &req->distributionPoints);
+
+ return req;
}
-/*
- * add a crl fetch request to the chained list
+/**
+ * Add a crl fetch request to the chained list
*/
-void
-add_crl_fetch_request(fetch_req_t *req)
+void add_crl_fetch_request(fetch_req_t *req)
{
- fetch_req_t *r;
+ fetch_req_t *r;
- lock_crl_fetch_list("add_crl_fetch_request");
- r = crl_fetch_reqs;
+ lock_crl_fetch_list("add_crl_fetch_request");
+ r = crl_fetch_reqs;
- while (r != NULL)
- {
- if ((req->authKeyID.ptr != NULL)? same_keyid(req->authKeyID, r->authKeyID)
- : (same_dn(req->issuer, r->issuer)
- && same_serial(req->authKeySerialNumber, r->authKeySerialNumber)))
+ while (r != NULL)
{
- /* there is already a fetch request */
- DBG(DBG_CONTROL,
- DBG_log("crl fetch request already exists")
- )
+ if ((req->authKeyID.ptr != NULL)? same_keyid(req->authKeyID, r->authKeyID)
+ : (same_dn(req->issuer, r->issuer)
+ && same_serial(req->authKeySerialNumber, r->authKeySerialNumber)))
+ {
+ /* there is already a fetch request */
+ DBG(DBG_CONTROL,
+ DBG_log("crl fetch request already exists")
+ )
- /* there might be new distribution points */
- add_distribution_points(req->distributionPoints, &r->distributionPoints);
+ /* there might be new distribution points */
+ add_distribution_points(req->distributionPoints, &r->distributionPoints);
- unlock_crl_fetch_list("add_crl_fetch_request");
- free_fetch_request(req);
- return;
+ unlock_crl_fetch_list("add_crl_fetch_request");
+ free_fetch_request(req);
+ return;
+ }
+ r = r->next;
}
- r = r->next;
- }
- /* insert new fetch request at the head of the queue */
- req->next = crl_fetch_reqs;
- crl_fetch_reqs = req;
+ /* insert new fetch request at the head of the queue */
+ req->next = crl_fetch_reqs;
+ crl_fetch_reqs = req;
- DBG(DBG_CONTROL,
- DBG_log("crl fetch request added")
- )
- unlock_crl_fetch_list("add_crl_fetch_request");
+ DBG(DBG_CONTROL,
+ DBG_log("crl fetch request added")
+ )
+ unlock_crl_fetch_list("add_crl_fetch_request");
}
-/*
- * add an ocsp fetch request to the chained list
+/**
+ * Add an ocsp fetch request to the chained list
*/
-void
-add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
+void add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
{
- ocsp_certinfo_t certinfo;
+ ocsp_certinfo_t certinfo;
- certinfo.serialNumber = serialNumber;
+ certinfo.serialNumber = serialNumber;
- lock_ocsp_fetch_list("add_ocsp_fetch_request");
- add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE);
- unlock_ocsp_fetch_list("add_ocsp_fetch_request");
+ lock_ocsp_fetch_list("add_ocsp_fetch_request");
+ add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE);
+ unlock_ocsp_fetch_list("add_ocsp_fetch_request");
}
-/*
- * list all distribution points
+/**
+ * List all distribution points
*/
-void
-list_distribution_points(const generalName_t *gn)
+void list_distribution_points(const generalName_t *gn)
{
- bool first_gn = TRUE;
-
- while (gn != NULL)
- {
- whack_log(RC_COMMENT, " %s '%.*s'", (first_gn)? "distPts: "
- :" ", (int)gn->name.len, gn->name.ptr);
- first_gn = FALSE;
- gn = gn->next;
- }
+ bool first_gn = TRUE;
+
+ while (gn != NULL)
+ {
+ whack_log(RC_COMMENT, " %s '%.*s'", (first_gn)? "distPts: "
+ :" ", (int)gn->name.len, gn->name.ptr);
+ first_gn = FALSE;
+ gn = gn->next;
+ }
}
-/*
- * list all fetch requests in the chained list
+/**
+ * List all fetch requests in the chained list
*/
-void
-list_crl_fetch_requests(bool utc)
+void list_crl_fetch_requests(bool utc)
{
- fetch_req_t *req;
-
- lock_crl_fetch_list("list_crl_fetch_requests");
- req = crl_fetch_reqs;
-
- if (req != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of CRL fetch requests:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (req != NULL)
- {
- u_char buf[BUF_LEN];
-
- whack_log(RC_COMMENT, "%s, trials: %d"
- , timetoa(&req->installed, utc), req->trials);
- dntoa(buf, BUF_LEN, req->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- if (req->authKeyID.ptr != NULL)
+ fetch_req_t *req;
+
+ lock_crl_fetch_list("list_crl_fetch_requests");
+ req = crl_fetch_reqs;
+
+ if (req != NULL)
{
- datatot(req->authKeyID.ptr, req->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of CRL fetch requests:");
+ whack_log(RC_COMMENT, " ");
}
- if (req->authKeySerialNumber.ptr != NULL)
+
+ while (req != NULL)
{
- datatot(req->authKeySerialNumber.ptr, req->authKeySerialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
+ u_char buf[BUF_LEN];
+
+ whack_log(RC_COMMENT, "%T, trials: %d"
+ , &req->installed, utc, req->trials);
+ dntoa(buf, BUF_LEN, req->issuer);
+ whack_log(RC_COMMENT, " issuer: '%s'", buf);
+ if (req->authKeyID.ptr != NULL)
+ {
+ datatot(req->authKeyID.ptr, req->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (req->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(req->authKeySerialNumber.ptr, req->authKeySerialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
+ list_distribution_points(req->distributionPoints);
+ req = req->next;
}
- list_distribution_points(req->distributionPoints);
- req = req->next;
- }
- unlock_crl_fetch_list("list_crl_fetch_requests");
+ unlock_crl_fetch_list("list_crl_fetch_requests");
}
-void
-list_ocsp_fetch_requests(bool utc)
+void list_ocsp_fetch_requests(bool utc)
{
- lock_ocsp_fetch_list("list_ocsp_fetch_requests");
- list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
- unlock_ocsp_fetch_list("list_ocsp_fetch_requests");
+ lock_ocsp_fetch_list("list_ocsp_fetch_requests");
+ list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
+ unlock_ocsp_fetch_list("list_ocsp_fetch_requests");
}
diff --git a/src/pluto/fetch.h b/src/pluto/fetch.h
index 67be12d47..f7b4eb074 100644
--- a/src/pluto/fetch.h
+++ b/src/pluto/fetch.h
@@ -11,31 +11,29 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: fetch.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include "x509.h"
-#define FETCH_CMD_TIMEOUT 10 /* seconds */
+#define FETCH_CMD_TIMEOUT 10 /* seconds */
-struct ocsp_location; /* forward declaration of ocsp_location defined in ocsp.h */
+struct ocsp_location; /* forward declaration of ocsp_location defined in ocsp.h */
typedef enum {
- FETCH_GET = 1,
- FETCH_POST = 2
+ FETCH_GET = 1,
+ FETCH_POST = 2
} fetch_request_t;
typedef struct fetch_req fetch_req_t;
struct fetch_req {
- fetch_req_t *next;
- time_t installed;
- int trials;
- chunk_t issuer;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- generalName_t *distributionPoints;
+ fetch_req_t *next;
+ time_t installed;
+ int trials;
+ chunk_t issuer;
+ chunk_t authKeyID;
+ chunk_t authKeySerialNumber;
+ generalName_t *distributionPoints;
};
#ifdef THREADS
@@ -67,9 +65,9 @@ extern void init_fetch(void);
extern void free_crl_fetch(void);
extern void free_ocsp_fetch(void);
extern void add_distribution_points(const generalName_t *newPoints
- , generalName_t **distributionPoints);
+ , generalName_t **distributionPoints);
extern fetch_req_t* build_crl_fetch_request(chunk_t issuer, chunk_t authKeySerialNumber
- , chunk_t authKeyID, const generalName_t *gn);
+ , chunk_t authKeyID, const generalName_t *gn);
extern void add_crl_fetch_request(fetch_req_t *req);
extern void add_ocsp_fetch_request(struct ocsp_location *location, chunk_t serialNumber);
extern void list_distribution_points(const generalName_t *gn);
diff --git a/src/pluto/foodgroups.c b/src/pluto/foodgroups.c
index 5b2836bce..ed9853fc4 100644
--- a/src/pluto/foodgroups.c
+++ b/src/pluto/foodgroups.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: foodgroups.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <string.h>
@@ -49,8 +47,8 @@ static size_t fg_path_space = 0;
*/
struct fg_groups {
- struct fg_groups *next;
- struct connection *connection;
+ struct fg_groups *next;
+ struct connection *connection;
};
static struct fg_groups *groups = NULL;
@@ -66,10 +64,10 @@ static struct fg_groups *groups = NULL;
*/
struct fg_targets {
- struct fg_targets *next;
- struct fg_groups *group;
- ip_subnet subnet;
- char *name; /* name of instance of group conn */
+ struct fg_targets *next;
+ struct fg_groups *group;
+ ip_subnet subnet;
+ char *name; /* name of instance of group conn */
};
static struct fg_targets *targets = NULL;
@@ -83,24 +81,24 @@ struct fg_targets *new_targets;
static int
ipcmp(ip_address *a, ip_address *b)
{
- if (addrtypeof(a) != addrtypeof(b))
- {
- return addrtypeof(a) < addrtypeof(b)? -1 : 1;
- }
- else if (sameaddr(a, b))
- {
- return 0;
- }
- else
- {
- const struct sockaddr *sa = sockaddrof(a)
- , *sb = sockaddrof(b);
-
- passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
- return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
- < ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
- ? -1 : 1;
- }
+ if (addrtypeof(a) != addrtypeof(b))
+ {
+ return addrtypeof(a) < addrtypeof(b)? -1 : 1;
+ }
+ else if (sameaddr(a, b))
+ {
+ return 0;
+ }
+ else
+ {
+ const struct sockaddr *sa = sockaddrof(a)
+ , *sb = sockaddrof(b);
+
+ passert(addrtypeof(a) == AF_INET); /* not yet implemented IPv6 version :-( */
+ return (ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr)
+ < ntohl(((const struct sockaddr_in *)sb)->sin_addr.s_addr))
+ ? -1 : 1;
+ }
}
/* subnetcmp compares the two ip_subnet values a and b.
@@ -110,353 +108,353 @@ ipcmp(ip_address *a, ip_address *b)
static int
subnetcmp(const ip_subnet *a, const ip_subnet *b)
{
- ip_address neta, maska, netb, maskb;
- int r;
-
- networkof(a, &neta);
- maskof(a, &maska);
- networkof(b, &netb);
- maskof(b, &maskb);
- r = ipcmp(&neta, &netb);
- if (r == 0)
- r = ipcmp(&maska, &maskb);
- return r;
+ ip_address neta, maska, netb, maskb;
+ int r;
+
+ networkof(a, &neta);
+ maskof(a, &maska);
+ networkof(b, &netb);
+ maskof(b, &maskb);
+ r = ipcmp(&neta, &netb);
+ if (r == 0)
+ r = ipcmp(&maska, &maskb);
+ return r;
}
static void
read_foodgroup(struct fg_groups *g)
{
- const char *fgn = g->connection->name;
- const ip_subnet *lsn = &g->connection->spd.this.client;
- size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
- struct file_lex_position flp_space;
-
- if (plen > fg_path_space)
- {
- pfreeany(fg_path);
- fg_path_space = plen + 10;
- fg_path = alloc_bytes(fg_path_space, "policy group path");
- }
- snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
- if (!lexopen(&flp_space, fg_path, TRUE))
- {
- DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
- }
- else
- {
- plog("loading group \"%s\"", fg_path);
- for (;;)
+ const char *fgn = g->connection->name;
+ const ip_subnet *lsn = &g->connection->spd.this.client;
+ size_t plen = strlen(policygroups_dir) + 1 + strlen(fgn) + 1;
+ struct file_lex_position flp_space;
+
+ if (plen > fg_path_space)
+ {
+ free(fg_path);
+ fg_path_space = plen + 10;
+ fg_path = malloc(fg_path_space);
+ }
+ snprintf(fg_path, fg_path_space, "%s/%s", policygroups_dir, fgn);
+ if (!lexopen(&flp_space, fg_path, TRUE))
+ {
+ DBG(DBG_CONTROL, DBG_log("no group file \"%s\"", fg_path));
+ }
+ else
{
- switch (flp->bdry)
- {
- case B_none:
+ plog("loading group \"%s\"", fg_path);
+ for (;;)
{
- /* !!! this test is not sufficient for distinguishing address families.
- * We need a notation to specify that a FQDN is to be resolved to IPv6.
- */
- const struct af_info *afi = strchr(tok, ':') == NULL
- ? &af_inet4_info: &af_inet6_info;
- ip_subnet sn;
- err_t ugh;
-
- if (strchr(tok, '/') == NULL)
- {
- /* no /, so treat as /32 or V6 equivalent */
- ip_address t;
-
- ugh = ttoaddr(tok, 0, afi->af, &t);
- if (ugh == NULL)
- ugh = addrtosubnet(&t, &sn);
- }
- else
- {
- ugh = ttosubnet(tok, 0, afi->af, &sn);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
- , flp->filename, flp->lino, ugh, tok);
- }
- else if (afi->af != AF_INET)
- {
- loglog(RC_LOG_SERIOUS
- , "\"%s\" line %d: unsupported Address Family \"%s\""
- , flp->filename, flp->lino, tok);
- }
- else
- {
- /* Find where new entry ought to go in new_targets. */
- struct fg_targets **pp;
- int r;
-
- for (pp = &new_targets; ; pp = &(*pp)->next)
- {
- if (*pp == NULL)
- {
- r = -1; /* end of list is infinite */
- break;
- }
- r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
- if (r == 0)
- r = subnetcmp(&sn, &(*pp)->subnet);
- if (r <= 0)
- break;
- }
-
- if (r == 0)
+ switch (flp->bdry)
{
- char source[SUBNETTOT_BUF];
-
- subnettot(lsn, 0, source, sizeof(source));
- loglog(RC_LOG_SERIOUS
- , "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
- , flp->filename
- , flp->lino
- , tok
- , source
- , (*pp)->group->connection->name);
+ case B_none:
+ {
+ /* !!! this test is not sufficient for distinguishing address families.
+ * We need a notation to specify that a FQDN is to be resolved to IPv6.
+ */
+ const struct af_info *afi = strchr(tok, ':') == NULL
+ ? &af_inet4_info: &af_inet6_info;
+ ip_subnet sn;
+ err_t ugh;
+
+ if (strchr(tok, '/') == NULL)
+ {
+ /* no /, so treat as /32 or V6 equivalent */
+ ip_address t;
+
+ ugh = ttoaddr(tok, 0, afi->af, &t);
+ if (ugh == NULL)
+ ugh = addrtosubnet(&t, &sn);
+ }
+ else
+ {
+ ugh = ttosubnet(tok, 0, afi->af, &sn);
+ }
+
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s \"%s\""
+ , flp->filename, flp->lino, ugh, tok);
+ }
+ else if (afi->af != AF_INET)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "\"%s\" line %d: unsupported Address Family \"%s\""
+ , flp->filename, flp->lino, tok);
+ }
+ else
+ {
+ /* Find where new entry ought to go in new_targets. */
+ struct fg_targets **pp;
+ int r;
+
+ for (pp = &new_targets; ; pp = &(*pp)->next)
+ {
+ if (*pp == NULL)
+ {
+ r = -1; /* end of list is infinite */
+ break;
+ }
+ r = subnetcmp(lsn, &(*pp)->group->connection->spd.this.client);
+ if (r == 0)
+ r = subnetcmp(&sn, &(*pp)->subnet);
+ if (r <= 0)
+ break;
+ }
+
+ if (r == 0)
+ {
+ char source[SUBNETTOT_BUF];
+
+ subnettot(lsn, 0, source, sizeof(source));
+ loglog(RC_LOG_SERIOUS
+ , "\"%s\" line %d: subnet \"%s\", source %s, already \"%s\""
+ , flp->filename
+ , flp->lino
+ , tok
+ , source
+ , (*pp)->group->connection->name);
+ }
+ else
+ {
+ struct fg_targets *f = malloc_thing(struct fg_targets);
+
+ f->next = *pp;
+ f->group = g;
+ f->subnet = sn;
+ f->name = NULL;
+ *pp = f;
+ }
+ }
+ }
+ (void)shift(); /* next */
+ continue;
+
+ case B_record:
+ flp->bdry = B_none; /* eat the Record Boundary */
+ (void)shift(); /* get real first token */
+ continue;
+
+ case B_file:
+ break; /* done */
}
- else
- {
- struct fg_targets *f = alloc_thing(struct fg_targets, "fg_target");
-
- f->next = *pp;
- f->group = g;
- f->subnet = sn;
- f->name = NULL;
- *pp = f;
- }
- }
+ break; /* if we reach here, out of loop */
}
- (void)shift(); /* next */
- continue;
-
- case B_record:
- flp->bdry = B_none; /* eat the Record Boundary */
- (void)shift(); /* get real first token */
- continue;
-
- case B_file:
- break; /* done */
- }
- break; /* if we reach here, out of loop */
+ lexclose();
}
- lexclose();
- }
}
static void
free_targets(void)
{
- while (targets != NULL)
- {
- struct fg_targets *t = targets;
-
- targets = t->next;
- pfreeany(t->name);
- pfree(t);
- }
+ while (targets != NULL)
+ {
+ struct fg_targets *t = targets;
+
+ targets = t->next;
+ free(t->name);
+ free(t);
+ }
}
void
load_groups(void)
{
- passert(new_targets == NULL);
+ passert(new_targets == NULL);
- /* for each group, add config file targets into new_targets */
- {
- struct fg_groups *g;
+ /* for each group, add config file targets into new_targets */
+ {
+ struct fg_groups *g;
- for (g = groups; g != NULL; g = g->next)
- if (oriented(*g->connection))
- read_foodgroup(g);
- }
+ for (g = groups; g != NULL; g = g->next)
+ if (oriented(*g->connection))
+ read_foodgroup(g);
+ }
- /* dump new_targets */
- DBG(DBG_CONTROL,
- {
- struct fg_targets *t;
-
- for (t = new_targets; t != NULL; t = t->next)
- {
- char asource[SUBNETTOT_BUF];
- char atarget[SUBNETTOT_BUF];
-
- subnettot(&t->group->connection->spd.this.client
- , 0, asource, sizeof(asource));
- subnettot(&t->subnet, 0, atarget, sizeof(atarget));
- DBG_log("%s->%s %s"
- , asource, atarget
- , t->group->connection->name);
- }
- });
-
- /* determine and deal with differences between targets and new_targets.
- * structured like a merge.
- */
- {
- struct fg_targets *op = targets
- , *np = new_targets;
-
- while (op != NULL && np != NULL)
- {
- int r = subnetcmp(&op->group->connection->spd.this.client
- , &np->group->connection->spd.this.client);
-
- if (r == 0)
- r = subnetcmp(&op->subnet, &np->subnet);
-
- if (r == 0 && op->group == np->group)
- {
- /* unchanged -- steal name & skip over */
- np->name = op->name;
- op->name = NULL;
- op = op->next;
- np = np->next;
- }
- else
- {
- /* note: following cases overlap! */
- if (r <= 0)
+ /* dump new_targets */
+ DBG(DBG_CONTROL,
{
- remove_group_instance(op->group->connection, op->name);
- op = op->next;
- }
- if (r >= 0)
+ struct fg_targets *t;
+
+ for (t = new_targets; t != NULL; t = t->next)
+ {
+ char asource[SUBNETTOT_BUF];
+ char atarget[SUBNETTOT_BUF];
+
+ subnettot(&t->group->connection->spd.this.client
+ , 0, asource, sizeof(asource));
+ subnettot(&t->subnet, 0, atarget, sizeof(atarget));
+ DBG_log("%s->%s %s"
+ , asource, atarget
+ , t->group->connection->name);
+ }
+ });
+
+ /* determine and deal with differences between targets and new_targets.
+ * structured like a merge.
+ */
+ {
+ struct fg_targets *op = targets
+ , *np = new_targets;
+
+ while (op != NULL && np != NULL)
{
- np->name = add_group_instance(np->group->connection, &np->subnet);
- np = np->next;
+ int r = subnetcmp(&op->group->connection->spd.this.client
+ , &np->group->connection->spd.this.client);
+
+ if (r == 0)
+ r = subnetcmp(&op->subnet, &np->subnet);
+
+ if (r == 0 && op->group == np->group)
+ {
+ /* unchanged -- steal name & skip over */
+ np->name = op->name;
+ op->name = NULL;
+ op = op->next;
+ np = np->next;
+ }
+ else
+ {
+ /* note: following cases overlap! */
+ if (r <= 0)
+ {
+ remove_group_instance(op->group->connection, op->name);
+ op = op->next;
+ }
+ if (r >= 0)
+ {
+ np->name = add_group_instance(np->group->connection, &np->subnet);
+ np = np->next;
+ }
+ }
}
- }
+ for (; op != NULL; op = op->next)
+ remove_group_instance(op->group->connection, op->name);
+ for (; np != NULL; np = np->next)
+ np->name = add_group_instance(np->group->connection, &np->subnet);
+
+ /* update: new_targets replaces targets */
+ free_targets();
+ targets = new_targets;
+ new_targets = NULL;
}
- for (; op != NULL; op = op->next)
- remove_group_instance(op->group->connection, op->name);
- for (; np != NULL; np = np->next)
- np->name = add_group_instance(np->group->connection, &np->subnet);
-
- /* update: new_targets replaces targets */
- free_targets();
- targets = new_targets;
- new_targets = NULL;
- }
}
void
add_group(struct connection *c)
{
- struct fg_groups *g = alloc_thing(struct fg_groups, "policy group");
+ struct fg_groups *g = malloc_thing(struct fg_groups);
- g->next = groups;
- groups = g;
+ g->next = groups;
+ groups = g;
- g->connection = c;
+ g->connection = c;
}
static struct fg_groups *
find_group(const struct connection *c)
{
- struct fg_groups *g;
+ struct fg_groups *g;
- for (g = groups; g != NULL && g->connection != c; g = g->next)
- ;
- return g;
+ for (g = groups; g != NULL && g->connection != c; g = g->next)
+ ;
+ return g;
}
void
route_group(struct connection *c)
{
- /* it makes no sense to route a connection that is ISAKMP-only */
- if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
- {
- loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
- }
- else
- {
- struct fg_groups *g = find_group(c);
- struct fg_targets *t;
-
- passert(g != NULL);
- g->connection->policy |= POLICY_GROUTED;
- for (t = targets; t != NULL; t = t->next)
+ /* it makes no sense to route a connection that is ISAKMP-only */
+ if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
+ {
+ loglog(RC_ROUTE, "cannot route an ISAKMP-only group connection");
+ }
+ else
{
- if (t->group == g)
- {
- struct connection *ci = con_by_name(t->name, FALSE);
+ struct fg_groups *g = find_group(c);
+ struct fg_targets *t;
- if (ci != NULL)
+ passert(g != NULL);
+ g->connection->policy |= POLICY_GROUTED;
+ for (t = targets; t != NULL; t = t->next)
{
- set_cur_connection(ci);
- if (!trap_connection(ci))
- whack_log(RC_ROUTE, "could not route");
- set_cur_connection(c);
+ if (t->group == g)
+ {
+ struct connection *ci = con_by_name(t->name, FALSE);
+
+ if (ci != NULL)
+ {
+ set_cur_connection(ci);
+ if (!trap_connection(ci))
+ whack_log(RC_ROUTE, "could not route");
+ set_cur_connection(c);
+ }
+ }
}
- }
}
- }
}
void
unroute_group(struct connection *c)
{
- struct fg_groups *g = find_group(c);
- struct fg_targets *t;
-
- passert(g != NULL);
- g->connection->policy &= ~POLICY_GROUTED;
- for (t = targets; t != NULL; t = t->next)
- {
- if (t->group == g)
+ struct fg_groups *g = find_group(c);
+ struct fg_targets *t;
+
+ passert(g != NULL);
+ g->connection->policy &= ~POLICY_GROUTED;
+ for (t = targets; t != NULL; t = t->next)
{
- struct connection *ci = con_by_name(t->name, FALSE);
-
- if (ci != NULL)
- {
- set_cur_connection(ci);
- unroute_connection(ci);
- set_cur_connection(c);
- }
+ if (t->group == g)
+ {
+ struct connection *ci = con_by_name(t->name, FALSE);
+
+ if (ci != NULL)
+ {
+ set_cur_connection(ci);
+ unroute_connection(ci);
+ set_cur_connection(c);
+ }
+ }
}
- }
}
void
delete_group(const struct connection *c)
{
- struct fg_groups *g;
-
- /* find and remove from groups */
- {
- struct fg_groups **pp;
+ struct fg_groups *g;
- for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
- ;
+ /* find and remove from groups */
+ {
+ struct fg_groups **pp;
- *pp = g->next;
- }
+ for (pp = &groups; (g = *pp)->connection != c; pp = &(*pp)->next)
+ ;
- /* find and remove from targets */
- {
- struct fg_targets **pp;
+ *pp = g->next;
+ }
- for (pp = &targets; *pp != NULL; )
+ /* find and remove from targets */
{
- struct fg_targets *t = *pp;
-
- if (t->group == g)
- {
- *pp = t->next;
- remove_group_instance(t->group->connection, t->name);
- pfree(t);
- /* pp is ready for next iteration */
- }
- else
- {
- pp = &t->next;
- }
+ struct fg_targets **pp;
+
+ for (pp = &targets; *pp != NULL; )
+ {
+ struct fg_targets *t = *pp;
+
+ if (t->group == g)
+ {
+ *pp = t->next;
+ remove_group_instance(t->group->connection, t->name);
+ free(t);
+ /* pp is ready for next iteration */
+ }
+ else
+ {
+ pp = &t->next;
+ }
+ }
}
- }
- pfree(g);
+ free(g);
}
diff --git a/src/pluto/foodgroups.h b/src/pluto/foodgroups.h
index d66f85423..b6d3386ae 100644
--- a/src/pluto/foodgroups.h
+++ b/src/pluto/foodgroups.h
@@ -10,11 +10,9 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: foodgroups.h 3252 2007-10-06 21:24:50Z andreas $
*/
-struct connection; /* forward declaration */
+struct connection; /* forward declaration */
extern void add_group(struct connection *c);
extern void route_group(struct connection *c);
extern void unroute_group(struct connection *c);
diff --git a/src/pluto/gcryptfix.c b/src/pluto/gcryptfix.c
deleted file mode 100644
index b8007046d..000000000
--- a/src/pluto/gcryptfix.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Routines to make gcrypt routines feel at home in Pluto.
- * Copyright (C) 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: gcryptfix.c 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#include <stdlib.h>
-
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h" /* includes <gmp.h> "defs.h" "rnd.h" */
-
-MPI
-mpi_alloc( unsigned nlimbs UNUSED )
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_alloc");
-
- mpz_init(n);
- return n;
-}
-
-MPI
-mpi_alloc_secure( unsigned nlimbs )
-{
- return mpi_alloc(nlimbs);
-}
-
-MPI
-mpi_alloc_set_ui( unsigned long u)
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_copy");
-
- mpz_init_set_ui(n, u);
- return n;
-}
-
-MPI
-mpi_copy( MPI a )
-{
- MPI n = alloc_bytes(sizeof *n, "mpi_copy");
-
- mpz_init_set(n, a);
- return n;
-}
-
-void
-mpi_free( MPI a )
-{
- mpz_clear(a);
- pfree(a);
-}
-
-int
-mpi_divisible_ui(MPI dividend, ulong divisor )
-{
- ulong rem;
- mpz_t remtoo;
-
- mpz_init(remtoo);
- rem = mpz_mod_ui(remtoo, dividend, divisor);
- mpz_clear(remtoo);
- return rem == 0;
-}
-
-unsigned
-mpi_trailing_zeros( MPI a )
-{
- return mpz_scan1(a, 0);
-}
-
-unsigned
-mpi_get_nbits( MPI a )
-{
- return mpz_sizeinbase(a, 2);
-}
-
-int
-mpi_test_bit( MPI a, unsigned n )
-{
- /* inspired by gmp/mpz/clrbit.c */
- mp_size_t li = n / mp_bits_per_limb;
-
- if (li >= a->_mp_size)
- return 0;
- return (a->_mp_d[li] & ((mp_limb_t) 1 << (n % mp_bits_per_limb))) != 0;
-}
-
-void
-mpi_set_bit( MPI a, unsigned n )
-{
- mpz_setbit(a, n);
-}
-
-void
-mpi_clear_bit( MPI a, unsigned n )
-{
- mpz_clrbit(a, n);
-}
-
-void
-mpi_clear_highbit( MPI a, unsigned n )
-{
- /* This seems whacky, but what do I know. */
- mpz_fdiv_r_2exp(a, a, n);
-}
-
-void
-mpi_set_highbit( MPI a, unsigned n )
-{
- /* This seems whacky, but what do I know. */
- mpz_fdiv_r_2exp(a, a, n+1);
- mpz_setbit(a, n);
-}
-
-void
-mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign )
-{
- /* this is a lot like n_to_mpz */
- size_t i;
-
- passert(sign == 0); /* we won't hit any negative numbers */
- mpz_init_set_ui(a, 0);
-
- for (i = 0; i != nbytes; i++)
- {
- mpz_mul_ui(a, a, 1 << BITS_PER_BYTE);
- mpz_add_ui(a, a, buffer[i]);
- }
-}
-
-u_char *
-get_random_bits(size_t nbits, int level UNUSED, int secure UNUSED)
-{
- size_t nbytes = (nbits+7)/8;
- u_char *b = alloc_bytes(nbytes, "random bytes");
-
- get_rnd_bytes(b, nbytes);
- return b;
-}
-/**************** from gnupg-1.0.0/mpi/mpi-mpow.c
- * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
- */
-#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) mpi_mulm( (w), (u), (v), (m) )
-
-static int
-build_index( MPI *exparray, int k, int i, int t )
-{
- int j, bitno;
- int index = 0;
-
- bitno = t-i;
- for(j=k-1; j >= 0; j-- ) {
- index <<= 1;
- if( mpi_test_bit( exparray[j], bitno ) )
- index |= 1;
- }
- /*log_debug("t=%d i=%d index=%d\n", t, i, index );*/
- return index;
-}
-
-void
-mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
-{
- int k; /* number of elements */
- int t; /* bit size of largest exponent */
- int i, j, idx;
- MPI *G; /* table with precomputed values of size 2^k */
- MPI tmp;
- #ifdef USE_BARRETT
- MPI barrett_y, barrett_r1, barrett_r2;
- int barrett_k;
- #endif
-
- for(k=0; basearray[k]; k++ )
- ;
- passert(k);
- for(t=0, i=0; (tmp=exparray[i]); i++ ) {
- /*log_mpidump("exp: ", tmp );*/
- j = mpi_get_nbits(tmp);
- if( j > t )
- t = j;
- }
- /*log_mpidump("mod: ", m );*/
- passert(i==k);
- passert(t);
- passert( k < 10 );
-
-#ifdef PLUTO
- m_alloc_ptrs_clear(G, 1<<k);
-#else
- G = m_alloc_clear( (1<<k) * sizeof *G );
-#endif
-
- #ifdef USE_BARRETT
- barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
- #endif
- /* and calculate */
- tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
- mpi_set_ui( res, 1 );
- for(i = 1; i <= t; i++ ) {
- barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
- barrett_r1, barrett_r2 );
- idx = build_index( exparray, k, i, t );
- passert( idx >= 0 && idx < (1<<k) );
- if( !G[idx] ) {
- if( !idx )
- G[0] = mpi_alloc_set_ui( 1 );
- else {
- for(j=0; j < k; j++ ) {
- if( (idx & (1<<j) ) ) {
- if( !G[idx] )
- G[idx] = mpi_copy( basearray[j] );
- else
- barrett_mulm( G[idx], G[idx], basearray[j],
- m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
- }
- }
- if( !G[idx] )
- G[idx] = mpi_alloc(0);
- }
- }
- barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
- }
-
- /* cleanup */
- mpi_free(tmp);
- #ifdef USE_BARRETT
- mpi_free(barrett_y);
- mpi_free(barrett_r1);
- mpi_free(barrett_r2);
- #endif
- for(i=0; i < (1<<k); i++ )
- mpi_free(G[i]);
- m_free(G);
-}
-
-void
-log_mpidump( const char *text UNUSED, MPI a )
-{
- /* Print number in hex -- helpful to see if they match bytes.
- * Humans are not going to do arithmetic with the large numbers!
- * Much code adapted from mpz_to_n.
- */
- u_char buf[8048]; /* this ought to be big enough */
- size_t len = (mpz_sizeinbase(a, 16) + 1) / 2; /* bytes */
- MP_INT temp1, temp2;
- int i;
-
- passert(len <= sizeof(buf));
-
- mpz_init(&temp1);
- mpz_init(&temp2);
-
- mpz_set(&temp1, a);
-
- for (i = len-1; i >= 0; i--)
- {
- buf[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
- mpz_set(&temp1, &temp2);
- }
-
- passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
- mpz_clear(&temp1);
- mpz_clear(&temp2);
-
-#ifdef DEBUG
- DBG_dump(text, buf, len);
-#endif /* DEBUG */
-}
diff --git a/src/pluto/gcryptfix.h b/src/pluto/gcryptfix.h
deleted file mode 100644
index db2587c59..000000000
--- a/src/pluto/gcryptfix.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Definitions to make gcrypt routines feel at home in Pluto.
- * Copyright (C) 1999 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: gcryptfix.h 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#define DBG_CIPHER 1 /* some day we'll do this right */
-
-/* Simulate MPI routines with gmp routines.
- * gmp's MP_INT is a stuct; MPI's MPI is a pointer to an analogous struct.
- * gmp's mpz_t is an array of one of these structs to enable magic pointer
- * conversions to make the notation convenient (but confusing).
- */
-typedef u_char byte;
-typedef MP_INT *MPI;
-
-#define BITS_PER_MPI_LIMB mp_bits_per_limb
-
-extern MPI mpi_alloc( unsigned nlimbs );
-extern MPI mpi_alloc_secure( unsigned nlimbs );
-#define mpi_alloc_like(n) mpi_alloc(mpi_get_nlimbs(n))
-extern MPI mpi_alloc_set_ui( unsigned long u);
-#define mpi_set_ui(w, u) mpz_set_ui(w, u)
-#define mpi_set(w, u) mpz_set(w, u)
-extern void mpi_free( MPI a );
-extern MPI mpi_copy( MPI a );
-extern unsigned mpi_get_nbits( MPI a );
-#define mpi_get_nlimbs(a) ((a)->_mp_alloc) /* dirty, but useless */
-extern void mpi_set_buffer( MPI a, const u_char *buffer, unsigned nbytes, int sign );
-extern unsigned mpi_trailing_zeros( MPI a );
-extern int mpi_test_bit( MPI a, unsigned n );
-extern void mpi_set_bit( MPI a, unsigned n );
-extern void mpi_clear_bit( MPI a, unsigned n );
-extern void mpi_clear_highbit( MPI a, unsigned n );
-extern void mpi_set_highbit( MPI a, unsigned n );
-#define mpi_cmp_ui(u, v) mpz_cmp_ui((u), (v))
-#define mpi_cmp(u, v) mpz_cmp((u), (v))
-#define mpi_is_neg(n) (mpz_sgn(n) < 0)
-#define mpi_add(w, u, v) mpz_add((w), (u), (v))
-#define mpi_add_ui(w, u, v) mpz_add_ui((w), (u), (v))
-#define mpi_sub_ui(w, u, v) mpz_sub_ui((w), (u), (v))
-#define mpi_subm( w, u, v, m) { mpz_sub( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
-#define mpi_mul( w, u, v) mpz_mul( (w), (u), (v))
-#define mpi_mul_ui( w, u, v) mpz_mul_ui( (w), (u), (v))
-#define mpi_mulm( w, u, v, m) { mpz_mul( (w), (u), (v)) ; mpz_fdiv_r((w), (w), (m)); }
-#define mpi_fdiv_q(quot, dividend, divisor) mpz_fdiv_q((quot), (dividend), (divisor))
-#define mpi_fdiv_r( rem, dividend, divisor ) mpz_fdiv_r( (rem), (dividend), (divisor) )
-#define mpi_fdiv_r_ui( rem, dividend, divisor ) mpz_fdiv_r_ui( (rem), (dividend), (divisor) )
-#define mpi_tdiv_q_2exp( w, u, count ) mpz_tdiv_q_2exp( (w), (u), (count) )
-extern int mpi_divisible_ui(MPI dividend, ulong divisor );
-#define mpi_powm( res, base, exp, mod) mpz_powm( res, base, exp, mod)
-extern void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
-#define mpi_gcd( g, a, b ) ( mpz_gcd( (g), (a), (b) ), !mpi_cmp_ui( (g), 1))
-#define mpi_invm( x, a, n ) mpz_invert( (x), (a), (n) )
-
-#ifdef DEBUG
-# define log_debug(f...) DBG_log(f)
-#else
-# define log_debug(f...) do ; while (0) /* do nothing, carefully */
-#endif
-#define log_fatal(f...) exit_log(f) /* overreaction? */
-extern void log_mpidump( const char *text, MPI a );
-
-#define assert(p) passert(p)
-#define BUG() passert(FALSE)
-
-#define m_alloc_ptrs_clear(pp, n) { \
- int c = (n); \
- (pp) = alloc_bytes((n) * sizeof(*(pp)), "m_alloc_ptrs_clear"); \
- while (c > 0) (pp)[--c] = NULL; \
- }
-
-extern u_char *get_random_bits(size_t nbits, int level, int secure);
-#define m_alloc(sz) alloc_bytes((sz), "m_alloc") /* not initialized */
-#define m_free(n) pfree(n) /* always freeing something from get_random_bits */
-
-/* declarations from gnupg-1.0.0/include/cipher.h */
-/*-- primegen.c --*/
-MPI generate_secret_prime( unsigned nbits );
-MPI generate_public_prime( unsigned nbits );
-MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
- MPI g, MPI **factors );
-
-#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not for v3)*/
-#define PUBKEY_ALGO_DSA 17
-#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */
-
-#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
-
-#define PUBKEY_USAGE_SIG 1 /* key is good for signatures */
-#define PUBKEY_USAGE_ENC 2 /* key is good for encryption */
-
-/* from gnupg-1.0.0/include/errors.h */
-
-#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
-#define G10ERR_BAD_SECKEY 7 /* Bad secret key */
-#define G10ERR_BAD_SIGN 8 /* Bad signature */
-#define G10ERR_BAD_MPI 30
-
-/*-- smallprime.c --*/
-extern ushort small_prime_numbers[];
diff --git a/src/pluto/id.c b/src/pluto/id.c
index 8db322a5e..f34775e68 100644
--- a/src/pluto/id.c
+++ b/src/pluto/id.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: id.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdlib.h>
@@ -22,13 +20,12 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
-#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
-# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
+#ifndef HOST_NAME_MAX /* POSIX 1003.1-2001 says <unistd.h> defines this */
+# define HOST_NAME_MAX 255 /* upper bound, according to SUSv2 */
#endif
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "constants.h"
#include "defs.h"
@@ -38,10 +35,10 @@
#include "packet.h"
#include "whack.h"
-const struct id empty_id; /* ID_NONE */
+const struct id empty_id; /* ID_ANY */
enum myid_state myid_state = MYID_UNKNOWN;
-struct id myids[MYID_SPECIFIED+1]; /* %myid */
+struct id myids[MYID_SPECIFIED+1]; /* %myid */
char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
/* initialize id module
@@ -50,100 +47,117 @@ char *myid_str[MYID_SPECIFIED+1]; /* string form of IDs */
void
init_id(void)
{
- passert(empty_id.kind == ID_NONE);
- myid_state = MYID_UNKNOWN;
- {
+ passert(empty_id.kind == ID_ANY);
+ myid_state = MYID_UNKNOWN;
+ {
+ enum myid_state s;
+
+ for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
+ {
+ myids[s] = empty_id;
+ myid_str[s] = NULL;
+ }
+ }
+ set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
+ set_myid(MYID_IP, getenv("defaultrouteaddr"));
+ set_myFQDN();
+}
+
+/*
+ * free id module
+ */
+void
+free_id(void)
+{
enum myid_state s;
for (s = MYID_UNKNOWN; s <= MYID_SPECIFIED; s++)
{
- myids[s] = empty_id;
- myid_str[s] = NULL;
+ free_id_content(&myids[s]);
+ free(myid_str[s]);
}
- }
- set_myid(MYID_SPECIFIED, getenv("IPSECmyid"));
- set_myid(MYID_IP, getenv("defaultrouteaddr"));
- set_myFQDN();
}
static void
calc_myid_str(enum myid_state s)
{
- /* preformat the ID name */
- char buf[BUF_LEN];
+ /* preformat the ID name */
+ char buf[BUF_LEN];
- idtoa(&myids[s], buf, BUF_LEN);
- replace(myid_str[s], clone_str(buf, "myid string"));
+ idtoa(&myids[s], buf, BUF_LEN);
+ replace(myid_str[s], clone_str(buf));
}
void
set_myid(enum myid_state s, char *idstr)
{
- if (idstr != NULL)
- {
- struct id id;
- err_t ugh = atoid(idstr, &id, FALSE);
-
- if (ugh != NULL)
- {
- loglog(RC_BADID, "myid malformed: %s \"%s\"", ugh, idstr);
- }
- else
+ if (idstr != NULL)
{
- free_id_content(&myids[s]);
- unshare_id_content(&id);
- myids[s] = id;
- if (s == MYID_SPECIFIED)
- myid_state = MYID_SPECIFIED;
-
- calc_myid_str(s);
+ struct id id;
+ err_t ugh = atoid(idstr, &id, FALSE);
+
+ if (ugh != NULL)
+ {
+ loglog(RC_BADID, "myid malformed: %s \"%s\"", ugh, idstr);
+ }
+ else
+ {
+ free_id_content(&myids[s]);
+ unshare_id_content(&id);
+ myids[s] = id;
+ if (s == MYID_SPECIFIED)
+ myid_state = MYID_SPECIFIED;
+
+ calc_myid_str(s);
+ }
}
- }
}
void
set_myFQDN(void)
{
- char FQDN[HOST_NAME_MAX + 1];
- int r = gethostname(FQDN, sizeof(FQDN));
-
- free_id_content(&myids[MYID_HOSTNAME]);
- myids[MYID_HOSTNAME] = empty_id;
- if (r != 0)
- {
- log_errno((e, "gethostname() failed in set_myFQDN"));
- }
- else
- {
- FQDN[sizeof(FQDN) - 1] = '\0'; /* insurance */
+ char FQDN[HOST_NAME_MAX + 1];
+ int r = gethostname(FQDN, sizeof(FQDN));
+ free_id_content(&myids[MYID_HOSTNAME]);
+ myids[MYID_HOSTNAME] = empty_id;
+ if (r != 0)
{
- size_t len = strlen(FQDN);
-
- if (len > 0 && FQDN[len-1] == '.')
- {
- /* nuke trailing . */
- FQDN[len-1]='\0';
- }
+ log_errno((e, "gethostname() failed in set_myFQDN"));
}
-
- if (!strcaseeq(FQDN, "localhost.localdomain"))
+ else
{
- clonetochunk(myids[MYID_HOSTNAME].name, FQDN, strlen(FQDN), "my FQDN");
- myids[MYID_HOSTNAME].kind = ID_FQDN;
- calc_myid_str(MYID_HOSTNAME);
+ FQDN[sizeof(FQDN) - 1] = '\0'; /* insurance */
+
+ {
+ size_t len = strlen(FQDN);
+
+ if (len > 0 && FQDN[len-1] == '.')
+ {
+ /* nuke trailing . */
+ FQDN[len-1]='\0';
+ }
+ }
+
+ if (!strcaseeq(FQDN, "localhost.localdomain"))
+ {
+ chunk_t myid_name = { FQDN, strlen(FQDN) };
+
+ myids[MYID_HOSTNAME].name = chunk_clone(myid_name);
+ myids[MYID_HOSTNAME].kind = ID_FQDN;
+ calc_myid_str(MYID_HOSTNAME);
+ }
}
- }
}
void
show_myid_status(void)
{
- char idstr[BUF_LEN];
+ char idstr[BUF_LEN];
- (void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
- whack_log(RC_COMMENT, "%%myid = %s", idstr);
+ (void)idtoa(&myids[myid_state], idstr, sizeof(idstr));
+ whack_log(RC_COMMENT, "%%myid = %s", idstr);
}
/* Convert textual form of id into a (temporary) struct id.
@@ -152,86 +166,86 @@ show_myid_status(void)
err_t
atoid(char *src, struct id *id, bool myid_ok)
{
- err_t ugh = NULL;
-
- *id = empty_id;
-
- if (myid_ok && streq("%myid", src))
- {
- id->kind = ID_MYID;
- }
- else if (strchr(src, '=') != NULL)
- {
- /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
- id->kind = ID_DER_ASN1_DN;
- id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */
- id->name.len = 0;
- /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN
- * discard optional @ character in front of DN
- */
- ugh = atodn((*src == '@')?src+1:src, &id->name);
- }
- else if (strchr(src, '@') == NULL)
- {
- if (streq(src, "%any") || streq(src, "0.0.0.0"))
+ err_t ugh = NULL;
+
+ *id = empty_id;
+
+ if (myid_ok && streq("%myid", src))
{
- /* any ID will be accepted */
- id->kind = ID_NONE;
+ id->kind = ID_MYID;
}
- else
+ else if (strchr(src, '=') != NULL)
{
- /* !!! this test is not sufficient for distinguishing address families.
- * We need a notation to specify that a FQDN is to be resolved to IPv6.
- */
- const struct af_info *afi = strchr(src, ':') == NULL
- ? &af_inet4_info: &af_inet6_info;
-
- id->kind = afi->id_addr;
- ugh = ttoaddr(src, 0, afi->af, &id->ip_addr);
+ /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
+ id->kind = ID_DER_ASN1_DN;
+ id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */
+ id->name.len = 0;
+ /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN
+ * discard optional @ character in front of DN
+ */
+ ugh = atodn((*src == '@')?src+1:src, &id->name);
}
- }
- else
- {
- if (*src == '@')
+ else if (strchr(src, '@') == NULL)
{
- if (*(src+1) == '#')
- {
- /* if there is a second specifier (#) on the line
- * we interprete this as ID_KEY_ID
- */
- id->kind = ID_KEY_ID;
- id->name.ptr = src;
- /* discard @~, convert from hex to bin */
- ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
- }
- else if (*(src+1) == '~')
- {
- /* if there is a second specifier (~) on the line
- * we interprete this as a binary ID_DER_ASN1_DN
- */
- id->kind = ID_DER_ASN1_DN;
- id->name.ptr = src;
- /* discard @~, convert from hex to bin */
- ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
- }
- else
- {
- id->kind = ID_FQDN;
- id->name.ptr = src+1; /* discard @ */
- id->name.len = strlen(src)-1;
- }
+ if (streq(src, "%any") || streq(src, "0.0.0.0"))
+ {
+ /* any ID will be accepted */
+ id->kind = ID_ANY;
+ }
+ else
+ {
+ /* !!! this test is not sufficient for distinguishing address families.
+ * We need a notation to specify that a FQDN is to be resolved to IPv6.
+ */
+ const struct af_info *afi = strchr(src, ':') == NULL
+ ? &af_inet4_info: &af_inet6_info;
+
+ id->kind = afi->id_addr;
+ ugh = ttoaddr(src, 0, afi->af, &id->ip_addr);
+ }
}
else
{
- /* We leave in @, as per DOI 4.6.2.4
- * (but DNS wants . instead).
- */
- id->kind = ID_USER_FQDN;
- id->name.ptr = src;
- id->name.len = strlen(src);
+ if (*src == '@')
+ {
+ if (*(src+1) == '#')
+ {
+ /* if there is a second specifier (#) on the line
+ * we interprete this as ID_KEY_ID
+ */
+ id->kind = ID_KEY_ID;
+ id->name.ptr = src;
+ /* discard @~, convert from hex to bin */
+ ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
+ }
+ else if (*(src+1) == '~')
+ {
+ /* if there is a second specifier (~) on the line
+ * we interprete this as a binary ID_DER_ASN1_DN
+ */
+ id->kind = ID_DER_ASN1_DN;
+ id->name.ptr = src;
+ /* discard @~, convert from hex to bin */
+ ugh = ttodata(src+2, 0, 16, id->name.ptr, strlen(src), &id->name.len);
+ }
+ else
+ {
+ id->kind = ID_FQDN;
+ id->name.ptr = src+1; /* discard @ */
+ id->name.len = strlen(src)-1;
+ }
+ }
+ else
+ {
+ /* We leave in @, as per DOI 4.6.2.4
+ * (but DNS wants . instead).
+ */
+ id->kind = ID_USER_FQDN;
+ id->name.ptr = src;
+ id->name.len = strlen(src);
+ }
}
- }
- return ugh;
+ return ugh;
}
@@ -241,72 +255,72 @@ atoid(char *src, struct id *id, bool myid_ok)
int
keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
{
- int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
- return (((size_t)n < dstlen)? n : dstlen) - 1;
+ int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
+ return (((size_t)n < dstlen)? n : dstlen) - 1;
}
void
iptoid(const ip_address *ip, struct id *id)
{
- *id = empty_id;
-
- switch (addrtypeof(ip))
- {
- case AF_INET:
- id->kind = ID_IPV4_ADDR;
- break;
- case AF_INET6:
- id->kind = ID_IPV6_ADDR;
- break;
- default:
- bad_case(addrtypeof(ip));
- }
- id->ip_addr = *ip;
+ *id = empty_id;
+
+ switch (addrtypeof(ip))
+ {
+ case AF_INET:
+ id->kind = ID_IPV4_ADDR;
+ break;
+ case AF_INET6:
+ id->kind = ID_IPV6_ADDR;
+ break;
+ default:
+ bad_case(addrtypeof(ip));
+ }
+ id->ip_addr = *ip;
}
int
idtoa(const struct id *id, char *dst, size_t dstlen)
{
- int n;
-
- id = resolve_myid(id);
- switch (id->kind)
- {
- case ID_NONE:
- n = snprintf(dst, dstlen, "(none)");
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
- break;
- case ID_FQDN:
- n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
- break;
- case ID_USER_FQDN:
- n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
- break;
- case ID_DER_ASN1_DN:
- n = dntoa(dst, dstlen, id->name);
- break;
- case ID_KEY_ID:
- n = keyidtoa(dst, dstlen, id->name);
- break;
- default:
- n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
- break;
- }
-
- /* "Sanitize" string so that log isn't endangered:
- * replace unprintable characters with '?'.
- */
- if (n > 0)
- {
- for ( ; *dst != '\0'; dst++)
- if (!isprint(*dst))
- *dst = '?';
- }
-
- return n;
+ int n;
+
+ id = resolve_myid(id);
+ switch (id->kind)
+ {
+ case ID_ANY:
+ n = snprintf(dst, dstlen, "(none)");
+ break;
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ n = (int)addrtot(&id->ip_addr, 0, dst, dstlen) - 1;
+ break;
+ case ID_FQDN:
+ n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
+ break;
+ case ID_USER_FQDN:
+ n = snprintf(dst, dstlen, "%.*s", (int)id->name.len, id->name.ptr);
+ break;
+ case ID_DER_ASN1_DN:
+ n = dntoa(dst, dstlen, id->name);
+ break;
+ case ID_KEY_ID:
+ n = keyidtoa(dst, dstlen, id->name);
+ break;
+ default:
+ n = snprintf(dst, dstlen, "unknown id kind %d", id->kind);
+ break;
+ }
+
+ /* "Sanitize" string so that log isn't endangered:
+ * replace unprintable characters with '?'.
+ */
+ if (n > 0)
+ {
+ for ( ; *dst != '\0'; dst++)
+ if (!isprint(*dst))
+ *dst = '?';
+ }
+
+ return n;
}
/* Replace the shell metacharacters ', \, ", `, and $ in a character string
@@ -315,26 +329,26 @@ idtoa(const struct id *id, char *dst, size_t dstlen)
void
escape_metachar(const char *src, char *dst, size_t dstlen)
{
- while (*src != '\0' && dstlen > 4)
- {
- switch (*src)
+ while (*src != '\0' && dstlen > 4)
{
- case '\'':
- case '\\':
- case '"':
- case '`':
- case '$':
- sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
- dst += 4;
- dstlen -= 4;
- break;
- default:
- *dst++ = *src;
- dstlen--;
+ switch (*src)
+ {
+ case '\'':
+ case '\\':
+ case '"':
+ case '`':
+ case '$':
+ sprintf(dst,"\\%s%o", (*src < 64)?"0":"", *src);
+ dst += 4;
+ dstlen -= 4;
+ break;
+ default:
+ *dst++ = *src;
+ dstlen--;
+ }
+ src++;
}
- src++;
- }
- *dst = '\0';
+ *dst = '\0';
}
@@ -344,126 +358,126 @@ escape_metachar(const char *src, char *dst, size_t dstlen)
void
unshare_id_content(struct id *id)
{
- switch (id->kind)
- {
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- id->name.ptr = clone_bytes(id->name.ptr, id->name.len, "keep id name");
- break;
- case ID_MYID:
- case ID_NONE:
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- break;
- default:
- bad_case(id->kind);
- }
+ switch (id->kind)
+ {
+ case ID_FQDN:
+ case ID_USER_FQDN:
+ case ID_DER_ASN1_DN:
+ case ID_KEY_ID:
+ id->name = chunk_clone(id->name);
+ break;
+ case ID_MYID:
+ case ID_ANY:
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ break;
+ default:
+ bad_case(id->kind);
+ }
}
void
free_id_content(struct id *id)
{
- switch (id->kind)
- {
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- freeanychunk(id->name);
- break;
- case ID_MYID:
- case ID_NONE:
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- break;
- default:
- bad_case(id->kind);
- }
+ switch (id->kind)
+ {
+ case ID_FQDN:
+ case ID_USER_FQDN:
+ case ID_DER_ASN1_DN:
+ case ID_KEY_ID:
+ free(id->name.ptr);
+ break;
+ case ID_MYID:
+ case ID_ANY:
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ break;
+ default:
+ bad_case(id->kind);
+ }
}
/* compare two struct id values */
bool
same_id(const struct id *a, const struct id *b)
{
- a = resolve_myid(a);
- b = resolve_myid(b);
- if (a->kind != b->kind)
- return FALSE;
- switch (a->kind)
- {
- case ID_NONE:
- return TRUE; /* kind of vacuous */
-
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- return sameaddr(&a->ip_addr, &b->ip_addr);
-
- case ID_FQDN:
- case ID_USER_FQDN:
- /* assumptions:
- * - case should be ignored
- * - trailing "." should be ignored (even if the only character?)
- */
+ a = resolve_myid(a);
+ b = resolve_myid(b);
+ if (a->kind != b->kind)
+ return FALSE;
+ switch (a->kind)
{
- size_t al = a->name.len
- , bl = b->name.len;
-
- while (al > 0 && a->name.ptr[al - 1] == '.')
- al--;
- while (bl > 0 && b->name.ptr[bl - 1] == '.')
- bl--;
- return al == bl
- && strncasecmp(a->name.ptr, b->name.ptr, al) == 0;
- }
+ case ID_ANY:
+ return TRUE; /* kind of vacuous */
+
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ return sameaddr(&a->ip_addr, &b->ip_addr);
+
+ case ID_FQDN:
+ case ID_USER_FQDN:
+ /* assumptions:
+ * - case should be ignored
+ * - trailing "." should be ignored (even if the only character?)
+ */
+ {
+ size_t al = a->name.len
+ , bl = b->name.len;
+
+ while (al > 0 && a->name.ptr[al - 1] == '.')
+ al--;
+ while (bl > 0 && b->name.ptr[bl - 1] == '.')
+ bl--;
+ return al == bl
+ && strncasecmp(a->name.ptr, b->name.ptr, al) == 0;
+ }
- case ID_DER_ASN1_DN:
- return same_dn(a->name, b->name);
+ case ID_DER_ASN1_DN:
+ return same_dn(a->name, b->name);
- case ID_KEY_ID:
- return a->name.len == b->name.len
- && memcmp(a->name.ptr, b->name.ptr, a->name.len) == 0;
+ case ID_KEY_ID:
+ return a->name.len == b->name.len
+ && memeq(a->name.ptr, b->name.ptr, a->name.len);
- default:
- bad_case(a->kind);
- }
- return FALSE;
+ default:
+ bad_case(a->kind);
+ }
+ return FALSE;
}
/* compare two struct id values, DNs can contain wildcards */
bool
match_id(const struct id *a, const struct id *b, int *wildcards)
{
- if (b->kind == ID_NONE)
- {
- *wildcards = MAX_WILDCARDS;
- return TRUE;
- }
- if (a->kind != b->kind)
- return FALSE;
- if (a->kind == ID_DER_ASN1_DN)
- return match_dn(a->name, b->name, wildcards);
- else
- {
- *wildcards = 0;
- return same_id(a, b);
- }
+ if (b->kind == ID_ANY)
+ {
+ *wildcards = MAX_WILDCARDS;
+ return TRUE;
+ }
+ if (a->kind != b->kind)
+ return FALSE;
+ if (a->kind == ID_DER_ASN1_DN)
+ return match_dn(a->name, b->name, wildcards);
+ else
+ {
+ *wildcards = 0;
+ return same_id(a, b);
+ }
}
/* count the numer of wildcards in an id */
int
id_count_wildcards(const struct id *id)
{
- switch (id->kind)
- {
- case ID_NONE:
- return MAX_WILDCARDS;
- case ID_DER_ASN1_DN:
- return dn_count_wildcards(id->name);
- default:
- return 0;
- }
+ switch (id->kind)
+ {
+ case ID_ANY:
+ return MAX_WILDCARDS;
+ case ID_DER_ASN1_DN:
+ return dn_count_wildcards(id->name);
+ default:
+ return 0;
+ }
}
/* build an ID payload
@@ -474,31 +488,31 @@ id_count_wildcards(const struct id *id)
void
build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end)
{
- const struct id *id = resolve_myid(&end->id);
-
- zero(hd);
- hd->isaiid_idtype = id->kind;
- switch (id->kind)
- {
- case ID_NONE:
- hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
- tl->len = addrbytesptr(&end->host_addr
- , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
- break;
- case ID_FQDN:
- case ID_USER_FQDN:
- case ID_DER_ASN1_DN:
- case ID_KEY_ID:
- *tl = id->name;
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- tl->len = addrbytesptr(&id->ip_addr
- , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
- break;
- default:
- bad_case(id->kind);
- }
+ const struct id *id = resolve_myid(&end->id);
+
+ zero(hd);
+ hd->isaiid_idtype = id->kind;
+ switch (id->kind)
+ {
+ case ID_ANY:
+ hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr;
+ tl->len = addrbytesptr(&end->host_addr
+ , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
+ break;
+ case ID_FQDN:
+ case ID_USER_FQDN:
+ case ID_DER_ASN1_DN:
+ case ID_KEY_ID:
+ *tl = id->name;
+ break;
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ tl->len = addrbytesptr(&id->ip_addr
+ , (const unsigned char **)&tl->ptr); /* sets tl->ptr too */
+ break;
+ default:
+ bad_case(id->kind);
+ }
}
/*
diff --git a/src/pluto/id.h b/src/pluto/id.h
index 185c17f20..dc2dcdfa6 100644
--- a/src/pluto/id.h
+++ b/src/pluto/id.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: id.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _ID_H
@@ -20,25 +18,25 @@
#include "defs.h"
struct id {
- int kind; /* ID_* value */
- ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
- chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
- /* ID_KEY_ID, ID_DER_ASN_DN */
+ int kind; /* ID_* value */
+ ip_address ip_addr; /* ID_IPV4_ADDR, ID_IPV6_ADDR */
+ chunk_t name; /* ID_FQDN, ID_USER_FQDN (with @) */
+ /* ID_KEY_ID, ID_DER_ASN_DN */
};
extern void init_id(void);
-
-extern const struct id empty_id; /* ID_NONE */
+extern void free_id(void);
+extern const struct id empty_id; /* ID_NONE */
enum myid_state {
- MYID_UNKNOWN, /* not yet figured out */
- MYID_HOSTNAME, /* our current hostname */
- MYID_IP, /* our default IP address */
- MYID_SPECIFIED /* as specified by ipsec.conf */
+ MYID_UNKNOWN, /* not yet figured out */
+ MYID_HOSTNAME, /* our current hostname */
+ MYID_IP, /* our default IP address */
+ MYID_SPECIFIED /* as specified by ipsec.conf */
};
extern enum myid_state myid_state;
-extern struct id myids[MYID_SPECIFIED+1]; /* %myid */
+extern struct id myids[MYID_SPECIFIED+1]; /* %myid */
extern char *myid_str[MYID_SPECIFIED+1]; /* strings */
extern void set_myid(enum myid_state s, char *);
extern void show_myid_status(void);
@@ -49,19 +47,19 @@ extern err_t atoid(char *src, struct id *id, bool myid_ok);
extern int keyidtoa(char *dst, size_t dstlen, chunk_t keyid);
extern void iptoid(const ip_address *ip, struct id *id);
extern int idtoa(const struct id *id, char *dst, size_t dstlen);
-#define IDTOA_BUF 512
+#define IDTOA_BUF 512
extern void escape_metachar(const char *src, char *dst, size_t dstlen);
-struct end; /* forward declaration of tag (defined in connections.h) */
+struct end; /* forward declaration of tag (defined in connections.h) */
extern void unshare_id_content(struct id *id);
extern void free_id_content(struct id *id);
extern bool same_id(const struct id *a, const struct id *b);
-#define MAX_WILDCARDS 15
+#define MAX_WILDCARDS 15
extern bool match_id(const struct id *a, const struct id *b, int *wildcards);
extern int id_count_wildcards(const struct id *id);
#define id_is_ipaddr(id) ((id)->kind == ID_IPV4_ADDR || (id)->kind == ID_IPV6_ADDR)
-struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */
+struct isakmp_ipsec_id; /* forward declaration of tag (defined in packet.h) */
extern void
- build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end);
+ build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end);
#endif /* _ID_H */
diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c
index 6759059fa..f833f85b5 100644
--- a/src/pluto/ike_alg.c
+++ b/src/pluto/ike_alg.c
@@ -1,5 +1,6 @@
/* IKE modular algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ike_alg.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdio.h>
@@ -21,16 +20,19 @@
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <library.h>
+#include <debug.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/prfs/prf.h>
#include "constants.h"
#include "defs.h"
-#include "sha1.h"
-#include "md5.h"
#include "crypto.h"
-
#include "state.h"
#include "packet.h"
+#include "keys.h"
#include "log.h"
#include "whack.h"
#include "spdb.h"
@@ -42,7 +44,7 @@
#define return_on(var, val) do { var=val;goto return_out; } while(0);
-/*
+/**
* IKE algorithm list handling - registration and lookup
*/
@@ -50,540 +52,371 @@
static struct ike_alg *ike_alg_base[IKE_ALG_MAX+1] = {NULL, NULL};
-/*
- * return ike_algo object by {type, id}
+/**
+ * Return ike_algo object by {type, id}
*/
-static struct ike_alg *
-ike_alg_find(u_int algo_type, u_int algo_id, u_int keysize __attribute__((unused)))
+static struct ike_alg *ike_alg_find(u_int algo_type, u_int algo_id,
+ u_int keysize __attribute__((unused)))
{
- struct ike_alg *e = ike_alg_base[algo_type];
+ struct ike_alg *e = ike_alg_base[algo_type];
- while (e != NULL && algo_id > e->algo_id)
- {
- e = e->algo_next;
- }
- return (e != NULL && e->algo_id == algo_id) ? e : NULL;
+ while (e != NULL && algo_id > e->algo_id)
+ {
+ e = e->algo_next;
+ }
+ return (e != NULL && e->algo_id == algo_id) ? e : NULL;
}
-/*
+/**
* "raw" ike_alg list adding function
*/
-int
-ike_alg_add(struct ike_alg* a)
+int ike_alg_add(struct ike_alg* a)
{
- if (a->algo_type > IKE_ALG_MAX)
- {
- plog("ike_alg: Not added, invalid algorithm type");
- return -EINVAL;
- }
-
- if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
- {
- plog("ike_alg: Not added, algorithm already exists");
- return -EEXIST;
- }
-
- {
- struct ike_alg **ep = &ike_alg_base[a->algo_type];
- struct ike_alg *e = *ep;
-
- while (e != NULL && a->algo_id > e->algo_id)
+ if (a->algo_type > IKE_ALG_MAX)
{
- ep = &e->algo_next;
- e = *ep;
+ plog("ike_alg: Not added, invalid algorithm type");
+ return -EINVAL;
}
- *ep = a;
- a->algo_next = e;
- return 0;
- }
-}
-/*
- * get IKE hash algorithm
- */
-struct hash_desc *ike_alg_get_hasher(u_int alg)
-{
- return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
-}
+ if (ike_alg_find(a->algo_type, a->algo_id, 0) != NULL)
+ {
+ plog("ike_alg: Not added, algorithm already exists");
+ return -EEXIST;
+ }
-/*
- * get IKE encryption algorithm
- */
-struct encrypt_desc *ike_alg_get_encrypter(u_int alg)
-{
- return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
-}
+ {
+ struct ike_alg **ep = &ike_alg_base[a->algo_type];
+ struct ike_alg *e = *ep;
-/*
- * check if IKE hash algorithm is present
- */
-bool
-ike_alg_hash_present(u_int halg)
-{
- return ike_alg_get_hasher(halg) != NULL;
+ while (e != NULL && a->algo_id > e->algo_id)
+ {
+ ep = &e->algo_next;
+ e = *ep;
+ }
+ *ep = a;
+ a->algo_next = e;
+ return 0;
+ }
}
-/*
- * check if IKE encryption algorithm is present
+/**
+ * Get IKE hash algorithm
*/
-bool
-ike_alg_enc_present(u_int ealg)
+struct hash_desc *ike_alg_get_hasher(u_int alg)
{
- return ike_alg_get_encrypter(ealg) != NULL;
+ return (struct hash_desc *) ike_alg_find(IKE_ALG_HASH, alg, 0);
}
-/*
- * Validate and register IKE hash algorithm object
+/**
+ * Get IKE encryption algorithm
*/
-int
-ike_alg_register_hash(struct hash_desc *hash_desc)
+struct encrypt_desc *ike_alg_get_crypter(u_int alg)
{
- const char *alg_name = NULL;
- int ret = 0;
-
- if (hash_desc->algo_id > OAKLEY_HASH_MAX)
- {
- plog ("ike_alg: hash alg=%d > max=%d"
- , hash_desc->algo_id, OAKLEY_HASH_MAX);
- return_on(ret,-EINVAL);
- }
-
- if (hash_desc->hash_ctx_size > sizeof (union hash_ctx))
- {
- plog ("ike_alg: hash alg=%d has ctx_size=%d > hash_ctx=%d"
- , hash_desc->algo_id
- , (int)hash_desc->hash_ctx_size
- , (int)sizeof (union hash_ctx));
- return_on(ret,-EOVERFLOW);
- }
-
- if (!(hash_desc->hash_init && hash_desc->hash_update && hash_desc->hash_final))
- {
- plog ("ike_alg: hash alg=%d needs hash_init(), hash_update() and hash_final()"
- , hash_desc->algo_id);
- return_on(ret,-EINVAL);
- }
-
- alg_name = enum_name(&oakley_hash_names, hash_desc->algo_id);
- if (!alg_name)
- {
- plog ("ike_alg: hash alg=%d not found in constants.c:oakley_hash_names"
- , hash_desc->algo_id);
- alg_name = "<NULL>";
- }
-
-return_out:
- if (ret == 0)
- ret = ike_alg_add((struct ike_alg *)hash_desc);
-
- plog("ike_alg: Activating %s hash: %s"
- ,alg_name, ret == 0 ? "Ok" : "FAILED");
-
- return ret;
+ return (struct encrypt_desc *) ike_alg_find(IKE_ALG_ENCRYPT, alg, 0);
}
-/*
- * Validate and register IKE encryption algorithm object
+/**
+ * Get IKE dh group
*/
-int
-ike_alg_register_enc(struct encrypt_desc *enc_desc)
+struct dh_desc *ike_alg_get_dh_group(u_int alg)
{
- int ret = ike_alg_add((struct ike_alg *)enc_desc);
-
- const char *alg_name = enum_name(&oakley_enc_names, enc_desc->algo_id);
-
- char alg_number[20];
-
- /* algorithm is not listed in oakley_enc_names */
- if (alg_name == NULL)
- {
- snprintf(alg_number, sizeof(alg_number), "OAKLEY_ID_%d"
- , enc_desc->algo_id);
- alg_name = alg_number;
- }
-
- plog("ike_alg: Activating %s encryption: %s"
- , alg_name, ret == 0 ? "Ok" : "FAILED");
-
- return ret;
+ return (struct dh_desc *) ike_alg_find(IKE_ALG_DH_GROUP, alg, 0);
}
-/*
+/**
* Get pfsgroup for this connection
*/
-const struct oakley_group_desc *
-ike_alg_pfsgroup(struct connection *c, lset_t policy)
+const struct dh_desc *ike_alg_pfsgroup(struct connection *c, lset_t policy)
{
- const struct oakley_group_desc * ret = NULL;
+ const struct dh_desc *ret = NULL;
- if ((policy & POLICY_PFS)
- && c->alg_info_esp
- && c->alg_info_esp->esp_pfsgroup)
- ret = lookup_group(c->alg_info_esp->esp_pfsgroup);
- return ret;
+ if ((policy & POLICY_PFS) &&
+ c->alg_info_esp && c->alg_info_esp->esp_pfsgroup)
+ {
+ ret = ike_alg_get_dh_group(c->alg_info_esp->esp_pfsgroup);
+ }
+ return ret;
}
-/*
+/**
* Create an OAKLEY proposal based on alg_info and policy
*/
-struct db_context *
-ike_alg_db_new(struct alg_info_ike *ai , lset_t policy)
+struct db_context *ike_alg_db_new(struct connection *c, lset_t policy)
{
- struct db_context *db_ctx = NULL;
- struct ike_info *ike_info;
- struct encrypt_desc *enc_desc;
- u_int ealg, halg, modp, eklen = 0;
- int i;
-
- bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
-
- if (!ai)
- {
- whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
- "for this connection "
- "(check ike algorithm string)");
- goto fail;
- }
- policy &= POLICY_ID_AUTH_MASK;
- db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
-
- /* for each group */
- ALG_INFO_IKE_FOREACH(ai, ike_info, i)
- {
- ealg = ike_info->ike_ealg;
- halg = ike_info->ike_halg;
- modp = ike_info->ike_modp;
- eklen= ike_info->ike_eklen;
-
- if (!ike_alg_enc_present(ealg))
- {
- DBG_log("ike_alg: ike enc ealg=%d not present"
- , ealg);
- continue;
- }
-
- if (!ike_alg_hash_present(halg))
- {
- DBG_log("ike_alg: ike hash halg=%d not present"
- , halg);
- continue;
- }
+ struct alg_info_ike *ai = c->alg_info_ike;
+ struct db_context *db_ctx = NULL;
+ struct ike_info *ike_info;
+ struct encrypt_desc *enc_desc;
+ u_int ealg, halg, modp, eklen = 0;
+ int i;
- enc_desc = ike_alg_get_encrypter(ealg);
- passert(enc_desc != NULL);
+ bool is_xauth_server = (policy & POLICY_XAUTH_SERVER) != LEMPTY;
- if (eklen
- && (eklen < enc_desc->keyminlen || eklen > enc_desc->keymaxlen))
+ if (!ai)
{
- DBG_log("ike_alg: ealg=%d (specified) keylen:%d, not valid min=%d, max=%d"
- , ealg
- , eklen
- , enc_desc->keyminlen
- , enc_desc->keymaxlen
- );
- continue;
+ whack_log(RC_LOG_SERIOUS, "no IKE algorithms "
+ "for this connection "
+ "(check ike algorithm string)");
+ goto fail;
}
+ policy &= POLICY_ID_AUTH_MASK;
+ db_ctx = db_prop_new(PROTO_ISAKMP, 8, 8 * 5);
- if (policy & POLICY_RSASIG)
+ /* for each group */
+ ALG_INFO_IKE_FOREACH(ai, ike_info, i)
{
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_RSA_SIG);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
+ ealg = ike_info->ike_ealg;
+ halg = ike_info->ike_halg;
+ modp = ike_info->ike_modp;
+ eklen= ike_info->ike_eklen;
- if (policy & POLICY_PSK)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
+ if (!ike_alg_get_crypter(ealg))
+ {
+ plog("ike alg: crypter %s not present",
+ enum_show(&oakley_enc_names, ealg));
+ continue;
+ }
+ if (!ike_alg_get_hasher(halg))
+ {
+ plog("ike alg: hasher %s not present",
+ enum_show(&oakley_hash_names, halg));
+ continue;
+ }
+ if (!ike_alg_get_dh_group(modp))
+ {
+ plog("ike alg: dh group %s not present",
+ enum_show(&oakley_group_names, modp));
+ continue;
+ }
+ enc_desc = ike_alg_get_crypter(ealg);
- if (policy & POLICY_XAUTH_RSASIG)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
- , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
- }
+ if (policy & POLICY_PUBKEY)
+ {
+ int auth_method = 0;
+ private_key_t *key = get_private_key(c);
+
+ if (key == NULL)
+ {
+ plog("ike alg: unable to locate my private key");
+ continue;
+ }
+ switch (key->get_type(key))
+ {
+ case KEY_RSA:
+ auth_method = OAKLEY_RSA_SIG;
+ break;
+ case KEY_ECDSA:
+ switch (key->get_keysize(key))
+ {
+ case 32:
+ auth_method = OAKLEY_ECDSA_256;
+ break;
+ case 48:
+ auth_method = OAKLEY_ECDSA_384;
+ break;
+ case 66:
+ auth_method = OAKLEY_ECDSA_521;
+ break;
+ default:
+ continue;
+ }
+ break;
+ default:
+ continue;
+ }
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ {
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ }
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, auth_method);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
- if (policy & POLICY_XAUTH_PSK)
- {
- db_trans_add(db_ctx, KEY_IKE);
- db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
- db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
- if (eklen)
- db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
- db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
- , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
- db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ if (policy & POLICY_PSK)
+ {
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ {
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ }
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD, OAKLEY_PRESHARED_KEY);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
+
+ if (policy & POLICY_XAUTH_RSASIG)
+ {
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ {
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ }
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
+ , is_xauth_server ? XAUTHRespRSA : XAUTHInitRSA);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
+
+ if (policy & POLICY_XAUTH_PSK)
+ {
+ db_trans_add(db_ctx, KEY_IKE);
+ db_attr_add_values(db_ctx, OAKLEY_ENCRYPTION_ALGORITHM, ealg);
+ db_attr_add_values(db_ctx, OAKLEY_HASH_ALGORITHM, halg);
+ if (eklen)
+ {
+ db_attr_add_values(db_ctx, OAKLEY_KEY_LENGTH, eklen);
+ }
+ db_attr_add_values(db_ctx, OAKLEY_AUTHENTICATION_METHOD
+ , is_xauth_server ? XAUTHRespPreShared : XAUTHInitPreShared);
+ db_attr_add_values(db_ctx, OAKLEY_GROUP_DESCRIPTION, modp);
+ }
}
- }
fail:
- return db_ctx;
+ return db_ctx;
}
-/*
+/**
* Show registered IKE algorithms
*/
-void
-ike_alg_list(void)
+void ike_alg_list(void)
{
- u_int i;
- struct ike_alg *a;
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE Encryption Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
- {
- struct encrypt_desc *desc = (struct encrypt_desc*)a;
-
- whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d-%d"
- , a->algo_id
- , enum_name(&oakley_enc_names, a->algo_id)
- , (int)desc->enc_blocksize*BITS_PER_BYTE
- , desc->keyminlen
- , desc->keydeflen
- , desc->keymaxlen
- );
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE Hash Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
- {
- whack_log(RC_COMMENT, "#%-5d %s, hashsize: %d"
- , a->algo_id
- , enum_name(&oakley_hash_names, a->algo_id)
- , (int)((struct hash_desc *)a)->hash_digest_size*BITS_PER_BYTE
- );
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered IKE DH Groups:");
- whack_log(RC_COMMENT, " ");
-
- for (i = 0; i < elemsof(oakley_group); i++)
- {
- const struct oakley_group_desc *gdesc=oakley_group + i;
-
- whack_log(RC_COMMENT, "#%-5d %s, groupsize: %d"
- , gdesc->group
- , enum_name(&oakley_group_names, gdesc->group)
- , (int)gdesc->bytes*BITS_PER_BYTE
- );
- }
-}
-
-/* Show IKE algorithms for
- * - this connection (result from ike= string)
- * - newest SA
- */
-void
-ike_alg_show_connection(struct connection *c, const char *instance)
-{
- char buf[256];
- struct state *st;
-
- if (c->alg_info_ike)
- {
- alg_info_snprint(buf, sizeof(buf)-1, (struct alg_info *)c->alg_info_ike);
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithms wanted: %s"
- , c->name
- , instance
- , buf
- );
-
- alg_info_snprint_ike(buf, sizeof(buf)-1, c->alg_info_ike);
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithms found: %s"
- , c->name
- , instance
- , buf
- );
- }
-
- st = state_with_serialno(c->newest_isakmp_sa);
- if (st)
- whack_log(RC_COMMENT
- , "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s"
- , c->name
- , instance
- , enum_show(&oakley_enc_names, st->st_oakley.encrypt)
- +7 /* strlen("OAKLEY_") */
- /* , st->st_oakley.encrypter->keydeflen */
- , st->st_oakley.enckeylen
- , enum_show(&oakley_hash_names, st->st_oakley.hash)
- +7 /* strlen("OAKLEY_") */
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- +13 /* strlen("OAKLEY_GROUP_") */
- );
-}
-
-/*
- * Apply a suite of testvectors to a hash algorithm
- */
-static bool
-ike_hash_test(const struct hash_desc *desc)
-{
- bool hash_results = TRUE;
- bool hmac_results = TRUE;
-
- if (desc->hash_testvectors == NULL)
- {
- plog(" %s hash self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
- }
- else
- {
- int i;
+ char buf[BUF_LEN];
+ char *pos;
+ int n, len;
+ struct ike_alg *a;
+
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of registered IKEv1 Algorithms:");
+ whack_log(RC_COMMENT, " ");
+
+ pos = buf;
+ *pos = '\0';
+ len = BUF_LEN;
+ for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
+ {
+ n = snprintf(pos, len, " %s", enum_name(&oakley_enc_names, a->algo_id));
+ pos += n;
+ len -= n;
+ if (len <= 0)
+ {
+ break;
+ }
+ }
+ whack_log(RC_COMMENT, " encryption:%s", buf);
- for (i = 0; desc->hash_testvectors[i].msg_digest != NULL; i++)
+ pos = buf;
+ *pos = '\0';
+ len = BUF_LEN;
+ for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
{
- u_char digest[MAX_DIGEST_LEN];
- bool result;
-
- union hash_ctx ctx;
-
- desc->hash_init(&ctx);
- desc->hash_update(&ctx, desc->hash_testvectors[i].msg
- ,desc->hash_testvectors[i].msg_size);
- desc->hash_final(digest, &ctx);
- result = memcmp(digest, desc->hash_testvectors[i].msg_digest
- , desc->hash_digest_size) == 0;
- DBG(DBG_CRYPT,
- DBG_log(" hash testvector %d: %s", i, result ? "ok":"failed")
- )
- hash_results &= result;
+ n = snprintf(pos, len, " %s", enum_name(&oakley_hash_names, a->algo_id));
+ pos += n;
+ len -= n;
+ if (len <= 0)
+ {
+ break;
+ }
}
- plog(" %s hash self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
- , hash_results ? "passed":"failed");
- }
-
- if (desc->hmac_testvectors == NULL)
- {
- plog(" %s hmac self-test not available", enum_name(&oakley_hash_names, desc->algo_id));
- }
- else
- {
- int i;
+ whack_log(RC_COMMENT, " integrity: %s", buf);
- for (i = 0; desc->hmac_testvectors[i].hmac != NULL; i++)
+ pos = buf;
+ *pos = '\0';
+ len = BUF_LEN;
+ for (a = ike_alg_base[IKE_ALG_DH_GROUP]; a != NULL; a = a->algo_next)
{
- u_char digest[MAX_DIGEST_LEN];
- bool result;
-
- struct hmac_ctx ctx;
-
- hmac_init(&ctx, desc, desc->hmac_testvectors[i].key
- , desc->hmac_testvectors[i].key_size);
- hmac_update(&ctx, desc->hmac_testvectors[i].msg
- ,desc->hmac_testvectors[i].msg_size);
- hmac_final(digest, &ctx);
- result = memcmp(digest, desc->hmac_testvectors[i].hmac
- , desc->hash_digest_size) == 0;
- DBG(DBG_CRYPT,
- DBG_log(" hmac testvector %d: %s", i, result ? "ok":"failed")
- )
- hmac_results &= result;
+ n = snprintf(pos, len, " %s", enum_name(&oakley_group_names, a->algo_id));
+ pos += n;
+ len -= n;
+ if (len <= 0)
+ {
+ break;
+ }
}
- plog(" %s hmac self-test %s", enum_name(&oakley_hash_names, desc->algo_id)
- , hmac_results ? "passed":"failed");
- }
- return hash_results && hmac_results;
+ whack_log(RC_COMMENT, " dh-group: %s", buf);
}
-/*
- * Apply test vectors to registered encryption and hash algorithms
+/**
+ * Show IKE algorithms for this connection (result from ike= string)
+ * and newest SA
*/
-bool
-ike_alg_test(void)
+void ike_alg_show_connection(struct connection *c, const char *instance)
{
- bool all_results = TRUE;
- struct ike_alg *a;
-
- plog("Testing registered IKE encryption algorithms:");
-
- for (a = ike_alg_base[IKE_ALG_ENCRYPT]; a != NULL; a = a->algo_next)
- {
- plog(" %s self-test not available", enum_name(&oakley_enc_names, a->algo_id));
- }
-
- plog("Testing registered IKE hash algorithms:");
-
- for (a = ike_alg_base[IKE_ALG_HASH]; a != NULL; a = a->algo_next)
- {
- struct hash_desc *desc = (struct hash_desc*)a;
+ struct state *st = state_with_serialno(c->newest_isakmp_sa);
- all_results &= ike_hash_test(desc);
- }
-
- if (all_results)
- plog("All crypto self-tests passed");
- else
- plog("Some crypto self-tests failed");
- return all_results;
+ if (st)
+ {
+ if (st->st_oakley.encrypt == OAKLEY_3DES_CBC)
+ {
+ whack_log(RC_COMMENT,
+ "\"%s\"%s: IKE proposal: %s/%s/%s",
+ c->name, instance,
+ enum_show(&oakley_enc_names, st->st_oakley.encrypt),
+ enum_show(&oakley_hash_names, st->st_oakley.hash),
+ enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
+ );
+ }
+ else
+ {
+ whack_log(RC_COMMENT,
+ "\"%s\"%s: IKE proposal: %s_%u/%s/%s",
+ c->name, instance,
+ enum_show(&oakley_enc_names, st->st_oakley.encrypt),
+ st->st_oakley.enckeylen,
+ enum_show(&oakley_hash_names, st->st_oakley.hash),
+ enum_show(&oakley_group_names, st->st_oakley.group->algo_id)
+ );
+ }
+ }
}
-/*
+/**
* ML: make F_STRICT logic consider enc,hash/auth,modp algorithms
*/
-bool
-ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
-, struct alg_info_ike *alg_info_ike)
+bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group,
+ struct alg_info_ike *alg_info_ike)
{
- /*
- * simple test to discard low key_len, will accept it only
- * if specified in "esp" string
- */
- bool ealg_insecure = (key_len < 128);
-
- if (ealg_insecure
- || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
- {
- int i;
- struct ike_info *ike_info;
-
- if (alg_info_ike)
+ /*
+ * simple test to discard low key_len, will accept it only
+ * if specified in "esp" string
+ */
+ bool ealg_insecure = (key_len < 128);
+
+ if (ealg_insecure
+ || (alg_info_ike && alg_info_ike->alg_info_flags & ALG_INFO_F_STRICT))
{
- ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
- {
- if (ike_info->ike_ealg == ealg
- && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
- && ike_info->ike_halg == aalg
- && ike_info->ike_modp == group)
+ int i;
+ struct ike_info *ike_info;
+
+ if (alg_info_ike)
{
- if (ealg_insecure)
- loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
- , enum_name(&oakley_enc_names, ealg));
- return TRUE;
+ ALG_INFO_IKE_FOREACH(alg_info_ike, ike_info, i)
+ {
+ if (ike_info->ike_ealg == ealg
+ && (ike_info->ike_eklen == 0 || key_len == 0 || ike_info->ike_eklen == key_len)
+ && ike_info->ike_halg == aalg
+ && ike_info->ike_modp == group)
+ {
+ if (ealg_insecure)
+ loglog(RC_LOG_SERIOUS, "You should NOT use insecure IKE algorithms (%s)!"
+ , enum_name(&oakley_enc_names, ealg));
+ return TRUE;
+ }
+ }
}
- }
+ plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
+ , enum_name(&oakley_enc_names, ealg), key_len
+ , enum_name(&oakley_hash_names, aalg)
+ , enum_name(&oakley_group_names, group)
+ , ealg_insecure ?
+ "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
+ );
+ return FALSE;
}
- plog("Oakley Transform [%s (%d), %s, %s] refused due to %s"
- , enum_name(&oakley_enc_names, ealg), key_len
- , enum_name(&oakley_hash_names, aalg)
- , enum_name(&oakley_group_names, group)
- , ealg_insecure ?
- "insecure key_len and enc. alg. not listed in \"ike\" string" : "strict flag"
- );
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
diff --git a/src/pluto/ike_alg.h b/src/pluto/ike_alg.h
index dbf4076c5..458d14c3a 100644
--- a/src/pluto/ike_alg.h
+++ b/src/pluto/ike_alg.h
@@ -10,85 +10,63 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ike_alg.h 3252 2007-10-06 21:24:50Z andreas $
*/
-
+
#ifndef _IKE_ALG_H
#define _IKE_ALG_H
+#include <freeswan.h>
+
#include "connections.h"
struct ike_alg {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
+ u_int16_t algo_type;
+ u_int16_t algo_id;
+ struct ike_alg *algo_next;
};
struct encrypt_desc {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
+ u_int16_t algo_type;
+ u_int16_t algo_id;
+ struct ike_alg *algo_next;
- size_t enc_ctxsize;
- size_t enc_blocksize;
- u_int keydeflen;
- u_int keymaxlen;
- u_int keyminlen;
- void (*do_crypt)(u_int8_t *dat, size_t datasize, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc);
+ size_t enc_blocksize;
+ u_int keydeflen;
+ u_int keymaxlen;
+ u_int keyminlen;
};
-typedef struct hash_testvector hash_testvector_t;
+struct hash_desc {
+ u_int16_t algo_type;
+ u_int16_t algo_id;
+ struct ike_alg *algo_next;
-struct hash_testvector {
- const size_t msg_size;
- const u_char *msg;
- const u_char *msg_digest;
+ size_t hash_digest_size;
};
-typedef struct hmac_testvector hmac_testvector_t;
-
-struct hmac_testvector {
- const size_t key_size;
- const u_char *key;
- const size_t msg_size;
- const u_char *msg;
- const u_char *hmac;
-};
-struct hash_desc {
- u_int16_t algo_type;
- u_int16_t algo_id;
- struct ike_alg *algo_next;
+struct dh_desc {
+ u_int16_t algo_type;
+ u_int16_t algo_id;
+ struct ike_alg *algo_next;
- size_t hash_ctx_size;
- size_t hash_block_size;
- size_t hash_digest_size;
- const hash_testvector_t *hash_testvectors;
- const hmac_testvector_t *hmac_testvectors;
- void (*hash_init)(void *ctx);
- void (*hash_update)(void *ctx, const u_int8_t *in, size_t datasize);
- void (*hash_final)(u_int8_t *out, void *ctx);
+ size_t ke_size;
};
-#define IKE_ALG_ENCRYPT 0
-#define IKE_ALG_HASH 1
-#define IKE_ALG_MAX IKE_ALG_HASH
+#define IKE_ALG_ENCRYPT 0
+#define IKE_ALG_HASH 1
+#define IKE_ALG_DH_GROUP 2
+#define IKE_ALG_MAX IKE_ALG_DH_GROUP
extern int ike_alg_add(struct ike_alg *a);
extern struct hash_desc *ike_alg_get_hasher(u_int alg);
-extern struct encrypt_desc *ike_alg_get_encrypter(u_int alg);
-extern bool ike_alg_enc_present(u_int ealg);
-extern bool ike_alg_hash_present(u_int halg);
-extern int ike_alg_register_hash(struct hash_desc *a);
-extern int ike_alg_register_enc(struct encrypt_desc *e);
-extern const struct oakley_group_desc* ike_alg_pfsgroup(struct connection *c
- , lset_t policy);
-extern struct db_context * ike_alg_db_new(struct alg_info_ike *ai, lset_t policy);
+extern struct encrypt_desc *ike_alg_get_crypter(u_int alg);
+extern struct dh_desc *ike_alg_get_dh_group(u_int alg);
+extern const struct dh_desc* ike_alg_pfsgroup(struct connection *c, lset_t policy);
+extern struct db_context * ike_alg_db_new(struct connection *c, lset_t policy);
extern void ike_alg_list(void);
extern void ike_alg_show_connection(struct connection *c, const char *instance);
-extern bool ike_alg_test(void);
extern bool ike_alg_ok_final(u_int ealg, u_int key_len, u_int aalg, u_int group
- , struct alg_info_ike *alg_info_ike);
+ , struct alg_info_ike *alg_info_ike);
extern int ike_alg_init(void);
#endif /* _IKE_ALG_H */
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index 9721ac583..929768ee9 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -1,6 +1,7 @@
/* IPsec DOI and Oakley resolution routines
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ipsec_doi.c 5052 2009-03-30 03:47:14Z andreas $
*/
#include <stdio.h>
@@ -24,16 +23,22 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
-#include <sys/time.h> /* for gettimeofday */
+#include <sys/time.h> /* for gettimeofday */
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <library.h>
+#include <asn1/asn1.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+#include <crypto/rngs/rng.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
#include "constants.h"
#include "defs.h"
-#include "mp_defs.h"
#include "state.h"
#include "id.h"
#include "x509.h"
@@ -44,25 +49,20 @@
#include "connections.h"
#include "keys.h"
#include "packet.h"
-#include "demux.h" /* needs packet.h */
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
+#include "demux.h" /* needs packet.h */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "kernel.h"
#include "log.h"
#include "cookie.h"
#include "server.h"
#include "spdb.h"
#include "timer.h"
-#include "rnd.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "whack.h"
#include "fetch.h"
#include "pkcs7.h"
-#include "asn1.h"
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
#include "vendor.h"
#include "alg_info.h"
#include "ike_alg.h"
@@ -74,115 +74,84 @@
* are we sending Pluto's Vendor ID?
*/
#ifdef VENDORID
-#define SEND_PLUTO_VID 1
+#define SEND_PLUTO_VID 1
#else /* !VENDORID */
-#define SEND_PLUTO_VID 0
+#define SEND_PLUTO_VID 0
#endif /* !VENDORID */
/*
* are we sending an XAUTH VID?
*/
#ifdef XAUTH_VID
-#define SEND_XAUTH_VID 1
+#define SEND_XAUTH_VID 1
#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID 0
+#define SEND_XAUTH_VID 0
#endif /* !XAUTH_VID */
/*
* are we sending a Cisco Unity VID?
*/
#ifdef CISCO_QUIRKS
-#define SEND_CISCO_UNITY_VID 1
+#define SEND_CISCO_UNITY_VID 1
#else /* !CISCO_QUIRKS */
-#define SEND_CISCO_UNITY_VID 0
+#define SEND_CISCO_UNITY_VID 0
#endif /* !CISCO_QUIRKS */
/* MAGIC: perform f, a function that returns notification_t
* and return from the ENCLOSING stf_status returning function if it fails.
*/
#define RETURN_STF_FAILURE(f) \
- { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; }
+ { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; }
/* create output HDR as replica of input HDR */
void
echo_hdr(struct msg_digest *md, bool enc, u_int8_t np)
{
- struct isakmp_hdr r_hdr = md->hdr; /* mostly same as incoming header */
-
- r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
- if (enc)
- r_hdr.isa_flags |= ISAKMP_FLAG_ENCRYPTION;
- /* some day, we may have to set r_hdr.isa_version */
- r_hdr.isa_np = np;
- if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
- impossible(); /* surely must have room and be well-formed */
+ struct isakmp_hdr r_hdr = md->hdr; /* mostly same as incoming header */
+
+ r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
+ if (enc)
+ r_hdr.isa_flags |= ISAKMP_FLAG_ENCRYPTION;
+ /* some day, we may have to set r_hdr.isa_version */
+ r_hdr.isa_np = np;
+ if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
+ impossible(); /* surely must have room and be well-formed */
}
/* Compute DH shared secret from our local secret and the peer's public value.
* We make the leap that the length should be that of the group
* (see quoted passage at start of ACCEPT_KE).
*/
-static void
-compute_dh_shared(struct state *st, const chunk_t g
-, const struct oakley_group_desc *group)
+static void compute_dh_shared(struct state *st, const chunk_t g)
{
- MP_INT mp_g, mp_shared;
- struct timeval tv0, tv1;
- unsigned long tv_diff;
-
- gettimeofday(&tv0, NULL);
- passert(st->st_sec_in_use);
- n_to_mpz(&mp_g, g.ptr, g.len);
- mpz_init(&mp_shared);
- mpz_powm(&mp_shared, &mp_g, &st->st_sec, group->modulus);
- mpz_clear(&mp_g);
- freeanychunk(st->st_shared); /* happens in odd error cases */
- st->st_shared = mpz_to_n(&mp_shared, group->bytes);
- mpz_clear(&mp_shared);
- gettimeofday(&tv1, NULL);
- tv_diff=(tv1.tv_sec - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec);
- DBG(DBG_CRYPT,
- DBG_log("compute_dh_shared(): time elapsed (%s): %ld usec"
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- , tv_diff);
- );
- /* if took more than 200 msec ... */
- if (tv_diff > 200000) {
- loglog(RC_LOG_SERIOUS, "WARNING: compute_dh_shared(): for %s took "
- "%ld usec"
- , enum_show(&oakley_group_names, st->st_oakley.group->group)
- , tv_diff);
- }
-
- DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared);
+ passert(st->st_dh);
+ st->st_dh->set_other_public_value(st->st_dh, g);
+ st->st_dh->get_shared_secret(st->st_dh, &st->st_shared);
+ DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared);
}
/* if we haven't already done so, compute a local DH secret (st->st_sec) and
* the corresponding public value (g). This is emitted as a KE payload.
*/
-static bool
-build_and_ship_KE(struct state *st, chunk_t *g
-, const struct oakley_group_desc *group, pb_stream *outs, u_int8_t np)
+static bool build_and_ship_KE(struct state *st, chunk_t *g,
+ const struct dh_desc *group,
+ pb_stream *outs, u_int8_t np)
{
- if (!st->st_sec_in_use)
- {
- u_char tmp[LOCALSECRETSIZE];
- MP_INT mp_g;
-
- get_rnd_bytes(tmp, LOCALSECRETSIZE);
- st->st_sec_in_use = TRUE;
- n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE);
-
- mpz_init(&mp_g);
- mpz_powm(&mp_g, &groupgenerator, &st->st_sec, group->modulus);
- freeanychunk(*g); /* happens in odd error cases */
- *g = mpz_to_n(&mp_g, group->bytes);
- mpz_clear(&mp_g);
+ if (st->st_dh == NULL)
+ {
+ st->st_dh = lib->crypto->create_dh(lib->crypto, group->algo_id);
+ if (st->st_dh == NULL)
+ {
+ plog("Diffie Hellman group %N is not available",
+ diffie_hellman_group_names, group->algo_id);
+ return FALSE;
+ }
+ }
+ st->st_dh->get_my_public_value(st->st_dh, g);
DBG(DBG_CRYPT,
- DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE);
- DBG_dump_chunk("Public DH value sent:\n", *g));
- }
- return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value");
+ DBG_dump_chunk("Public DH value sent:\n", *g)
+ )
+ return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value");
}
/* accept_ke
@@ -194,21 +163,22 @@ build_and_ship_KE(struct state *st, chunk_t *g
* Diffie-Hellman group enforced, if necessary, by pre-pending the
* value with zeros.
*/
-static notification_t
-accept_KE(chunk_t *dest, const char *val_name
-, const struct oakley_group_desc *gr
-, pb_stream *pbs)
+static notification_t accept_KE(chunk_t *dest, const char *val_name,
+ const struct dh_desc *gr,
+ pb_stream *pbs)
{
- if (pbs_left(pbs) != gr->bytes)
- {
- loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required"
- , (unsigned) pbs_left(pbs), (unsigned) gr->bytes);
- /* XXX Could send notification back */
- return INVALID_KEY_INFORMATION;
- }
- clonereplacechunk(*dest, pbs->cur, pbs_left(pbs), val_name);
- DBG_cond_dump_chunk(DBG_CRYPT, "DH public value received:\n", *dest);
- return NOTHING_WRONG;
+ if (pbs_left(pbs) != gr->ke_size)
+ {
+ loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required"
+ , (unsigned) pbs_left(pbs), gr->ke_size);
+ /* XXX Could send notification back */
+ return INVALID_KEY_INFORMATION;
+ }
+ free(dest->ptr);
+ *dest = chunk_create(pbs->cur, pbs_left(pbs));
+ *dest = chunk_clone(*dest);
+ DBG_cond_dump_chunk(DBG_CRYPT, "DH public value received:\n", *dest);
+ return NOTHING_WRONG;
}
/* accept_PFS_KE
@@ -216,652 +186,663 @@ accept_KE(chunk_t *dest, const char *val_name
* Check and accept optional Quick Mode KE payload for PFS.
* Extends ACCEPT_PFS to check whether KE is allowed or required.
*/
-static notification_t
-accept_PFS_KE(struct msg_digest *md, chunk_t *dest
-, const char *val_name, const char *msg_name)
+static notification_t accept_PFS_KE(struct msg_digest *md, chunk_t *dest,
+ const char *val_name, const char *msg_name)
{
- struct state *st = md->st;
- struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
+ struct state *st = md->st;
+ struct payload_digest *const ke_pd = md->chain[ISAKMP_NEXT_KE];
- if (ke_pd == NULL)
- {
- if (st->st_pfs_group != NULL)
- {
- loglog(RC_LOG_SERIOUS, "missing KE payload in %s message", msg_name);
- return INVALID_KEY_INFORMATION;
- }
- }
- else
- {
- if (st->st_pfs_group == NULL)
+ if (ke_pd == NULL)
{
- loglog(RC_LOG_SERIOUS, "%s message KE payload requires a GROUP_DESCRIPTION attribute in SA"
- , msg_name);
- return INVALID_KEY_INFORMATION;
+ if (st->st_pfs_group != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "missing KE payload in %s message", msg_name);
+ return INVALID_KEY_INFORMATION;
+ }
}
- if (ke_pd->next != NULL)
+ else
{
- loglog(RC_LOG_SERIOUS, "%s message contains several KE payloads; we accept at most one", msg_name);
- return INVALID_KEY_INFORMATION; /* ??? */
+ if (st->st_pfs_group == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%s message KE payload requires a GROUP_DESCRIPTION attribute in SA"
+ , msg_name);
+ return INVALID_KEY_INFORMATION;
+ }
+ if (ke_pd->next != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%s message contains several KE payloads; we accept at most one", msg_name);
+ return INVALID_KEY_INFORMATION; /* ??? */
+ }
+ return accept_KE(dest, val_name, st->st_pfs_group, &ke_pd->pbs);
}
- return accept_KE(dest, val_name, st->st_pfs_group, &ke_pd->pbs);
- }
- return NOTHING_WRONG;
+ return NOTHING_WRONG;
}
-static bool
-build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np
-, const char *name)
+static bool build_and_ship_nonce(chunk_t *n, pb_stream *outs, u_int8_t np,
+ const char *name)
{
- freeanychunk(*n);
- setchunk(*n, alloc_bytes(DEFAULT_NONCE_SIZE, name), DEFAULT_NONCE_SIZE);
- get_rnd_bytes(n->ptr, DEFAULT_NONCE_SIZE);
- return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
+ rng_t *rng;
+
+ free(n->ptr);
+ *n = chunk_create(malloc(DEFAULT_NONCE_SIZE), DEFAULT_NONCE_SIZE);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ rng->get_bytes(rng, DEFAULT_NONCE_SIZE, n->ptr);
+ rng->destroy(rng);
+ return out_generic_chunk(np, &isakmp_nonce_desc, outs, *n, name);
}
-static bool
-collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
+static bool collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
{
- struct connection *d = find_host_connection(&md->iface->addr
- , pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
+ struct connection *d = find_host_connection(&md->iface->addr
+ , pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
- for (; d != NULL; d = d->hp_next)
- {
- /* must be a road warrior connection */
- if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO)
- && d->spd.that.ca.ptr != NULL)
+ for (; d != NULL; d = d->hp_next)
{
- generalName_t *gn;
- bool new_entry = TRUE;
-
- for (gn = *top; gn != NULL; gn = gn->next)
- {
- if (same_dn(gn->name, d->spd.that.ca))
+ /* must be a road warrior connection */
+ if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO)
+ && d->spd.that.ca.ptr != NULL)
{
- new_entry = FALSE;
- break;
+ generalName_t *gn;
+ bool new_entry = TRUE;
+
+ for (gn = *top; gn != NULL; gn = gn->next)
+ {
+ if (same_dn(gn->name, d->spd.that.ca))
+ {
+ new_entry = FALSE;
+ break;
+ }
+ }
+ if (new_entry)
+ {
+ gn = malloc_thing(generalName_t);
+ gn->kind = GN_DIRECTORY_NAME;
+ gn->name = d->spd.that.ca;
+ gn->next = *top;
+ *top = gn;
+ }
}
- }
- if (new_entry)
- {
- gn = alloc_thing(generalName_t, "generalName");
- gn->kind = GN_DIRECTORY_NAME;
- gn->name = d->spd.that.ca;
- gn->next = *top;
- *top = gn;
- }
- }
- }
- return *top != NULL;
+ }
+ return *top != NULL;
}
-static bool
-build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs, u_int8_t np)
+static bool build_and_ship_CR(u_int8_t type, chunk_t ca, pb_stream *outs,
+ u_int8_t np)
{
- pb_stream cr_pbs;
- struct isakmp_cr cr_hd;
- cr_hd.isacr_np = np;
- cr_hd.isacr_type = type;
+ pb_stream cr_pbs;
+ struct isakmp_cr cr_hd;
+ cr_hd.isacr_np = np;
+ cr_hd.isacr_type = type;
- /* build CR header */
- if (!out_struct(&cr_hd, &isakmp_ipsec_cert_req_desc, outs, &cr_pbs))
- return FALSE;
+ /* build CR header */
+ if (!out_struct(&cr_hd, &isakmp_ipsec_cert_req_desc, outs, &cr_pbs))
+ return FALSE;
- if (ca.ptr != NULL)
- {
- /* build CR body containing the distinguished name of the CA */
- if (!out_chunk(ca, &cr_pbs, "CA"))
- return FALSE;
- }
- close_output_pbs(&cr_pbs);
- return TRUE;
+ if (ca.ptr != NULL)
+ {
+ /* build CR body containing the distinguished name of the CA */
+ if (!out_chunk(ca, &cr_pbs, "CA"))
+ return FALSE;
+ }
+ close_output_pbs(&cr_pbs);
+ return TRUE;
}
/* Send a notification to the peer. We could decide
* whether to send the notification, based on the type and the
* destination, if we care to.
*/
-static void
-send_notification(struct state *sndst, u_int16_t type, struct state *encst,
- msgid_t msgid, u_char *icookie, u_char *rcookie,
- u_char *spi, size_t spisize, u_char protoid)
+static void send_notification(struct state *sndst, u_int16_t type,
+ struct state *encst, msgid_t msgid,
+ u_char *icookie, u_char *rcookie,
+ u_char *spi, size_t spisize, u_char protoid)
{
- u_char buffer[1024];
- pb_stream pbs, r_hdr_pbs;
- u_char *r_hashval = NULL; /* where in reply to jam hash value */
- u_char *r_hash_start = NULL; /* start of what is to be hashed */
-
- passert((sndst) && (sndst->st_connection));
-
- plog("sending %snotification %s to %s:%u"
- , encst ? "encrypted " : ""
- , enum_name(&notification_names, type)
- , ip_str(&sndst->st_connection->spd.that.host_addr)
- , (unsigned)sndst->st_connection->spd.that.host_port);
-
- memset(buffer, 0, sizeof(buffer));
- init_pbs(&pbs, buffer, sizeof(buffer), "ISAKMP notify");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = encst ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_N;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = encst ? ISAKMP_FLAG_ENCRYPTION : 0;
- if (icookie)
- memcpy(hdr.isa_icookie, icookie, COOKIE_SIZE);
- if (rcookie)
- memcpy(hdr.isa_rcookie, rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &pbs, &r_hdr_pbs))
- impossible();
- }
-
- /* HASH -- value to be filled later */
- if (encst)
- {
- pb_stream hash_pbs;
- if (!out_generic(ISAKMP_NEXT_N, &isakmp_hash_desc, &r_hdr_pbs,
- &hash_pbs))
- impossible();
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(
- encst->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
- impossible();
- close_output_pbs(&hash_pbs);
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH */
- }
-
- /* Notification Payload */
- {
- pb_stream not_pbs;
- struct isakmp_notification isan;
-
- isan.isan_doi = ISAKMP_DOI_IPSEC;
- isan.isan_np = ISAKMP_NEXT_NONE;
- isan.isan_type = type;
- isan.isan_spisize = spisize;
- isan.isan_protoid = protoid;
-
- if (!out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, &not_pbs)
- || !out_raw(spi, spisize, &not_pbs, "spi"))
- impossible();
- close_output_pbs(&not_pbs);
- }
-
- /* calculate hash value and patch into Hash Payload */
- if (encst)
- {
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, encst->st_oakley.hasher, encst->st_skeyid_a);
- hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
+ u_char buffer[1024];
+ pb_stream pbs, r_hdr_pbs;
+ u_char *r_hashval = NULL; /* where in reply to jam hash value */
+ u_char *r_hash_start = NULL; /* start of what is to be hashed */
- DBG(DBG_CRYPT,
- DBG_log("HASH computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size);
- )
- }
+ passert((sndst) && (sndst->st_connection));
- /* Encrypt message (preserve st_iv and st_new_iv) */
- if (encst)
- {
- u_char old_iv[MAX_DIGEST_LEN];
- u_char new_iv[MAX_DIGEST_LEN];
+ plog("sending %snotification %s to %s:%u"
+ , encst ? "encrypted " : ""
+ , enum_name(&notification_names, type)
+ , ip_str(&sndst->st_connection->spd.that.host_addr)
+ , (unsigned)sndst->st_connection->spd.that.host_port);
+
+ memset(buffer, 0, sizeof(buffer));
+ init_pbs(&pbs, buffer, sizeof(buffer), "ISAKMP notify");
+
+ /* HDR* */
+ {
+ struct isakmp_hdr hdr;
+
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = encst ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_N;
+ hdr.isa_xchg = ISAKMP_XCHG_INFO;
+ hdr.isa_msgid = msgid;
+ hdr.isa_flags = encst ? ISAKMP_FLAG_ENCRYPTION : 0;
+ if (icookie)
+ memcpy(hdr.isa_icookie, icookie, COOKIE_SIZE);
+ if (rcookie)
+ memcpy(hdr.isa_rcookie, rcookie, COOKIE_SIZE);
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &pbs, &r_hdr_pbs))
+ impossible();
+ }
- u_int old_iv_len = encst->st_iv_len;
- u_int new_iv_len = encst->st_new_iv_len;
-
- if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
- impossible();
-
- memcpy(old_iv, encst->st_iv, old_iv_len);
- memcpy(new_iv, encst->st_new_iv, new_iv_len);
-
- if (!IS_ISAKMP_SA_ESTABLISHED(encst->st_state))
- {
- memcpy(encst->st_ph1_iv, encst->st_new_iv, encst->st_new_iv_len);
- encst->st_ph1_iv_len = encst->st_new_iv_len;
- }
- init_phase2_iv(encst, &msgid);
- if (!encrypt_message(&r_hdr_pbs, encst))
- impossible();
-
- /* restore preserved st_iv and st_new_iv */
- memcpy(encst->st_iv, old_iv, old_iv_len);
- memcpy(encst->st_new_iv, new_iv, new_iv_len);
- encst->st_iv_len = old_iv_len;
- encst->st_new_iv_len = new_iv_len;
- }
- else
- {
- close_output_pbs(&r_hdr_pbs);
- }
-
- /* Send packet (preserve st_tpacket) */
- {
- chunk_t saved_tpacket = sndst->st_tpacket;
-
- setchunk(sndst->st_tpacket, pbs.start, pbs_offset(&pbs));
- send_packet(sndst, "ISAKMP notify");
- sndst->st_tpacket = saved_tpacket;
- }
+ /* HASH -- value to be filled later */
+ if (encst)
+ {
+ pb_stream hash_pbs;
+ if (!out_generic(ISAKMP_NEXT_N, &isakmp_hash_desc, &r_hdr_pbs,
+ &hash_pbs))
+ impossible();
+ r_hashval = hash_pbs.cur; /* remember where to plant value */
+ if (!out_zero(
+ encst->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH"))
+ impossible();
+ close_output_pbs(&hash_pbs);
+ r_hash_start = r_hdr_pbs.cur; /* hash from after HASH */
+ }
+
+ /* Notification Payload */
+ {
+ pb_stream not_pbs;
+ struct isakmp_notification isan;
+
+ isan.isan_doi = ISAKMP_DOI_IPSEC;
+ isan.isan_np = ISAKMP_NEXT_NONE;
+ isan.isan_type = type;
+ isan.isan_spisize = spisize;
+ isan.isan_protoid = protoid;
+
+ if (!out_struct(&isan, &isakmp_notification_desc, &r_hdr_pbs, &not_pbs)
+ || !out_raw(spi, spisize, &not_pbs, "spi"))
+ impossible();
+ close_output_pbs(&not_pbs);
+ }
+
+ /* calculate hash value and patch into Hash Payload */
+ if (encst)
+ {
+ chunk_t msgid_chunk = chunk_from_thing(msgid);
+ chunk_t msg_chunk = { r_hash_start, r_hdr_pbs.cur-r_hash_start };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(encst->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, encst->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, msg_chunk, r_hashval);
+
+ DBG(DBG_CRYPT,
+ DBG_log("HASH computed:");
+ DBG_dump("", r_hashval, prf->get_block_size(prf));
+ )
+ prf->destroy(prf);
+ }
+
+ /* Encrypt message (preserve st_iv and st_new_iv) */
+ if (encst)
+ {
+ u_char old_iv[MAX_DIGEST_LEN];
+ u_char new_iv[MAX_DIGEST_LEN];
+
+ u_int old_iv_len = encst->st_iv_len;
+ u_int new_iv_len = encst->st_new_iv_len;
+
+ if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
+ impossible();
+
+ memcpy(old_iv, encst->st_iv, old_iv_len);
+ memcpy(new_iv, encst->st_new_iv, new_iv_len);
+
+ if (!IS_ISAKMP_SA_ESTABLISHED(encst->st_state))
+ {
+ memcpy(encst->st_ph1_iv, encst->st_new_iv, encst->st_new_iv_len);
+ encst->st_ph1_iv_len = encst->st_new_iv_len;
+ }
+ init_phase2_iv(encst, &msgid);
+ if (!encrypt_message(&r_hdr_pbs, encst))
+ impossible();
+
+ /* restore preserved st_iv and st_new_iv */
+ memcpy(encst->st_iv, old_iv, old_iv_len);
+ memcpy(encst->st_new_iv, new_iv, new_iv_len);
+ encst->st_iv_len = old_iv_len;
+ encst->st_new_iv_len = new_iv_len;
+ }
+ else
+ {
+ close_output_pbs(&r_hdr_pbs);
+ }
+
+ /* Send packet (preserve st_tpacket) */
+ {
+ chunk_t saved_tpacket = sndst->st_tpacket;
+
+ sndst->st_tpacket = chunk_create(pbs.start, pbs_offset(&pbs));
+ send_packet(sndst, "ISAKMP notify");
+ sndst->st_tpacket = saved_tpacket;
+ }
}
-void
-send_notification_from_state(struct state *st, enum state_kind state,
- u_int16_t type)
+void send_notification_from_state(struct state *st, enum state_kind state,
+ u_int16_t type)
{
- struct state *p1st;
-
- passert(st);
-
- if (state == STATE_UNDEFINED)
- state = st->st_state;
-
- if (IS_QUICK(state))
- {
- p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
- if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)))
- {
- loglog(RC_LOG_SERIOUS,
- "no Phase1 state for Quick mode notification");
- return;
- }
- send_notification(st, type, p1st, generate_msgid(p1st),
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
- else if (IS_ISAKMP_ENCRYPTED(state) && st->st_enc_key.ptr != NULL)
- {
- send_notification(st, type, st, generate_msgid(st),
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
- else
- {
- /* no ISAKMP SA established - don't encrypt notification */
- send_notification(st, type, NULL, 0,
- st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
- }
+ struct state *p1st;
+
+ passert(st);
+
+ if (state == STATE_UNDEFINED)
+ state = st->st_state;
+
+ if (IS_QUICK(state))
+ {
+ p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
+ if ((p1st == NULL) || (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state)))
+ {
+ loglog(RC_LOG_SERIOUS,
+ "no Phase1 state for Quick mode notification");
+ return;
+ }
+ send_notification(st, type, p1st, generate_msgid(p1st),
+ st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
+ }
+ else if (IS_ISAKMP_ENCRYPTED(state) && st->st_enc_key.ptr != NULL)
+ {
+ send_notification(st, type, st, generate_msgid(st),
+ st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
+ }
+ else
+ {
+ /* no ISAKMP SA established - don't encrypt notification */
+ send_notification(st, type, NULL, 0,
+ st->st_icookie, st->st_rcookie, NULL, 0, PROTO_ISAKMP);
+ }
}
-void
-send_notification_from_md(struct msg_digest *md, u_int16_t type)
+void send_notification_from_md(struct msg_digest *md, u_int16_t type)
{
- /**
- * Create a dummy state to be able to use send_packet in
- * send_notification
- *
- * we need to set:
- * st_connection->that.host_addr
- * st_connection->that.host_port
- * st_connection->interface
- */
- struct state st;
- struct connection cnx;
-
- passert(md);
-
- memset(&st, 0, sizeof(st));
- memset(&cnx, 0, sizeof(cnx));
- st.st_connection = &cnx;
- cnx.spd.that.host_addr = md->sender;
- cnx.spd.that.host_port = md->sender_port;
- cnx.interface = md->iface;
-
- send_notification(&st, type, NULL, 0,
- md->hdr.isa_icookie, md->hdr.isa_rcookie, NULL, 0, PROTO_ISAKMP);
+ /**
+ * Create a dummy state to be able to use send_packet in
+ * send_notification
+ *
+ * we need to set:
+ * st_connection->that.host_addr
+ * st_connection->that.host_port
+ * st_connection->interface
+ */
+ struct state st;
+ struct connection cnx;
+
+ passert(md);
+
+ memset(&st, 0, sizeof(st));
+ memset(&cnx, 0, sizeof(cnx));
+ st.st_connection = &cnx;
+ cnx.spd.that.host_addr = md->sender;
+ cnx.spd.that.host_port = md->sender_port;
+ cnx.interface = md->iface;
+
+ send_notification(&st, type, NULL, 0,
+ md->hdr.isa_icookie, md->hdr.isa_rcookie, NULL, 0, PROTO_ISAKMP);
}
/* Send a Delete Notification to announce deletion of ISAKMP SA or
* inbound IPSEC SAs. Does nothing if no such SAs are being deleted.
* Delete Notifications cannot announce deletion of outbound IPSEC/ISAKMP SAs.
*/
-void
-send_delete(struct state *st)
+void send_delete(struct state *st)
{
- pb_stream reply_pbs;
- pb_stream r_hdr_pbs;
- msgid_t msgid;
- u_char buffer[8192];
- struct state *p1st;
- ip_said said[EM_MAXRELSPIS];
- ip_said *ns = said;
- u_char
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
- bool isakmp_sa = FALSE;
-
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
- if (p1st == NULL)
+ pb_stream reply_pbs;
+ pb_stream r_hdr_pbs;
+ msgid_t msgid;
+ u_char buffer[8192];
+ struct state *p1st;
+ ip_said said[EM_MAXRELSPIS];
+ ip_said *ns = said;
+ u_char
+ *r_hashval, /* where in reply to jam hash value */
+ *r_hash_start; /* start of what is to be hashed */
+ bool isakmp_sa = FALSE;
+
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ {
+ p1st = find_phase1_state(st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
+ if (p1st == NULL)
+ {
+ DBG(DBG_CONTROL, DBG_log("no Phase 1 state for Delete"));
+ return;
+ }
+
+ if (st->st_ah.present)
+ {
+ ns->spi = st->st_ah.our_spi;
+ ns->dst = st->st_connection->spd.this.host_addr;
+ ns->proto = PROTO_IPSEC_AH;
+ ns++;
+ }
+ if (st->st_esp.present)
+ {
+ ns->spi = st->st_esp.our_spi;
+ ns->dst = st->st_connection->spd.this.host_addr;
+ ns->proto = PROTO_IPSEC_ESP;
+ ns++;
+ }
+
+ passert(ns != said); /* there must be some SAs to delete */
+ }
+ else if (IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ p1st = st;
+ isakmp_sa = TRUE;
+ }
+ else
{
- DBG(DBG_CONTROL, DBG_log("no Phase 1 state for Delete"));
- return;
+ return; /* nothing to do */
}
- if (st->st_ah.present)
+ msgid = generate_msgid(p1st);
+
+ zero(buffer);
+ init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg");
+
+ /* HDR* */
{
- ns->spi = st->st_ah.our_spi;
- ns->dst = st->st_connection->spd.this.host_addr;
- ns->proto = PROTO_IPSEC_AH;
- ns++;
+ struct isakmp_hdr hdr;
+
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_HASH;
+ hdr.isa_xchg = ISAKMP_XCHG_INFO;
+ hdr.isa_msgid = msgid;
+ hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE);
+ memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE);
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs))
+ impossible();
}
- if (st->st_esp.present)
+
+ /* HASH -- value to be filled later */
{
- ns->spi = st->st_esp.our_spi;
- ns->dst = st->st_connection->spd.this.host_addr;
- ns->proto = PROTO_IPSEC_ESP;
- ns++;
- }
-
- passert(ns != said); /* there must be some SAs to delete */
- }
- else if (IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- p1st = st;
- isakmp_sa = TRUE;
- }
- else
- {
- return; /* nothing to do */
- }
-
- msgid = generate_msgid(p1st);
-
- zero(buffer);
- init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs))
- impossible();
- }
-
- /* HASH -- value to be filled later */
- {
- pb_stream hash_pbs;
-
- if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
- impossible();
- r_hashval = hash_pbs.cur; /* remember where to plant value */
- if (!out_zero(p1st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH(1)"))
- impossible();
- close_output_pbs(&hash_pbs);
- r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */
- }
-
- /* Delete Payloads */
- if (isakmp_sa)
- {
- pb_stream del_pbs;
- struct isakmp_delete isad;
- u_char isakmp_spi[2*COOKIE_SIZE];
-
- isad.isad_doi = ISAKMP_DOI_IPSEC;
- isad.isad_np = ISAKMP_NEXT_NONE;
- isad.isad_spisize = (2 * COOKIE_SIZE);
- isad.isad_protoid = PROTO_ISAKMP;
- isad.isad_nospi = 1;
-
- memcpy(isakmp_spi, st->st_icookie, COOKIE_SIZE);
- memcpy(isakmp_spi+COOKIE_SIZE, st->st_rcookie, COOKIE_SIZE);
-
- if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
- || !out_raw(&isakmp_spi, (2*COOKIE_SIZE), &del_pbs, "delete payload"))
- impossible();
- close_output_pbs(&del_pbs);
- }
- else
- {
- while (ns != said)
- {
-
- pb_stream del_pbs;
- struct isakmp_delete isad;
-
- ns--;
- isad.isad_doi = ISAKMP_DOI_IPSEC;
- isad.isad_np = ns == said? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D;
- isad.isad_spisize = sizeof(ipsec_spi_t);
- isad.isad_protoid = ns->proto;
-
- isad.isad_nospi = 1;
- if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
- || !out_raw(&ns->spi, sizeof(ipsec_spi_t), &del_pbs, "delete payload"))
- impossible();
- close_output_pbs(&del_pbs);
- }
- }
-
- /* calculate hash value and patch into Hash Payload */
- {
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, p1st->st_oakley.hasher, p1st->st_skeyid_a);
- hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
+ pb_stream hash_pbs;
+
+ if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
+ impossible();
+ r_hashval = hash_pbs.cur; /* remember where to plant value */
+ if (!out_zero(p1st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH(1)"))
+ impossible();
+ close_output_pbs(&hash_pbs);
+ r_hash_start = r_hdr_pbs.cur; /* hash from after HASH(1) */
+ }
- DBG(DBG_CRYPT,
- DBG_log("HASH(1) computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size);
- )
- }
-
- /* Do a dance to avoid needing a new state object.
- * We use the Phase 1 State. This is the one with right
- * IV, for one thing.
- * The tricky bits are:
- * - we need to preserve (save/restore) st_iv (but not st_iv_new)
- * - we need to preserve (save/restore) st_tpacket.
- */
- {
- u_char old_iv[MAX_DIGEST_LEN];
- chunk_t saved_tpacket = p1st->st_tpacket;
-
- memcpy(old_iv, p1st->st_iv, p1st->st_iv_len);
- init_phase2_iv(p1st, &msgid);
-
- if (!encrypt_message(&r_hdr_pbs, p1st))
- impossible();
-
- setchunk(p1st->st_tpacket, reply_pbs.start, pbs_offset(&reply_pbs));
- send_packet(p1st, "delete notify");
- p1st->st_tpacket = saved_tpacket;
-
- /* get back old IV for this state */
- memcpy(p1st->st_iv, old_iv, p1st->st_iv_len);
- }
+ /* Delete Payloads */
+ if (isakmp_sa)
+ {
+ pb_stream del_pbs;
+ struct isakmp_delete isad;
+ u_char isakmp_spi[2*COOKIE_SIZE];
+
+ isad.isad_doi = ISAKMP_DOI_IPSEC;
+ isad.isad_np = ISAKMP_NEXT_NONE;
+ isad.isad_spisize = (2 * COOKIE_SIZE);
+ isad.isad_protoid = PROTO_ISAKMP;
+ isad.isad_nospi = 1;
+
+ memcpy(isakmp_spi, st->st_icookie, COOKIE_SIZE);
+ memcpy(isakmp_spi+COOKIE_SIZE, st->st_rcookie, COOKIE_SIZE);
+
+ if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
+ || !out_raw(&isakmp_spi, (2*COOKIE_SIZE), &del_pbs, "delete payload"))
+ impossible();
+ close_output_pbs(&del_pbs);
+ }
+ else
+ {
+ while (ns != said)
+ {
+
+ pb_stream del_pbs;
+ struct isakmp_delete isad;
+
+ ns--;
+ isad.isad_doi = ISAKMP_DOI_IPSEC;
+ isad.isad_np = ns == said? ISAKMP_NEXT_NONE : ISAKMP_NEXT_D;
+ isad.isad_spisize = sizeof(ipsec_spi_t);
+ isad.isad_protoid = ns->proto;
+
+ isad.isad_nospi = 1;
+ if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs)
+ || !out_raw(&ns->spi, sizeof(ipsec_spi_t), &del_pbs, "delete payload"))
+ impossible();
+ close_output_pbs(&del_pbs);
+ }
+ }
+
+ /* calculate hash value and patch into Hash Payload */
+ {
+ chunk_t msgid_chunk = chunk_from_thing(msgid);
+ chunk_t msg_chunk = { r_hash_start, r_hdr_pbs.cur-r_hash_start };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(p1st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, p1st->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, msg_chunk, r_hashval);
+
+ DBG(DBG_CRYPT,
+ DBG_log("HASH(1) computed:");
+ DBG_dump("", r_hashval, prf->get_block_size(prf));
+ )
+
+ prf->destroy(prf);
+ }
+
+ /* Do a dance to avoid needing a new state object.
+ * We use the Phase 1 State. This is the one with right
+ * IV, for one thing.
+ * The tricky bits are:
+ * - we need to preserve (save/restore) st_iv (but not st_iv_new)
+ * - we need to preserve (save/restore) st_tpacket.
+ */
+ {
+ u_char old_iv[MAX_DIGEST_LEN];
+ chunk_t saved_tpacket = p1st->st_tpacket;
+
+ memcpy(old_iv, p1st->st_iv, p1st->st_iv_len);
+ init_phase2_iv(p1st, &msgid);
+
+ if (!encrypt_message(&r_hdr_pbs, p1st))
+ impossible();
+
+ p1st->st_tpacket = chunk_create(reply_pbs.start, pbs_offset(&reply_pbs));
+ send_packet(p1st, "delete notify");
+ p1st->st_tpacket = saved_tpacket;
+
+ /* get back old IV for this state */
+ memcpy(p1st->st_iv, old_iv, p1st->st_iv_len);
+ }
}
-void
-accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
+void accept_delete(struct state *st, struct msg_digest *md,
+ struct payload_digest *p)
{
- struct isakmp_delete *d = &(p->payload.delete);
- size_t sizespi;
- int i;
-
- if (!md->encrypted)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: not encrypted");
- return;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- /* can't happen (if msg is encrypt), but just to be sure */
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA not established");
- return;
- }
-
- if (d->isad_nospi == 0)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: no SPI");
- return;
- }
-
- switch (d->isad_protoid)
- {
- case PROTO_ISAKMP:
- sizespi = 2 * COOKIE_SIZE;
- break;
- case PROTO_IPSEC_AH:
- case PROTO_IPSEC_ESP:
- sizespi = sizeof(ipsec_spi_t);
- break;
- case PROTO_IPCOMP:
- /* nothing interesting to delete */
- return;
- default:
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: unknown Protocol ID (%s)"
- , enum_show(&protocol_names, d->isad_protoid));
- return;
- }
-
- if (d->isad_spisize != sizespi)
- {
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: bad SPI size (%d) for %s"
- , d->isad_spisize, enum_show(&protocol_names, d->isad_protoid));
- return;
- }
-
- if (pbs_left(&p->pbs) != d->isad_nospi * sizespi)
- {
- loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: invalid payload size");
- return;
- }
-
- for (i = 0; i < d->isad_nospi; i++)
- {
- u_char *spi = p->pbs.cur + (i * sizespi);
-
- if (d->isad_protoid == PROTO_ISAKMP)
- {
- /**
- * ISAKMP
- */
- struct state *dst = find_state(spi /*iCookie*/
- , spi+COOKIE_SIZE /*rCookie*/
- , &st->st_connection->spd.that.host_addr
- , MAINMODE_MSGID);
-
- if (dst == NULL)
- {
- loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA not found (maybe expired)");
- }
- else if (!same_peer_ids(st->st_connection, dst->st_connection, NULL))
- {
- /* we've not authenticated the relevant identities */
+ struct isakmp_delete *d = &(p->payload.delete);
+ size_t sizespi;
+ int i;
+
+ if (!md->encrypted)
+ {
+ loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: not encrypted");
+ return;
+ }
+
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ /* can't happen (if msg is encrypt), but just to be sure */
loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
- "ISAKMP SA used to convey Delete has different IDs from ISAKMP SA it deletes");
- }
- else
- {
- struct connection *oldc;
-
- oldc = cur_connection;
- set_cur_connection(dst->st_connection);
+ "ISAKMP SA not established");
+ return;
+ }
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, dst);
+ if (d->isad_nospi == 0)
+ {
+ loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: no SPI");
+ return;
+ }
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "deleting ISAKMP State #%lu", dst->st_serialno);
- delete_state(dst);
- set_cur_connection(oldc);
- }
+ switch (d->isad_protoid)
+ {
+ case PROTO_ISAKMP:
+ sizespi = 2 * COOKIE_SIZE;
+ break;
+ case PROTO_IPSEC_AH:
+ case PROTO_IPSEC_ESP:
+ sizespi = sizeof(ipsec_spi_t);
+ break;
+ case PROTO_IPCOMP:
+ /* nothing interesting to delete */
+ return;
+ default:
+ loglog(RC_LOG_SERIOUS
+ , "ignoring Delete SA payload: unknown Protocol ID (%s)"
+ , enum_show(&protocol_names, d->isad_protoid));
+ return;
}
- else
+
+ if (d->isad_spisize != sizespi)
{
- /**
- * IPSEC (ESP/AH)
- */
- bool bogus;
- struct state *dst = find_phase2_state_to_delete(st
- , d->isad_protoid
- , *(ipsec_spi_t *)spi /* network order */
- , &bogus);
-
- if (dst == NULL)
- {
loglog(RC_LOG_SERIOUS
- , "ignoring Delete SA payload: %s SA(0x%08lx) not found (%s)"
- , enum_show(&protocol_names, d->isad_protoid)
- , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
- , bogus ? "our SPI - bogus implementation" : "maybe expired");
- }
- else
- {
- struct connection *rc = dst->st_connection;
- struct connection *oldc;
-
- oldc = cur_connection;
- set_cur_connection(rc);
-
- if (nat_traversal_enabled)
- nat_traversal_change_port_lookup(md, dst);
-
- if (rc->newest_ipsec_sa == dst->st_serialno
- && (rc->policy & POLICY_UP))
- {
- /* Last IPSec SA for a permanent connection that we
- * have initiated. Replace it in a few seconds.
- *
- * Useful if the other peer is rebooting.
- */
-#define DELETE_SA_DELAY EVENT_RETRANSMIT_DELAY_0
- if (dst->st_event != NULL
- && dst->st_event->ev_type == EVENT_SA_REPLACE
- && dst->st_event->ev_time <= DELETE_SA_DELAY + now())
- {
- /* Patch from Angus Lees to ignore retransmited
- * Delete SA.
+ , "ignoring Delete SA payload: bad SPI size (%d) for %s"
+ , d->isad_spisize, enum_show(&protocol_names, d->isad_protoid));
+ return;
+ }
+
+ if (pbs_left(&p->pbs) != d->isad_nospi * sizespi)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ignoring Delete SA payload: invalid payload size");
+ return;
+ }
+
+ for (i = 0; i < d->isad_nospi; i++)
+ {
+ u_char *spi = p->pbs.cur + (i * sizespi);
+
+ if (d->isad_protoid == PROTO_ISAKMP)
+ {
+ /**
+ * ISAKMP
*/
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "already replacing IPSEC State #%lu in %d seconds"
- , dst->st_serialno, (int)(dst->st_event->ev_time - now()));
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
- "replace IPSEC State #%lu in %d seconds"
- , dst->st_serialno, DELETE_SA_DELAY);
- dst->st_margin = DELETE_SA_DELAY;
- delete_event(dst);
- event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, dst);
- }
+ struct state *dst = find_state(spi /*iCookie*/
+ , spi+COOKIE_SIZE /*rCookie*/
+ , &st->st_connection->spd.that.host_addr
+ , MAINMODE_MSGID);
+
+ if (dst == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
+ "ISAKMP SA not found (maybe expired)");
+ }
+ else if (!same_peer_ids(st->st_connection, dst->st_connection, NULL))
+ {
+ /* we've not authenticated the relevant identities */
+ loglog(RC_LOG_SERIOUS, "ignoring Delete SA payload: "
+ "ISAKMP SA used to convey Delete has different IDs from ISAKMP SA it deletes");
+ }
+ else
+ {
+ struct connection *oldc;
+
+ oldc = cur_connection;
+ set_cur_connection(dst->st_connection);
+
+ if (nat_traversal_enabled)
+ nat_traversal_change_port_lookup(md, dst);
+
+ loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
+ "deleting ISAKMP State #%lu", dst->st_serialno);
+ delete_state(dst);
+ set_cur_connection(oldc);
+ }
}
else
{
- loglog(RC_LOG_SERIOUS, "received Delete SA(0x%08lx) payload: "
- "deleting IPSEC State #%lu"
- , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
- , dst->st_serialno);
- delete_state(dst);
- }
+ /**
+ * IPSEC (ESP/AH)
+ */
+ bool bogus;
+ struct state *dst = find_phase2_state_to_delete(st
+ , d->isad_protoid
+ , *(ipsec_spi_t *)spi /* network order */
+ , &bogus);
- /* reset connection */
- set_cur_connection(oldc);
- }
+ if (dst == NULL)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ignoring Delete SA payload: %s SA(0x%08lx) not found (%s)"
+ , enum_show(&protocol_names, d->isad_protoid)
+ , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
+ , bogus ? "our SPI - bogus implementation" : "maybe expired");
+ }
+ else
+ {
+ struct connection *rc = dst->st_connection;
+ struct connection *oldc;
+
+ oldc = cur_connection;
+ set_cur_connection(rc);
+
+ if (nat_traversal_enabled)
+ nat_traversal_change_port_lookup(md, dst);
+
+ if (rc->newest_ipsec_sa == dst->st_serialno
+ && (rc->policy & POLICY_UP))
+ {
+ /* Last IPSec SA for a permanent connection that we
+ * have initiated. Replace it in a few seconds.
+ *
+ * Useful if the other peer is rebooting.
+ */
+#define DELETE_SA_DELAY EVENT_RETRANSMIT_DELAY_0
+ if (dst->st_event != NULL
+ && dst->st_event->ev_type == EVENT_SA_REPLACE
+ && dst->st_event->ev_time <= DELETE_SA_DELAY + now())
+ {
+ /* Patch from Angus Lees to ignore retransmited
+ * Delete SA.
+ */
+ loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
+ "already replacing IPSEC State #%lu in %d seconds"
+ , dst->st_serialno, (int)(dst->st_event->ev_time - now()));
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "received Delete SA payload: "
+ "replace IPSEC State #%lu in %d seconds"
+ , dst->st_serialno, DELETE_SA_DELAY);
+ dst->st_margin = DELETE_SA_DELAY;
+ delete_event(dst);
+ event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, dst);
+ }
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "received Delete SA(0x%08lx) payload: "
+ "deleting IPSEC State #%lu"
+ , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)
+ , dst->st_serialno);
+ delete_state(dst);
+ }
+
+ /* reset connection */
+ set_cur_connection(oldc);
+ }
+ }
}
- }
}
/* The whole message must be a multiple of 4 octets.
@@ -869,14 +850,13 @@ accept_delete(struct state *st, struct msg_digest *md, struct payload_digest *p)
* rfc2408 3.6 Transform Payload.
* Note: it talks about 4 BYTE boundaries!
*/
-void
-close_message(pb_stream *pbs)
+void close_message(pb_stream *pbs)
{
- size_t padding = pad_up(pbs_offset(pbs), 4);
+ size_t padding = pad_up(pbs_offset(pbs), 4);
- if (padding != 0)
- (void) out_zero(padding, pbs, "message padding");
- close_output_pbs(pbs);
+ if (padding != 0)
+ (void) out_zero(padding, pbs, "message padding");
+ close_output_pbs(pbs);
}
/* Initiate an Oakley Main Mode exchange.
@@ -885,225 +865,220 @@ close_message(pb_stream *pbs)
*/
static stf_status
main_outI1(int whack_sock, struct connection *c, struct state *predecessor
- , lset_t policy, unsigned long try)
+ , lset_t policy, unsigned long try)
{
- struct state *st = new_state();
- pb_stream reply; /* not actually a reply, but you know what I mean */
- pb_stream rbody;
-
- int vids_to_send = 0;
-
- /* set up new state */
- st->st_connection = c;
- set_cur_state(st); /* we must reset before exit */
- st->st_policy = policy & ~POLICY_IPSEC_MASK;
- st->st_whack_sock = whack_sock;
- st->st_try = try;
- st->st_state = STATE_MAIN_I1;
-
- /* determine how many Vendor ID payloads we will be sending */
- if (SEND_PLUTO_VID)
- vids_to_send++;
- if (SEND_CISCO_UNITY_VID)
- vids_to_send++;
- if (c->spd.this.cert.type == CERT_PGP)
- vids_to_send++;
- if (SEND_XAUTH_VID)
- vids_to_send++;
- /* always send DPD Vendor ID */
- vids_to_send++;
- if (nat_traversal_enabled)
- vids_to_send++;
+ struct state *st = new_state();
+ pb_stream reply; /* not actually a reply, but you know what I mean */
+ pb_stream rbody;
+
+ int vids_to_send = 0;
+
+ /* set up new state */
+ st->st_connection = c;
+ set_cur_state(st); /* we must reset before exit */
+ st->st_policy = policy & ~POLICY_IPSEC_MASK;
+ st->st_whack_sock = whack_sock;
+ st->st_try = try;
+ st->st_state = STATE_MAIN_I1;
+
+ /* determine how many Vendor ID payloads we will be sending */
+ if (SEND_PLUTO_VID)
+ vids_to_send++;
+ if (SEND_CISCO_UNITY_VID)
+ vids_to_send++;
+ if (c->spd.this.cert.type == CERT_PGP)
+ vids_to_send++;
+ if (SEND_XAUTH_VID)
+ vids_to_send++;
+ /* always send DPD Vendor ID */
+ vids_to_send++;
+ if (nat_traversal_enabled)
+ vids_to_send++;
get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);
- insert_state(st); /* needs cookies, connection, and msgid (0) */
+ insert_state(st); /* needs cookies, connection, and msgid (0) */
- if (HAS_IPSEC_POLICY(policy))
- add_pending(dup_any(whack_sock), st, c, policy, 1
- , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);
+ if (HAS_IPSEC_POLICY(policy))
+ add_pending(dup_any(whack_sock), st, c, policy, 1
+ , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);
- if (predecessor == NULL)
- plog("initiating Main Mode");
- else
- plog("initiating Main Mode to replace #%lu", predecessor->st_serialno);
+ if (predecessor == NULL)
+ plog("initiating Main Mode");
+ else
+ plog("initiating Main Mode to replace #%lu", predecessor->st_serialno);
- /* set up reply */
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
+ /* set up reply */
+ init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
- /* HDR out */
- {
- struct isakmp_hdr hdr;
+ /* HDR out */
+ {
+ struct isakmp_hdr hdr;
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_SA;
- hdr.isa_xchg = ISAKMP_XCHG_IDPROT;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- /* R-cookie, flags and MessageID are left zero */
+ zero(&hdr); /* default to 0 */
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_SA;
+ hdr.isa_xchg = ISAKMP_XCHG_IDPROT;
+ memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
+ /* R-cookie, flags and MessageID are left zero */
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
-
- /* SA out */
- {
- u_char *sa_start = rbody.cur;
- if (!out_sa(&rbody, &oakley_sadb, st, TRUE
- , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+ /* SA out */
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
+ u_char *sa_start = rbody.cur;
- /* save initiator SA for later HASH */
- passert(st->st_p1isa.ptr == NULL); /* no leak! (MUST be first time) */
- clonetochunk(st->st_p1isa, sa_start, rbody.cur - sa_start
- , "sa in main_outI1");
- }
+ if (!out_sa(&rbody, &oakley_sadb, st, TRUE
+ , vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
- /* if enabled send Pluto Vendor ID */
- if (SEND_PLUTO_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_STRONGSWAN))
+ /* save initiator SA for later HASH */
+ passert(st->st_p1isa.ptr == NULL); /* no leak! (MUST be first time) */
+ st->st_p1isa = chunk_create(sa_start, rbody.cur - sa_start);
+ st->st_p1isa = chunk_clone(st->st_p1isa);
+ }
+
+ /* if enabled send Pluto Vendor ID */
+ if (SEND_PLUTO_VID)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_STRONGSWAN))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* if enabled send Cisco Unity Vendor ID */
- if (SEND_CISCO_UNITY_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_CISCO_UNITY))
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_CISCO_UNITY))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* if we have an OpenPGP certificate we assume an
- * OpenPGP peer and have to send the Vendor ID
- */
- if (c->spd.this.cert.type == CERT_PGP)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_OPENPGP))
+ /* if we have an OpenPGP certificate we assume an
+ * OpenPGP peer and have to send the Vendor ID
+ */
+ if (c->spd.this.cert.type == CERT_PGP)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_OPENPGP))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* Announce our ability to do eXtended AUTHentication to the peer */
- if (SEND_XAUTH_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_XAUTH))
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (SEND_XAUTH_VID)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_MISC_XAUTH))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* Announce our ability to do Dead Peer Detection to the peer */
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_DPD))
+ /* Announce our ability to do Dead Peer Detection to the peer */
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_MISC_DPD))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- if (nat_traversal_enabled)
- {
- /* Add supported NAT-Traversal VID */
- if (!nat_traversal_add_vid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody))
+ if (nat_traversal_enabled)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ /* Add supported NAT-Traversal VID */
+ if (!nat_traversal_add_vid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
-
- close_message(&rbody);
- close_output_pbs(&reply);
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "reply packet for main_outI1");
+ close_message(&rbody);
+ close_output_pbs(&reply);
+ st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
- /* Transmit */
+ /* Transmit */
- send_packet(st, "main_outI1");
+ send_packet(st, "main_outI1");
- /* Set up a retransmission event, half a minute henceforth */
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
+ /* Set up a retransmission event, half a minute henceforth */
+ delete_event(st);
+ event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
- if (predecessor != NULL)
- {
- update_pending(predecessor, st);
- whack_log(RC_NEW_STATE + STATE_MAIN_I1
- , "%s: initiate, replacing #%lu"
- , enum_name(&state_names, st->st_state)
- , predecessor->st_serialno);
- }
- else
- {
- whack_log(RC_NEW_STATE + STATE_MAIN_I1
- , "%s: initiate", enum_name(&state_names, st->st_state));
- }
- reset_cur_state();
- return STF_OK;
+ if (predecessor != NULL)
+ {
+ update_pending(predecessor, st);
+ whack_log(RC_NEW_STATE + STATE_MAIN_I1
+ , "%s: initiate, replacing #%lu"
+ , enum_name(&state_names, st->st_state)
+ , predecessor->st_serialno);
+ }
+ else
+ {
+ whack_log(RC_NEW_STATE + STATE_MAIN_I1
+ , "%s: initiate", enum_name(&state_names, st->st_state));
+ }
+ reset_cur_state();
+ return STF_OK;
}
-void
-ipsecdoi_initiate(int whack_sock
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
+void ipsecdoi_initiate(int whack_sock, struct connection *c, lset_t policy,
+ unsigned long try, so_serial_t replacing)
{
- /* If there's already an ISAKMP SA established, use that and
- * go directly to Quick Mode. We are even willing to use one
- * that is still being negotiated, but only if we are the Initiator
- * (thus we can be sure that the IDs are not going to change;
- * other issues around intent might matter).
- * Note: there is no way to initiate with a Road Warrior.
- */
- struct state *st = find_phase1_state(c
- , ISAKMP_SA_ESTABLISHED_STATES | PHASE1_INITIATOR_STATES);
-
- if (st == NULL)
- {
- (void) main_outI1(whack_sock, c, NULL, policy, try);
- }
- else if (HAS_IPSEC_POLICY(policy))
- {
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ /* If there's already an ISAKMP SA established, use that and
+ * go directly to Quick Mode. We are even willing to use one
+ * that is still being negotiated, but only if we are the Initiator
+ * (thus we can be sure that the IDs are not going to change;
+ * other issues around intent might matter).
+ * Note: there is no way to initiate with a Road Warrior.
+ */
+ struct state *st = find_phase1_state(c
+ , ISAKMP_SA_ESTABLISHED_STATES | PHASE1_INITIATOR_STATES);
+
+ if (st == NULL)
+ {
+ (void) main_outI1(whack_sock, c, NULL, policy, try);
+ }
+ else if (HAS_IPSEC_POLICY(policy))
{
- /* leave our Phase 2 negotiation pending */
- add_pending(whack_sock, st, c, policy, try, replacing);
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ /* leave our Phase 2 negotiation pending */
+ add_pending(whack_sock, st, c, policy, try, replacing);
+ }
+ else
+ {
+ /* ??? we assume that peer_nexthop_sin isn't important:
+ * we already have it from when we negotiated the ISAKMP SA!
+ * It isn't clear what to do with the error return.
+ */
+ (void) quick_outI1(whack_sock, st, c, policy, try, replacing);
+ }
}
else
{
- /* ??? we assume that peer_nexthop_sin isn't important:
- * we already have it from when we negotiated the ISAKMP SA!
- * It isn't clear what to do with the error return.
- */
- (void) quick_outI1(whack_sock, st, c, policy, try, replacing);
- }
- }
- else
- {
- close_any(whack_sock);
- }
+ close_any(whack_sock);
+ }
}
/* Replace SA with a fresh one that is similar
@@ -1115,221 +1090,264 @@ ipsecdoi_initiate(int whack_sock
* - duplicate whack fd, if live.
* Does not delete the old state -- someone else will do that.
*/
-void
-ipsecdoi_replace(struct state *st, unsigned long try)
+void ipsecdoi_replace(struct state *st, unsigned long try)
{
- int whack_sock = dup_any(st->st_whack_sock);
- lset_t policy = st->st_policy;
-
- if (IS_PHASE1(st->st_state))
- {
- passert(!HAS_IPSEC_POLICY(policy));
- (void) main_outI1(whack_sock, st->st_connection, st, policy, try);
- }
- else
- {
- /* Add features of actual old state to policy. This ensures
- * that rekeying doesn't downgrade security. I admit that
- * this doesn't capture everything.
- */
- if (st->st_pfs_group != NULL)
- policy |= POLICY_PFS;
- if (st->st_ah.present)
- {
- policy |= POLICY_AUTHENTICATE;
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
- }
- if (st->st_esp.present && st->st_esp.attrs.transid != ESP_NULL)
+ int whack_sock = dup_any(st->st_whack_sock);
+ lset_t policy = st->st_policy;
+
+ if (IS_PHASE1(st->st_state))
{
- policy |= POLICY_ENCRYPT;
- if (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
+ passert(!HAS_IPSEC_POLICY(policy));
+ (void) main_outI1(whack_sock, st->st_connection, st, policy, try);
}
- if (st->st_ipcomp.present)
+ else
{
- policy |= POLICY_COMPRESS;
- if (st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- policy |= POLICY_TUNNEL;
+ /* Add features of actual old state to policy. This ensures
+ * that rekeying doesn't downgrade security. I admit that
+ * this doesn't capture everything.
+ */
+ if (st->st_pfs_group != NULL)
+ policy |= POLICY_PFS;
+ if (st->st_ah.present)
+ {
+ policy |= POLICY_AUTHENTICATE;
+ if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ policy |= POLICY_TUNNEL;
+ }
+ if (st->st_esp.present && st->st_esp.attrs.transid != ESP_NULL)
+ {
+ policy |= POLICY_ENCRYPT;
+ if (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ policy |= POLICY_TUNNEL;
+ }
+ if (st->st_ipcomp.present)
+ {
+ policy |= POLICY_COMPRESS;
+ if (st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ policy |= POLICY_TUNNEL;
+ }
+ passert(HAS_IPSEC_POLICY(policy));
+ ipsecdoi_initiate(whack_sock, st->st_connection, policy, try
+ , st->st_serialno);
}
- passert(HAS_IPSEC_POLICY(policy));
- ipsecdoi_initiate(whack_sock, st->st_connection, policy, try
- , st->st_serialno);
- }
}
/* SKEYID for preshared keys.
* See draft-ietf-ipsec-ike-01.txt 4.1
*/
-static bool
-skeyid_preshared(struct state *st)
+static bool skeyid_preshared(struct state *st)
{
- const chunk_t *pss = get_preshared_secret(st->st_connection);
+ const chunk_t *pss = get_preshared_secret(st->st_connection);
- if (pss == NULL)
- {
- loglog(RC_LOG_SERIOUS, "preshared secret disappeared!");
- return FALSE;
- }
- else
- {
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, *pss);
- hmac_update_chunk(&ctx, st->st_ni);
- hmac_update_chunk(&ctx, st->st_nr);
- hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_preshared()", &ctx);
- return TRUE;
- }
+ if (pss == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "preshared secret disappeared!");
+ return FALSE;
+ }
+ else
+ {
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ if (prf == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
+ pseudo_random_function_names, prf_alg);
+ return FALSE;
+ }
+ free(st->st_skeyid.ptr);
+ prf->set_key(prf, *pss);
+ prf->allocate_bytes(prf, st->st_ni, NULL);
+ prf->allocate_bytes(prf, st->st_nr, &st->st_skeyid);
+ prf->destroy(prf);
+ return TRUE;
+ }
}
static bool
skeyid_digisig(struct state *st)
{
- struct hmac_ctx ctx;
- chunk_t nir;
-
- /* We need to hmac_init with the concatenation of Ni_b and Nr_b,
- * so we have to build a temporary concatentation.
- */
- nir.len = st->st_ni.len + st->st_nr.len;
- nir.ptr = alloc_bytes(nir.len, "Ni + Nr in skeyid_digisig");
- memcpy(nir.ptr, st->st_ni.ptr, st->st_ni.len);
- memcpy(nir.ptr+st->st_ni.len, st->st_nr.ptr, st->st_nr.len);
- hmac_init_chunk(&ctx, st->st_oakley.hasher, nir);
- pfree(nir.ptr);
-
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_final_chunk(st->st_skeyid, "st_skeyid in skeyid_digisig()", &ctx);
- return TRUE;
+ chunk_t nir;
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ if (prf == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%N not available to compute skeyid",
+ pseudo_random_function_names, prf_alg);
+ return FALSE;
+ }
+ free(st->st_skeyid.ptr);
+ nir = chunk_cat("cc", st->st_ni, st->st_nr);
+ prf->set_key(prf, nir);
+ prf->allocate_bytes(prf, st->st_shared, &st->st_skeyid);
+ prf->destroy(prf);
+ free(nir.ptr);
+ return TRUE;
}
/* Generate the SKEYID_* and new IV
* See draft-ietf-ipsec-ike-01.txt 4.1
*/
-static bool
-generate_skeyids_iv(struct state *st)
+static bool generate_skeyids_iv(struct state *st)
{
- /* Generate the SKEYID */
- switch (st->st_oakley.auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- if (!skeyid_preshared(st))
- return FALSE;
- break;
+ /* Generate the SKEYID */
+ switch (st->st_oakley.auth)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ if (!skeyid_preshared(st))
+ {
+ return FALSE;
+ }
+ break;
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- if (!skeyid_digisig(st))
- return FALSE;
- break;
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ if (!skeyid_digisig(st))
+ {
+ return FALSE;
+ }
+ break;
- case OAKLEY_DSS_SIG:
- /* XXX */
+ case OAKLEY_DSS_SIG:
+ /* XXX */
- case OAKLEY_RSA_ENC:
- case OAKLEY_RSA_ENC_REV:
- case OAKLEY_ELGAMAL_ENC:
- case OAKLEY_ELGAMAL_ENC_REV:
- /* XXX */
+ case OAKLEY_RSA_ENC:
+ case OAKLEY_RSA_ENC_REV:
+ case OAKLEY_ELGAMAL_ENC:
+ case OAKLEY_ELGAMAL_ENC_REV:
+ /* XXX */
- default:
- bad_case(st->st_oakley.auth);
- }
-
- /* generate SKEYID_* from SKEYID */
- {
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid);
-
- /* SKEYID_D */
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\0", 1);
- hmac_final_chunk(st->st_skeyid_d, "st_skeyid_d in generate_skeyids_iv()", &ctx);
-
- /* SKEYID_A */
- hmac_reinit(&ctx);
- hmac_update_chunk(&ctx, st->st_skeyid_d);
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\1", 1);
- hmac_final_chunk(st->st_skeyid_a, "st_skeyid_a in generate_skeyids_iv()", &ctx);
-
- /* SKEYID_E */
- hmac_reinit(&ctx);
- hmac_update_chunk(&ctx, st->st_skeyid_a);
- hmac_update_chunk(&ctx, st->st_shared);
- hmac_update(&ctx, st->st_icookie, COOKIE_SIZE);
- hmac_update(&ctx, st->st_rcookie, COOKIE_SIZE);
- hmac_update(&ctx, "\2", 1);
- hmac_final_chunk(st->st_skeyid_e, "st_skeyid_e in generate_skeyids_iv()", &ctx);
- }
-
- /* generate IV */
- {
- union hash_ctx hash_ctx;
- const struct hash_desc *h = st->st_oakley.hasher;
-
- st->st_new_iv_len = h->hash_digest_size;
- passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
+ default:
+ bad_case(st->st_oakley.auth);
+ }
+
+ /* generate SKEYID_* from SKEYID */
+ {
+ char buf_skeyid_d[] = { 0x00 };
+ char buf_skeyid_a[] = { 0x01 };
+ char buf_skeyid_e[] = { 0x02 };
+ chunk_t seed_skeyid_d = chunk_from_buf(buf_skeyid_d);
+ chunk_t seed_skeyid_a = chunk_from_buf(buf_skeyid_a);
+ chunk_t seed_skeyid_e = chunk_from_buf(buf_skeyid_e);
+ chunk_t icookie = { st->st_icookie, COOKIE_SIZE };
+ chunk_t rcookie = { st->st_rcookie, COOKIE_SIZE };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid);
+
+ /* SKEYID_D */
+ free(st->st_skeyid_d.ptr);
+ prf->allocate_bytes(prf, st->st_shared, NULL);
+ prf->allocate_bytes(prf, icookie, NULL);
+ prf->allocate_bytes(prf, rcookie, NULL);
+ prf->allocate_bytes(prf, seed_skeyid_d, &st->st_skeyid_d);
+
+ /* SKEYID_A */
+ free(st->st_skeyid_a.ptr);
+ prf->allocate_bytes(prf, st->st_skeyid_d, NULL);
+ prf->allocate_bytes(prf, st->st_shared, NULL);
+ prf->allocate_bytes(prf, icookie, NULL);
+ prf->allocate_bytes(prf, rcookie, NULL);
+ prf->allocate_bytes(prf, seed_skeyid_a, &st->st_skeyid_a);
+
+ /* SKEYID_E */
+ free(st->st_skeyid_e.ptr);
+ prf->allocate_bytes(prf, st->st_skeyid_a, NULL);
+ prf->allocate_bytes(prf, st->st_shared, NULL);
+ prf->allocate_bytes(prf, icookie, NULL);
+ prf->allocate_bytes(prf, rcookie, NULL);
+ prf->allocate_bytes(prf, seed_skeyid_e, &st->st_skeyid_e);
+
+ prf->destroy(prf);
+ }
+
+ /* generate IV */
+ {
+ hash_algorithm_t hash_alg;
+ hasher_t *hasher;
+
+ hash_alg = oakley_to_hash_algorithm(st->st_oakley.hash);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ st->st_new_iv_len = hasher->get_hash_size(hasher);
+ passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
+
+ DBG(DBG_CRYPT,
+ DBG_dump_chunk("DH_i:", st->st_gi);
+ DBG_dump_chunk("DH_r:", st->st_gr);
+ );
+
+ hasher->get_hash(hasher, st->st_gi, NULL);
+ hasher->get_hash(hasher, st->st_gr, st->st_new_iv);
+ hasher->destroy(hasher);
+ }
+
+ /* Oakley Keying Material
+ * Derived from Skeyid_e: if it is not big enough, generate more
+ * using the PRF.
+ * See RFC 2409 "IKE" Appendix B
+ */
+ {
+ size_t keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;
+
+ /* free any existing key */
+ free(st->st_enc_key.ptr);
+
+ if (keysize > st->st_skeyid_e.len)
+ {
+ u_char keytemp[MAX_OAKLEY_KEY_LEN + MAX_DIGEST_LEN];
+ char seed_buf[] = { 0x00 };
+ chunk_t seed = chunk_from_buf(seed_buf);
+ size_t prf_block_size, i;
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_e);
+ prf_block_size = prf->get_block_size(prf);
+
+ for (i = 0;;)
+ {
+ prf->get_bytes(prf, seed, &keytemp[i]);
+ i += prf_block_size;
+ if (i >= keysize)
+ {
+ break;
+ }
+ seed = chunk_create(&keytemp[i-prf_block_size], prf_block_size);
+ }
+ prf->destroy(prf);
+ st->st_enc_key = chunk_create(keytemp, keysize);
+ }
+ else
+ {
+ st->st_enc_key = chunk_create(st->st_skeyid_e.ptr, keysize);
+ }
+ st->st_enc_key = chunk_clone(st->st_enc_key);
+ }
- DBG(DBG_CRYPT,
- DBG_dump_chunk("DH_i:", st->st_gi);
- DBG_dump_chunk("DH_r:", st->st_gr);
- );
- h->hash_init(&hash_ctx);
- h->hash_update(&hash_ctx, st->st_gi.ptr, st->st_gi.len);
- h->hash_update(&hash_ctx, st->st_gr.ptr, st->st_gr.len);
- h->hash_final(st->st_new_iv, &hash_ctx);
- }
-
- /* Oakley Keying Material
- * Derived from Skeyid_e: if it is not big enough, generate more
- * using the PRF.
- * See RFC 2409 "IKE" Appendix B
- */
- {
- /* const size_t keysize = st->st_oakley.encrypter->keydeflen/BITS_PER_BYTE; */
- const size_t keysize = st->st_oakley.enckeylen/BITS_PER_BYTE;
- u_char keytemp[MAX_OAKLEY_KEY_LEN + MAX_DIGEST_LEN];
- u_char *k = st->st_skeyid_e.ptr;
-
- if (keysize > st->st_skeyid_e.len)
- {
- struct hmac_ctx ctx;
- size_t i = 0;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_e);
- hmac_update(&ctx, "\0", 1);
- for (;;)
- {
- hmac_final(&keytemp[i], &ctx);
- i += ctx.hmac_digest_size;
- if (i >= keysize)
- break;
- hmac_reinit(&ctx);
- hmac_update(&ctx, &keytemp[i - ctx.hmac_digest_size], ctx.hmac_digest_size);
- }
- k = keytemp;
- }
- clonereplacechunk(st->st_enc_key, k, keysize, "st_enc_key");
- }
-
- DBG(DBG_CRYPT,
- DBG_dump_chunk("Skeyid: ", st->st_skeyid);
- DBG_dump_chunk("Skeyid_d:", st->st_skeyid_d);
- DBG_dump_chunk("Skeyid_a:", st->st_skeyid_a);
- DBG_dump_chunk("Skeyid_e:", st->st_skeyid_e);
- DBG_dump_chunk("enc key:", st->st_enc_key);
- DBG_dump("IV:", st->st_new_iv, st->st_new_iv_len));
- return TRUE;
+ DBG(DBG_CRYPT,
+ DBG_dump_chunk("Skeyid: ", st->st_skeyid);
+ DBG_dump_chunk("Skeyid_d:", st->st_skeyid_d);
+ DBG_dump_chunk("Skeyid_a:", st->st_skeyid_a);
+ DBG_dump_chunk("Skeyid_e:", st->st_skeyid_e);
+ DBG_dump_chunk("enc key:", st->st_enc_key);
+ DBG_dump("IV:", st->st_new_iv, st->st_new_iv_len));
+ return TRUE;
}
/* Generate HASH_I or HASH_R for ISAKMP Phase I.
@@ -1338,288 +1356,126 @@ generate_skeyids_iv(struct state *st)
* If the hashi argument is TRUE, generate HASH_I; if FALSE generate HASH_R.
* If hashus argument is TRUE, we're generating a hash for our end.
* See RFC2409 IKE 5.
- *
- * Generating the SIG_I and SIG_R for DSS is an odd perversion of this:
- * Most of the logic is the same, but SHA-1 is used in place of HMAC-whatever.
- * The extensive common logic is embodied in main_mode_hash_body().
- * See draft-ietf-ipsec-ike-01.txt 4.1 and 6.1.1.2
*/
-
-typedef void (*hash_update_t)(union hash_ctx *, const u_char *, size_t) ;
-static void
-main_mode_hash_body(struct state *st
-, bool hashi /* Initiator? */
-, const pb_stream *idpl /* ID payload, as PBS */
-, union hash_ctx *ctx
-, void (*hash_update_void)(void *, const u_char *input, size_t))
+ static void main_mode_hash(struct state *st, chunk_t *hash, bool hashi,
+ const pb_stream *idpl)
{
-#define HASH_UPDATE_T (union hash_ctx *, const u_char *input, unsigned int len)
- hash_update_t hash_update=(hash_update_t) hash_update_void;
-#if 0 /* if desperate to debug hashing */
-# define hash_update(ctx, input, len) { \
- DBG_dump("hash input", input, len); \
- (hash_update)(ctx, input, len); \
+ chunk_t icookie = { st->st_icookie, COOKIE_SIZE };
+ chunk_t rcookie = { st->st_rcookie, COOKIE_SIZE };
+ chunk_t sa_body = { st->st_p1isa.ptr + sizeof(struct isakmp_generic),
+ st->st_p1isa.len - sizeof(struct isakmp_generic) };
+ chunk_t id_body = { idpl->start + sizeof(struct isakmp_generic),
+ pbs_offset(idpl) - sizeof(struct isakmp_generic) };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ switch (st->st_oakley.auth)
+ {
+ case OAKLEY_ECDSA_256:
+ prf_alg = PRF_HMAC_SHA2_256;
+ break;
+ case OAKLEY_ECDSA_384:
+ prf_alg = PRF_HMAC_SHA2_384;
+ break;
+ case OAKLEY_ECDSA_521:
+ prf_alg = PRF_HMAC_SHA2_512;
+ break;
+ default:
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
}
-#endif
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid);
-# define hash_update_chunk(ctx, ch) hash_update((ctx), (ch).ptr, (ch).len)
-
- if (hashi)
- {
- hash_update_chunk(ctx, st->st_gi);
- hash_update_chunk(ctx, st->st_gr);
- hash_update(ctx, st->st_icookie, COOKIE_SIZE);
- hash_update(ctx, st->st_rcookie, COOKIE_SIZE);
- }
- else
- {
- hash_update_chunk(ctx, st->st_gr);
- hash_update_chunk(ctx, st->st_gi);
- hash_update(ctx, st->st_rcookie, COOKIE_SIZE);
- hash_update(ctx, st->st_icookie, COOKIE_SIZE);
- }
-
- DBG(DBG_CRYPT, DBG_log("hashing %lu bytes of SA"
- , (unsigned long) (st->st_p1isa.len - sizeof(struct isakmp_generic))));
-
- /* SA_b */
- hash_update(ctx, st->st_p1isa.ptr + sizeof(struct isakmp_generic)
- , st->st_p1isa.len - sizeof(struct isakmp_generic));
-
- /* Hash identification payload, without generic payload header.
- * We used to reconstruct ID Payload for this purpose, but now
- * we use the bytes as they appear on the wire to avoid
- * "spelling problems".
- */
- hash_update(ctx
- , idpl->start + sizeof(struct isakmp_generic)
- , pbs_offset(idpl) - sizeof(struct isakmp_generic));
-
-# undef hash_update_chunk
-# undef hash_update
-}
-
-static size_t /* length of hash */
-main_mode_hash(struct state *st
-, u_char *hash_val /* resulting bytes */
-, bool hashi /* Initiator? */
-, const pb_stream *idpl) /* ID payload, as PBS; cur must be at end */
-{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid);
- main_mode_hash_body(st, hashi, idpl, &ctx.hash_ctx, ctx.h->hash_update);
- hmac_final(hash_val, &ctx);
- return ctx.hmac_digest_size;
-}
-
-#if 0 /* only needed for DSS */
-static void
-main_mode_sha1(struct state *st
-, u_char *hash_val /* resulting bytes */
-, size_t *hash_len /* length of hash */
-, bool hashi /* Initiator? */
-, const pb_stream *idpl) /* ID payload, as PBS */
-{
- union hash_ctx ctx;
-
- SHA1Init(&ctx.ctx_sha1);
- SHA1Update(&ctx.ctx_sha1, st->st_skeyid.ptr, st->st_skeyid.len);
- *hash_len = SHA1_DIGEST_SIZE;
- main_mode_hash_body(st, hashi, idpl, &ctx
- , (void (*)(union hash_ctx *, const u_char *, unsigned int))&SHA1Update);
- SHA1Final(hash_val, &ctx.ctx_sha1);
-}
-#endif
-
-/* Create an RSA signature of a hash.
- * Poorly specified in draft-ietf-ipsec-ike-01.txt 6.1.1.2.
- * Use PKCS#1 version 1.5 encryption of hash (called
- * RSAES-PKCS1-V1_5) in PKCS#2.
- */
-static size_t
-RSA_sign_hash(struct connection *c
-, u_char sig_val[RSA_MAX_OCTETS]
-, const u_char *hash_val, size_t hash_len)
-{
- size_t sz = 0;
- smartcard_t *sc = c->spd.this.sc;
-
- if (sc == NULL) /* no smartcard */
- {
- const struct RSA_private_key *k = get_RSA_private_key(c);
-
- if (k == NULL)
- return 0; /* failure: no key to use */
-
- sz = k->pub.k;
- passert(RSA_MIN_OCTETS <= sz && 4 + hash_len < sz && sz <= RSA_MAX_OCTETS);
- sign_hash(k, hash_val, hash_len, sig_val, sz);
- }
- else if (sc->valid) /* if valid pin then sign hash on the smartcard */
- {
- lock_certs_and_keys("RSA_sign_hash");
- if (!scx_establish_context(sc) || !scx_login(sc))
+ if (hashi)
{
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- return 0;
+ prf->get_bytes(prf, st->st_gi, NULL);
+ prf->get_bytes(prf, st->st_gr, NULL);
+ prf->get_bytes(prf, icookie, NULL);
+ prf->get_bytes(prf, rcookie, NULL);
}
-
- sz = scx_get_keylength(sc);
- if (sz == 0)
+ else
{
- plog("failed to get keylength from smartcard");
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- return 0;
+ prf->get_bytes(prf, st->st_gr, NULL);
+ prf->get_bytes(prf, st->st_gi, NULL);
+ prf->get_bytes(prf, rcookie, NULL);
+ prf->get_bytes(prf, icookie, NULL);
}
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
+ DBG(DBG_CRYPT,
+ DBG_log("hashing %u bytes of SA", sa_body.len)
)
- sz = scx_sign_hash(sc, hash_val, hash_len, sig_val, sz) ? sz : 0;
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- unlock_certs_and_keys("RSA_sign_hash");
- }
- return sz;
+ prf->get_bytes(prf, sa_body, NULL);
+
+ /* Hash identification payload, without generic payload header.
+ * We used to reconstruct ID Payload for this purpose, but now
+ * we use the bytes as they appear on the wire to avoid
+ * "spelling problems".
+ */
+ prf->get_bytes(prf, id_body, hash->ptr);
+ hash->len = prf->get_block_size(prf);
+ prf->destroy(prf);
}
-/* Check a Main Mode RSA Signature against computed hash using RSA public key k.
- *
- * As a side effect, on success, the public key is copied into the
- * state object to record the authenticator.
- *
- * Can fail because wrong public key is used or because hash disagrees.
- * We distinguish because diagnostics should also.
- *
- * The result is NULL if the Signature checked out.
- * Otherwise, the first character of the result indicates
- * how far along failure occurred. A greater character signifies
- * greater progress.
- *
- * Classes:
- * 0 reserved for caller
- * 1 SIG length doesn't match key length -- wrong key
- * 2-8 malformed ECB after decryption -- probably wrong key
- * 9 decrypted hash != computed hash -- probably correct key
- *
- * Although the math should be the same for generating and checking signatures,
- * it is not: the knowledge of the private key allows more efficient (i.e.
- * different) computation for encryption.
+/* Create a public key signature of a hash.
+ * Poorly specified in draft-ietf-ipsec-ike-01.txt 6.1.1.2.
+ * Use PKCS#1 version 1.5 encryption of hash (called
+ * RSAES-PKCS1-V1_5) in PKCS#2.
*/
-static err_t
-try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN], size_t hash_len
-, const pb_stream *sig_pbs, pubkey_t *kr
-, struct state *st)
+static size_t sign_hash(signature_scheme_t scheme, struct connection *c,
+ u_char sig_val[RSA_MAX_OCTETS], chunk_t hash)
{
- const u_char *sig_val = sig_pbs->cur;
- size_t sig_len = pbs_left(sig_pbs);
- u_char s[RSA_MAX_OCTETS]; /* for decrypted sig_val */
- u_char *hash_in_s = &s[sig_len - hash_len];
- const struct RSA_public_key *k = &kr->u.rsa;
-
- /* decrypt the signature -- reversing RSA_sign_hash */
- if (sig_len != k->k)
- {
- /* XXX notification: INVALID_KEY_INFORMATION */
- return "1" "SIG length does not match public key length";
- }
-
- /* actual exponentiation; see PKCS#1 v2.0 5.1 */
- {
- chunk_t temp_s;
- mpz_t c;
-
- n_to_mpz(c, sig_val, sig_len);
- mpz_powm(c, c, &k->e, &k->n);
-
- temp_s = mpz_to_n(c, sig_len); /* back to octets */
- memcpy(s, temp_s.ptr, sig_len);
- pfree(temp_s.ptr);
- mpz_clear(c);
- }
-
- /* sanity check on signature: see if it matches
- * PKCS#1 v1.5 8.1 encryption-block formatting
- */
- {
- err_t ugh = NULL;
+ size_t sz = 0;
+ smartcard_t *sc = c->spd.this.sc;
- if (s[0] != 0x00)
- ugh = "2" "no leading 00";
- else if (hash_in_s[-1] != 0x00)
- ugh = "3" "00 separator not present";
- else if (s[1] == 0x01)
+ if (sc == NULL) /* no smartcard */
{
- const u_char *p;
+ chunk_t sig;
+ private_key_t *private = get_private_key(c);
- for (p = &s[2]; p != hash_in_s - 1; p++)
- {
- if (*p != 0xFF)
+ if (private == NULL)
{
- ugh = "4" "invalid Padding String";
- break;
+ return 0; /* failure: no key to use */
}
- }
+ if (!private->sign(private, scheme, hash, &sig))
+ {
+ return 0;
+ }
+ memcpy(sig_val, sig.ptr, sig.len);
+ sz = sig.len;
+ free(sig.ptr);
}
- else if (s[1] == 0x02)
+ else if (sc->valid) /* if valid pin then sign hash on the smartcard */
{
- const u_char *p;
+ lock_certs_and_keys("sign_hash");
+ if (!scx_establish_context(sc) || !scx_login(sc))
+ {
+ scx_release_context(sc);
+ unlock_certs_and_keys("sign_hash");
+ return 0;
+ }
- for (p = &s[2]; p != hash_in_s - 1; p++)
- {
- if (*p == 0x00)
+ sz = scx_get_keylength(sc);
+ if (sz == 0)
{
- ugh = "5" "invalid Padding String";
- break;
+ plog("failed to get keylength from smartcard");
+ scx_release_context(sc);
+ unlock_certs_and_keys("sign_hash");
+ return 0;
}
- }
- }
- else
- ugh = "6" "Block Type not 01 or 02";
- if (ugh != NULL)
- {
- /* note: it might be a good idea to make sure that
- * an observer cannot tell what kind of failure happened.
- * I don't know what this means in practice.
- */
- /* We probably selected the wrong public key for peer:
- * SIG Payload decrypted into malformed ECB
- */
- /* XXX notification: INVALID_KEY_INFORMATION */
- return ugh;
- }
- }
-
- /* We have the decoded hash: see if it matches. */
- if (memcmp(hash_val, hash_in_s, hash_len) != 0)
- {
- /* good: header, hash, signature, and other payloads well-formed
- * good: we could find an RSA Sig key for the peer.
- * bad: hash doesn't match
- * Guess: sides disagree about key to be used.
- */
- DBG_cond_dump(DBG_CRYPT, "decrypted SIG", s, sig_len);
- DBG_cond_dump(DBG_CRYPT, "computed HASH", hash_val, hash_len);
- /* XXX notification: INVALID_HASH_INFORMATION */
- return "9" "authentication failure: received SIG does not match computed HASH, but message is well-formed";
- }
-
- /* Success: copy successful key into state.
- * There might be an old one if we previously aborted this
- * state transition.
- */
- unreference_key(&st->st_peer_pubkey);
- st->st_peer_pubkey = reference_key(kr);
-
- return NULL; /* happy happy */
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("signing hash with private key from smartcard (slot: %d, id: %s)"
+ , (int)sc->slot, sc->id)
+ )
+ sz = scx_sign_hash(sc, hash.ptr, hash.len, sig_val, sz) ? sz : 0;
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
+ unlock_certs_and_keys("sign_hash");
+ }
+ return sz;
}
-/* Check signature against all RSA public keys we can find.
+/* Check signature against all public keys we can find.
* If we need keys from DNS KEY records, and they haven't been fetched,
* return STF_SUSPEND to ask for asynch DNS lookup.
*
@@ -1630,227 +1486,195 @@ try_RSA_signature(const u_char hash_val[MAX_DIGEST_LEN], size_t hash_len
* If only we had coroutines.
*/
struct tac_state {
- /* RSA_check_signature's args that take_a_crack needs */
- struct state *st;
- const u_char *hash_val;
- size_t hash_len;
- const pb_stream *sig_pbs;
-
- /* state carried between calls */
- err_t best_ugh; /* most successful failure */
- int tried_cnt; /* number of keys tried */
- char tried[50]; /* keyids of tried public keys */
- char *tn; /* roof of tried[] */
+ struct state *st;
+ chunk_t hash;
+ chunk_t sig;
+ int tried_cnt; /* number of keys tried */
};
-static bool
-take_a_crack(struct tac_state *s
-, pubkey_t *kr
-, const char *story USED_BY_DEBUG)
+static bool take_a_crack(struct tac_state *s, pubkey_t *kr)
{
- err_t ugh = try_RSA_signature(s->hash_val, s->hash_len, s->sig_pbs
- , kr, s->st);
- const struct RSA_public_key *k = &kr->u.rsa;
-
- s->tried_cnt++;
- if (ugh == NULL)
- {
- DBG(DBG_CRYPT | DBG_CONTROL
- , DBG_log("an RSA Sig check passed with *%s [%s]"
- , k->keyid, story));
- return TRUE;
- }
- else
- {
- DBG(DBG_CRYPT
- , DBG_log("an RSA Sig check failure %s with *%s [%s]"
- , ugh + 1, k->keyid, story));
- if (s->best_ugh == NULL || s->best_ugh[0] < ugh[0])
- s->best_ugh = ugh;
- if (ugh[0] > '0'
- && s->tn - s->tried + KEYID_BUF + 2 < (ptrdiff_t)sizeof(s->tried))
- {
- strcpy(s->tn, " *");
- strcpy(s->tn + 2, k->keyid);
- s->tn += strlen(s->tn);
+ public_key_t *pub_key = kr->public_key;
+ identification_t *keyid = pub_key->get_id(pub_key, ID_PUBKEY_INFO_SHA1);
+ signature_scheme_t scheme;
+
+ s->tried_cnt++;
+ scheme = oakley_to_signature_scheme(s->st->st_oakley.auth);
+
+ if (pub_key->verify(pub_key, scheme, s->hash, s->sig))
+ {
+ DBG(DBG_CRYPT | DBG_CONTROL,
+ DBG_log("%s check passed with keyid %Y",
+ enum_show(&oakley_auth_names, s->st->st_oakley.auth), keyid)
+ )
+ unreference_key(&s->st->st_peer_pubkey);
+ s->st->st_peer_pubkey = reference_key(kr);
+ return TRUE;
+ }
+ else
+ {
+ DBG(DBG_CRYPT,
+ DBG_log("%s check failed with keyid %Y",
+ enum_show(&oakley_auth_names, s->st->st_oakley.auth), keyid)
+ )
+ return FALSE;
}
- return FALSE;
- }
}
-static stf_status
-RSA_check_signature(const struct id* peer
-, struct state *st
-, const u_char hash_val[MAX_DIGEST_LEN]
-, size_t hash_len
-, const pb_stream *sig_pbs
+static stf_status check_signature(key_type_t key_type, const struct id* peer,
+ struct state *st, chunk_t hash,
+ const pb_stream *sig_pbs,
#ifdef USE_KEYRR
-, const pubkey_list_t *keys_from_dns
+ const pubkey_list_t *keys_from_dns,
#endif /* USE_KEYRR */
-, const struct gw_info *gateways_from_dns
-)
+ const struct gw_info *gateways_from_dns)
{
- const struct connection *c = st->st_connection;
- struct tac_state s;
- err_t dns_ugh = NULL;
-
- s.st = st;
- s.hash_val = hash_val;
- s.hash_len = hash_len;
- s.sig_pbs = sig_pbs;
-
- s.best_ugh = NULL;
- s.tried_cnt = 0;
- s.tn = s.tried;
-
- /* try all gateway records hung off c */
- if (c->policy & POLICY_OPPO)
- {
- struct gw_info *gw;
-
- for (gw = c->gw_info; gw != NULL; gw = gw->next)
- {
- /* only consider entries that have a key and are for our peer */
- if (gw->gw_key_present
- && same_id(&gw->gw_id, &c->spd.that.id)
- && take_a_crack(&s, gw->key, "key saved from DNS TXT"))
- return STF_OK;
- }
- }
+ const struct connection *c = st->st_connection;
+ struct tac_state s;
- /* try all appropriate Public keys */
- {
- pubkey_list_t *p, **pp;
+ s.st = st;
+ s.hash = hash;
+ s.sig = chunk_create(sig_pbs->cur, pbs_left(sig_pbs));
+ s.tried_cnt = 0;
- pp = &pubkeys;
+ /* try all gateway records hung off c */
+ if (c->policy & POLICY_OPPO)
+ {
+ struct gw_info *gw;
- for (p = pubkeys; p != NULL; p = *pp)
+ for (gw = c->gw_info; gw != NULL; gw = gw->next)
+ {
+ /* only consider entries that have a key and are for our peer */
+ if (gw->gw_key_present && same_id(&gw->gw_id, &c->spd.that.id)&&
+ take_a_crack(&s, gw->key))
+ {
+ return STF_OK;
+ }
+ }
+ }
+
+ /* try all appropriate Public keys */
{
- pubkey_t *key = p->key;
+ pubkey_list_t *p, **pp;
- if (key->alg == PUBKEY_ALG_RSA && same_id(peer, &key->id))
- {
- time_t now = time(NULL);
+ pp = &pubkeys;
- /* check if found public key has expired */
- if (key->until_time != UNDEFINED_TIME && key->until_time < now)
+ for (p = pubkeys; p != NULL; p = *pp)
{
- loglog(RC_LOG_SERIOUS,
- "cached RSA public key has expired and has been deleted");
- *pp = free_public_keyentry(p);
- continue; /* continue with next public key */
- }
+ pubkey_t *key = p->key;
+ key_type_t type = key->public_key->get_type(key->public_key);
- if (take_a_crack(&s, key, "preloaded key"))
- return STF_OK;
- }
- pp = &p->next;
- }
+ if (type == key_type && same_id(peer, &key->id))
+ {
+ time_t now = time(NULL);
+
+ /* check if found public key has expired */
+ if (key->until_time != UNDEFINED_TIME && key->until_time < now)
+ {
+ loglog(RC_LOG_SERIOUS,
+ "cached public key has expired and has been deleted");
+ *pp = free_public_keyentry(p);
+ continue; /* continue with next public key */
+ }
+
+ if (take_a_crack(&s, key))
+ {
+ return STF_OK;
+ }
+ }
+ pp = &p->next;
+ }
}
- /* if no key was found (evidenced by best_ugh == NULL)
- * and that side of connection is key_from_DNS_on_demand
- * then go search DNS for keys for peer.
- */
- if (s.best_ugh == NULL && c->spd.that.key_from_DNS_on_demand)
- {
- if (gateways_from_dns != NULL)
+ /* if no key was found and that side of connection is
+ * key_from_DNS_on_demand then go search DNS for keys for peer.
+ */
+ if (s.tried_cnt == 0 && c->spd.that.key_from_DNS_on_demand)
{
- /* TXT keys */
- const struct gw_info *gwp;
+ if (gateways_from_dns != NULL)
+ {
+ /* TXT keys */
+ const struct gw_info *gwp;
- for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
- if (gwp->gw_key_present
- && take_a_crack(&s, gwp->key, "key from DNS TXT"))
- return STF_OK;
- }
+ for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ if (gwp->gw_key_present && take_a_crack(&s, gwp->key))
+ {
+ return STF_OK;
+ }
+ }
+ }
#ifdef USE_KEYRR
- else if (keys_from_dns != NULL)
- {
- /* KEY keys */
- const pubkey_list_t *kr;
+ else if (keys_from_dns != NULL)
+ {
+ /* KEY keys */
+ const pubkey_list_t *kr;
- for (kr = keys_from_dns; kr != NULL; kr = kr->next)
- if (kr->key->alg == PUBKEY_ALG_RSA
- && take_a_crack(&s, kr->key, "key from DNS KEY"))
- return STF_OK;
- }
+ for (kr = keys_from_dns; kr != NULL; kr = kr->next)
+ {
+ if (kr->key->alg == PUBKEY_ALG_RSA && take_a_crack(&s, kr->key))
+ {
+ return STF_OK;
+ }
+ }
+ }
#endif /* USE_KEYRR */
- else
- {
- /* nothing yet: ask for asynch DNS lookup */
- return STF_SUSPEND;
+ else
+ {
+ /* nothing yet: ask for asynch DNS lookup */
+ return STF_SUSPEND;
+ }
}
- }
-
- /* no acceptable key was found: diagnose */
- {
- char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
- (void) idtoa(peer, id_buf, sizeof(id_buf));
-
- if (s.best_ugh == NULL)
+ /* no acceptable key was found: diagnose */
{
- if (dns_ugh == NULL)
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- , id_buf);
- else
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- "; DNS search for KEY failed (%s)"
- , id_buf, dns_ugh);
+ char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
- /* ??? is this the best code there is? */
- return STF_FAIL + INVALID_KEY_INFORMATION;
- }
+ idtoa(peer, id_buf, sizeof(id_buf));
- if (s.best_ugh[0] == '9')
- {
- loglog(RC_LOG_SERIOUS, "%s", s.best_ugh + 1);
- /* XXX Could send notification back */
- return STF_FAIL + INVALID_HASH_INFORMATION;
- }
- else
- {
- if (s.tried_cnt == 1)
- {
- loglog(RC_LOG_SERIOUS
- , "Signature check (on %s) failed (wrong key?); tried%s"
- , id_buf, s.tried);
- DBG(DBG_CONTROL,
- DBG_log("public key for %s failed:"
- " decrypted SIG payload into a malformed ECB (%s)"
- , id_buf, s.best_ugh + 1));
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "Signature check (on %s) failed:"
- " tried%s keys but none worked."
- , id_buf, s.tried);
- DBG(DBG_CONTROL,
- DBG_log("all %d public keys for %s failed:"
- " best decrypted SIG payload into a malformed ECB (%s)"
- , s.tried_cnt, id_buf, s.best_ugh + 1));
- }
- return STF_FAIL + INVALID_KEY_INFORMATION;
+ if (s.tried_cnt == 0)
+ {
+ loglog(RC_LOG_SERIOUS, "no public key known for '%s'", id_buf);
+ }
+ else if (s.tried_cnt == 1)
+ {
+ loglog(RC_LOG_SERIOUS, "signature check for '%s' failed: "
+ " wrong key?; tried %d", id_buf, s.tried_cnt);
+ DBG(DBG_CONTROL,
+ DBG_log("public key for '%s' failed: "
+ "decrypted SIG payload into a malformed ECB", id_buf)
+ )
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "signature check for '%s' failed: "
+ "tried %d keys but none worked.", id_buf, s.tried_cnt);
+ DBG(DBG_CONTROL,
+ DBG_log("all %d public keys for '%s' failed: "
+ "best decrypted SIG payload into a malformed ECB",
+ s.tried_cnt, id_buf)
+ )
+ }
+ return STF_FAIL + INVALID_KEY_INFORMATION;
}
- }
}
-static notification_t
-accept_nonce(struct msg_digest *md, chunk_t *dest, const char *name)
+static notification_t accept_nonce(struct msg_digest *md, chunk_t *dest,
+ const char *name)
{
- pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
- size_t len = pbs_left(nonce_pbs);
-
- if (len < MINIMUM_NONCE_SIZE || MAXIMUM_NONCE_SIZE < len)
- {
- loglog(RC_LOG_SERIOUS, "%s length not between %d and %d"
- , name , MINIMUM_NONCE_SIZE, MAXIMUM_NONCE_SIZE);
- return PAYLOAD_MALFORMED; /* ??? */
- }
- clonereplacechunk(*dest, nonce_pbs->cur, len, "nonce");
- return NOTHING_WRONG;
+ pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_NONCE]->pbs;
+ size_t len = pbs_left(nonce_pbs);
+
+ if (len < MINIMUM_NONCE_SIZE || MAXIMUM_NONCE_SIZE < len)
+ {
+ loglog(RC_LOG_SERIOUS, "%s length not between %d and %d"
+ , name , MINIMUM_NONCE_SIZE, MAXIMUM_NONCE_SIZE);
+ return PAYLOAD_MALFORMED; /* ??? */
+ }
+ free(dest->ptr);
+ *dest = chunk_create(nonce_pbs->cur, len);
+ *dest = chunk_clone(*dest);
+ return NOTHING_WRONG;
}
/* encrypt message, sans fixed part of header
@@ -1861,36 +1685,51 @@ accept_nonce(struct msg_digest *md, chunk_t *dest, const char *name)
bool
encrypt_message(pb_stream *pbs, struct state *st)
{
- const struct encrypt_desc *e = st->st_oakley.encrypter;
- u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
- size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
-
- DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
-
- /* Pad up to multiple of encryption blocksize.
- * See the description associated with the definition of
- * struct isakmp_hdr in packet.h.
- */
- {
- size_t padding = pad_up(enc_len, e->enc_blocksize);
-
- if (padding != 0)
+ u_int8_t *enc_start = pbs->start + sizeof(struct isakmp_hdr);
+ size_t enc_len = pbs_offset(pbs) - sizeof(struct isakmp_hdr);
+ chunk_t data, iv;
+ char *new_iv;
+ size_t crypter_block_size;
+ encryption_algorithm_t enc_alg;
+ crypter_t *crypter;
+
+ DBG_cond_dump(DBG_CRYPT | DBG_RAW, "encrypting:\n", enc_start, enc_len);
+ enc_alg = oakley_to_encryption_algorithm(st->st_oakley.encrypt);
+ crypter = lib->crypto->create_crypter(lib->crypto, enc_alg, st->st_enc_key.len);
+ crypter_block_size = crypter->get_block_size(crypter);
+
+ /* Pad up to multiple of encryption blocksize.
+ * See the description associated with the definition of
+ * struct isakmp_hdr in packet.h.
+ */
{
- if (!out_zero(padding, pbs, "encryption padding"))
- return FALSE;
- enc_len += padding;
+ size_t padding = pad_up(enc_len, crypter_block_size);
+
+ if (padding != 0)
+ {
+ if (!out_zero(padding, pbs, "encryption padding"))
+ return FALSE;
+ enc_len += padding;
+ }
}
- }
- DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
+ DBG(DBG_CRYPT, DBG_log("encrypting using %s", enum_show(&oakley_enc_names, st->st_oakley.encrypt)));
+ data = chunk_create(enc_start, enc_len);
- /* e->crypt(TRUE, enc_start, enc_len, st); */
- crypto_cbc_encrypt(e, TRUE, enc_start, enc_len, st);
+ /* form iv by truncation */
+ st->st_new_iv_len = crypter_block_size;
+ iv = chunk_create(st->st_new_iv, st->st_new_iv_len);
- update_iv(st);
- DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
- close_message(pbs);
- return TRUE;
+ crypter->set_key(crypter, st->st_enc_key);
+ crypter->encrypt(crypter, data, iv, NULL);
+ crypter->destroy(crypter);
+
+ new_iv = data.ptr + data.len - crypter_block_size;
+ memcpy(st->st_new_iv, new_iv, crypter_block_size);
+ update_iv(st);
+ DBG_cond_dump(DBG_CRYPT, "next IV:", st->st_iv, st->st_iv_len);
+ close_message(pbs);
+ return TRUE;
}
/* Compute HASH(1), HASH(2) of Quick Mode.
@@ -1899,31 +1738,33 @@ encrypt_message(pb_stream *pbs, struct state *st)
* Used by: quick_outI1, quick_inI1_outR1 (twice), quick_inR1_outI2
* (see RFC 2409 "IKE" 5.5, pg. 18 or draft-ietf-ipsec-ike-01.txt 6.2 pg 25)
*/
-static size_t
-quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
-, const struct state *st, const msgid_t *msgid, bool hash2)
+static size_t quick_mode_hash12(u_char *dest, u_char *start, u_char *roof,
+ const struct state *st, const msgid_t *msgid,
+ bool hash2)
{
- struct hmac_ctx ctx;
-
-#if 0 /* if desperate to debug hashing */
-# define hmac_update(ctx, ptr, len) { \
- DBG_dump("hash input", (ptr), (len)); \
- (hmac_update)((ctx), (ptr), (len)); \
- }
- DBG_dump("hash key", st->st_skeyid_a.ptr, st->st_skeyid_a.len);
-#endif
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const void *) msgid, sizeof(msgid_t));
- if (hash2)
- hmac_update_chunk(&ctx, st->st_ni); /* include Ni_b in the hash */
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH(%d) computed:", hash2 + 1);
- DBG_dump("", dest, ctx.hmac_digest_size));
- return ctx.hmac_digest_size;
-# undef hmac_update
+ chunk_t msgid_chunk = chunk_from_thing(*msgid);
+ chunk_t msg_chunk = { start, roof - start };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+ size_t prf_block_size;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ if (hash2)
+ {
+ prf->get_bytes(prf, st->st_ni, NULL); /* include Ni_b in the hash */
+ }
+ prf->get_bytes(prf, msg_chunk, dest);
+ prf_block_size = prf->get_block_size(prf);
+ prf->destroy(prf);
+
+ DBG(DBG_CRYPT,
+ DBG_log("HASH(%d) computed:", hash2 + 1);
+ DBG_dump("", dest, prf_block_size)
+ )
+ return prf_block_size;
}
/* Compute HASH(3) in Quick Mode (part of Quick I2 message).
@@ -1932,44 +1773,54 @@ quick_mode_hash12(u_char *dest, const u_char *start, const u_char *roof
* NOTE: this hash (unlike HASH(1) and HASH(2)) ONLY covers the
* Message ID and Nonces. This is a mistake.
*/
-static size_t
-quick_mode_hash3(u_char *dest, struct state *st)
+static size_t quick_mode_hash3(u_char *dest, struct state *st)
{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, "\0", 1);
- hmac_update(&ctx, (u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update_chunk(&ctx, st->st_ni);
- hmac_update_chunk(&ctx, st->st_nr);
- hmac_final(dest, &ctx);
- DBG_cond_dump(DBG_CRYPT, "HASH(3) computed:", dest, ctx.hmac_digest_size);
- return ctx.hmac_digest_size;
+ char seed_buf[] = { 0x00 };
+ chunk_t seed_chunk = chunk_from_buf(seed_buf);
+ chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+ size_t prf_block_size;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_a);
+ prf->get_bytes(prf, seed_chunk, NULL );
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, st->st_ni, NULL);
+ prf->get_bytes(prf, st->st_nr, dest);
+ prf_block_size = prf->get_block_size(prf);
+ prf->destroy(prf);
+
+ DBG_cond_dump(DBG_CRYPT, "HASH(3) computed:", dest, prf_block_size);
+ return prf_block_size;
}
/* Compute Phase 2 IV.
* Uses Phase 1 IV from st_iv; puts result in st_new_iv.
*/
-void
-init_phase2_iv(struct state *st, const msgid_t *msgid)
+void init_phase2_iv(struct state *st, const msgid_t *msgid)
{
- const struct hash_desc *h = st->st_oakley.hasher;
- union hash_ctx ctx;
+ chunk_t iv_chunk = { st->st_ph1_iv, st->st_ph1_iv_len };
+ chunk_t msgid_chunk = chunk_from_thing(*msgid);
+ hash_algorithm_t hash_alg;
+ hasher_t *hasher;
- DBG_cond_dump(DBG_CRYPT, "last Phase 1 IV:"
- , st->st_ph1_iv, st->st_ph1_iv_len);
+ hash_alg = oakley_to_hash_algorithm(st->st_oakley.hash);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
- st->st_new_iv_len = h->hash_digest_size;
- passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
+ DBG_cond_dump(DBG_CRYPT, "last Phase 1 IV:",
+ st->st_ph1_iv, st->st_ph1_iv_len);
- h->hash_init(&ctx);
- h->hash_update(&ctx, st->st_ph1_iv, st->st_ph1_iv_len);
- passert(*msgid != 0);
- h->hash_update(&ctx, (const u_char *)msgid, sizeof(*msgid));
- h->hash_final(st->st_new_iv, &ctx);
+ st->st_new_iv_len = hasher->get_hash_size(hasher);
+ passert(st->st_new_iv_len <= sizeof(st->st_new_iv));
+
+ hasher->get_hash(hasher, iv_chunk, NULL);
+ hasher->get_hash(hasher, msgid_chunk, st->st_new_iv);
+ hasher->destroy(hasher);
- DBG_cond_dump(DBG_CRYPT, "computed Phase 2 IV:"
- , st->st_new_iv, st->st_new_iv_len);
+ DBG_cond_dump(DBG_CRYPT, "computed Phase 2 IV:",
+ st->st_new_iv, st->st_new_iv_len);
}
/* Initiate quick mode.
@@ -1978,474 +1829,467 @@ init_phase2_iv(struct state *st, const msgid_t *msgid)
* Note: this is not called from demux.c
*/
-static bool
-emit_subnet_id(ip_subnet *net
-, u_int8_t np, u_int8_t protoid, u_int16_t port, pb_stream *outs)
+static bool emit_subnet_id(ip_subnet *net, u_int8_t np, u_int8_t protoid,
+ u_int16_t port, pb_stream *outs)
{
- struct isakmp_ipsec_id id;
- pb_stream id_pbs;
- ip_address ta;
- const unsigned char *tbp;
- size_t tal;
-
- id.isaiid_np = np;
- id.isaiid_idtype = subnetishost(net)
- ? aftoinfo(subnettypeof(net))->id_addr
- : aftoinfo(subnettypeof(net))->id_subnet;
- id.isaiid_protoid = protoid;
- id.isaiid_port = port;
-
- if (!out_struct(&id, &isakmp_ipsec_identification_desc, outs, &id_pbs))
- return FALSE;
-
- networkof(net, &ta);
- tal = addrbytesptr(&ta, &tbp);
- if (!out_raw(tbp, tal, &id_pbs, "client network"))
- return FALSE;
+ struct isakmp_ipsec_id id;
+ pb_stream id_pbs;
+ ip_address ta;
+ const unsigned char *tbp;
+ size_t tal;
+
+ id.isaiid_np = np;
+ id.isaiid_idtype = subnetishost(net)
+ ? aftoinfo(subnettypeof(net))->id_addr
+ : aftoinfo(subnettypeof(net))->id_subnet;
+ id.isaiid_protoid = protoid;
+ id.isaiid_port = port;
+
+ if (!out_struct(&id, &isakmp_ipsec_identification_desc, outs, &id_pbs))
+ return FALSE;
- if (!subnetishost(net))
- {
- maskof(net, &ta);
+ networkof(net, &ta);
tal = addrbytesptr(&ta, &tbp);
- if (!out_raw(tbp, tal, &id_pbs, "client mask"))
- return FALSE;
- }
+ if (!out_raw(tbp, tal, &id_pbs, "client network"))
+ return FALSE;
+
+ if (!subnetishost(net))
+ {
+ maskof(net, &ta);
+ tal = addrbytesptr(&ta, &tbp);
+ if (!out_raw(tbp, tal, &id_pbs, "client mask"))
+ return FALSE;
+ }
- close_output_pbs(&id_pbs);
- return TRUE;
+ close_output_pbs(&id_pbs);
+ return TRUE;
}
-stf_status
-quick_outI1(int whack_sock
-, struct state *isakmp_sa
-, struct connection *c
-, lset_t policy
-, unsigned long try
-, so_serial_t replacing)
+stf_status quick_outI1(int whack_sock, struct state *isakmp_sa,
+ struct connection *c, lset_t policy, unsigned long try,
+ so_serial_t replacing)
{
- struct state *st = duplicate_state(isakmp_sa);
- pb_stream reply; /* not really a reply */
- pb_stream rbody;
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
- bool has_client = c->spd.this.has_client || c->spd.that.has_client ||
- c->spd.this.protocol || c->spd.that.protocol ||
- c->spd.this.port || c->spd.that.port;
-
- bool send_natoa = FALSE;
- u_int8_t np = ISAKMP_NEXT_NONE;
-
- st->st_whack_sock = whack_sock;
- st->st_connection = c;
- set_cur_state(st); /* we must reset before exit */
- st->st_policy = policy;
- st->st_try = try;
-
- st->st_myuserprotoid = c->spd.this.protocol;
- st->st_peeruserprotoid = c->spd.that.protocol;
- st->st_myuserport = c->spd.this.port;
- st->st_peeruserport = c->spd.that.port;
-
- st->st_msgid = generate_msgid(isakmp_sa);
- st->st_state = STATE_QUICK_I1;
-
- insert_state(st); /* needs cookies, connection, and msgid */
-
- if (replacing == SOS_NOBODY)
- plog("initiating Quick Mode %s {using isakmp#%lu}"
- , prettypolicy(policy)
- , isakmp_sa->st_serialno);
- else
- plog("initiating Quick Mode %s to replace #%lu {using isakmp#%lu}"
- , prettypolicy(policy)
- , replacing
- , isakmp_sa->st_serialno);
-
- if (isakmp_sa->nat_traversal & NAT_T_DETECTED)
- {
- /* Duplicate nat_traversal status in new state */
- st->nat_traversal = isakmp_sa->nat_traversal;
-
- if (isakmp_sa->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
- has_client = TRUE;
-
- nat_traversal_change_port_lookup(NULL, st);
- }
- else
- st->nat_traversal = 0;
-
- /* are we going to send a NAT-OA payload? */
- if ((st->nat_traversal & NAT_T_WITH_NATOA)
- && !(st->st_policy & POLICY_TUNNEL)
- && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)))
- {
- send_natoa = TRUE;
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATOA_RFC : ISAKMP_NEXT_NATOA_DRAFTS;
- }
-
- /* set up reply */
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
-
- /* HDR* out */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_QUICK;
- hdr.isa_msgid = st->st_msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* HASH(1) -- create and note space to be filled later */
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
-
- /* SA out */
-
- /*
- * See if pfs_group has been specified for this conn,
- * if not, fallback to old use-same-as-P1 behaviour
- */
+ struct state *st = duplicate_state(isakmp_sa);
+ pb_stream reply; /* not really a reply */
+ pb_stream rbody;
+ u_char /* set by START_HASH_PAYLOAD: */
+ *r_hashval, /* where in reply to jam hash value */
+ *r_hash_start; /* start of what is to be hashed */
+ bool has_client = c->spd.this.has_client || c->spd.that.has_client ||
+ c->spd.this.protocol || c->spd.that.protocol ||
+ c->spd.this.port || c->spd.that.port;
+
+ bool send_natoa = FALSE;
+ u_int8_t np = ISAKMP_NEXT_NONE;
+
+ st->st_whack_sock = whack_sock;
+ st->st_connection = c;
+ set_cur_state(st); /* we must reset before exit */
+ st->st_policy = policy;
+ st->st_try = try;
+
+ st->st_myuserprotoid = c->spd.this.protocol;
+ st->st_peeruserprotoid = c->spd.that.protocol;
+ st->st_myuserport = c->spd.this.port;
+ st->st_peeruserport = c->spd.that.port;
+
+ st->st_msgid = generate_msgid(isakmp_sa);
+ st->st_state = STATE_QUICK_I1;
+
+ insert_state(st); /* needs cookies, connection, and msgid */
+
+ if (replacing == SOS_NOBODY)
+ plog("initiating Quick Mode %s {using isakmp#%lu}"
+ , prettypolicy(policy)
+ , isakmp_sa->st_serialno);
+ else
+ plog("initiating Quick Mode %s to replace #%lu {using isakmp#%lu}"
+ , prettypolicy(policy)
+ , replacing
+ , isakmp_sa->st_serialno);
+
+ if (isakmp_sa->nat_traversal & NAT_T_DETECTED)
+ {
+ /* Duplicate nat_traversal status in new state */
+ st->nat_traversal = isakmp_sa->nat_traversal;
+
+ if (isakmp_sa->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
+ has_client = TRUE;
+
+ nat_traversal_change_port_lookup(NULL, st);
+ }
+ else
+ st->nat_traversal = 0;
+
+ /* are we going to send a NAT-OA payload? */
+ if ((st->nat_traversal & NAT_T_WITH_NATOA)
+ && !(st->st_policy & POLICY_TUNNEL)
+ && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)))
+ {
+ send_natoa = TRUE;
+ np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
+ ISAKMP_NEXT_NATOA_RFC : ISAKMP_NEXT_NATOA_DRAFTS;
+ }
+
+ /* set up reply */
+ init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");
+
+ /* HDR* out */
+ {
+ struct isakmp_hdr hdr;
+
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_HASH;
+ hdr.isa_xchg = ISAKMP_XCHG_QUICK;
+ hdr.isa_msgid = st->st_msgid;
+ hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
+ memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
+ }
+
+ /* HASH(1) -- create and note space to be filled later */
+ START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_SA);
+
+ /* SA out */
+
+ /*
+ * See if pfs_group has been specified for this conn,
+ * if not, fallback to old use-same-as-P1 behaviour
+ */
#ifndef NO_IKE_ALG
- if (st->st_connection)
- st->st_pfs_group = ike_alg_pfsgroup(st->st_connection, policy);
- if (!st->st_pfs_group)
+ if (st->st_connection)
+ st->st_pfs_group = ike_alg_pfsgroup(st->st_connection, policy);
+ if (!st->st_pfs_group)
#endif
- /* If PFS specified, use the same group as during Phase 1:
- * since no negotiation is possible, we pick one that is
- * very likely supported.
- */
- st->st_pfs_group = policy & POLICY_PFS? isakmp_sa->st_oakley.group : NULL;
-
- /* Emit SA payload based on a subset of the policy bits.
- * POLICY_COMPRESS is considered iff we can do IPcomp.
- */
- {
- lset_t pm = POLICY_ENCRYPT | POLICY_AUTHENTICATE;
-
- if (can_do_IPcomp)
- pm |= POLICY_COMPRESS;
-
- if (!out_sa(&rbody
- , &ipsec_sadb[(st->st_policy & pm) >> POLICY_IPSEC_SHIFT]
- , st, FALSE, ISAKMP_NEXT_NONCE))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &rbody
- , policy & POLICY_PFS? ISAKMP_NEXT_KE : has_client? ISAKMP_NEXT_ID : np
- , "Ni"))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
+ /* If PFS specified, use the same group as during Phase 1:
+ * since no negotiation is possible, we pick one that is
+ * very likely supported.
+ */
+ st->st_pfs_group = policy & POLICY_PFS? isakmp_sa->st_oakley.group : NULL;
+
+ /* Emit SA payload based on a subset of the policy bits.
+ * POLICY_COMPRESS is considered iff we can do IPcomp.
+ */
+ {
+ lset_t pm = POLICY_ENCRYPT | POLICY_AUTHENTICATE;
+
+ if (can_do_IPcomp)
+ pm |= POLICY_COMPRESS;
+
+ if (!out_sa(&rbody
+ , &ipsec_sadb[(st->st_policy & pm) >> POLICY_IPSEC_SHIFT]
+ , st, FALSE, ISAKMP_NEXT_NONCE))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
+ }
+
+ /* Ni out */
+ if (!build_and_ship_nonce(&st->st_ni, &rbody
+ , policy & POLICY_PFS? ISAKMP_NEXT_KE : has_client? ISAKMP_NEXT_ID : np
+ , "Ni"))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
- /* [ KE ] out (for PFS) */
+ /* [ KE ] out (for PFS) */
- if (st->st_pfs_group != NULL)
- {
- if (!build_and_ship_KE(st, &st->st_gi, st->st_pfs_group
- , &rbody, has_client? ISAKMP_NEXT_ID : np))
+ if (st->st_pfs_group != NULL)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!build_and_ship_KE(st, &st->st_gi, st->st_pfs_group
+ , &rbody, has_client? ISAKMP_NEXT_ID : np))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* [ IDci, IDcr ] out */
- if (has_client)
- {
- /* IDci (we are initiator), then IDcr (peer is responder) */
- if (!emit_subnet_id(&c->spd.this.client
- , ISAKMP_NEXT_ID, st->st_myuserprotoid, st->st_myuserport, &rbody)
- || !emit_subnet_id(&c->spd.that.client
- , np, st->st_peeruserprotoid, st->st_peeruserport, &rbody))
+ /* [ IDci, IDcr ] out */
+ if (has_client)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ /* IDci (we are initiator), then IDcr (peer is responder) */
+ if (!emit_subnet_id(&c->spd.this.client
+ , ISAKMP_NEXT_ID, st->st_myuserprotoid, st->st_myuserport, &rbody)
+ || !emit_subnet_id(&c->spd.that.client
+ , np, st->st_peeruserprotoid, st->st_peeruserport, &rbody))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* Send NAT-OA if our address is NATed */
- if (send_natoa)
- {
- if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &rbody, st))
+ /* Send NAT-OA if our address is NATed */
+ if (send_natoa)
{
- reset_cur_state();
- return STF_INTERNAL_ERROR;
+ if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &rbody, st))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* finish computing HASH(1), inserting it in output */
- (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur
- , st, &st->st_msgid, FALSE);
+ /* finish computing HASH(1), inserting it in output */
+ (void) quick_mode_hash12(r_hashval, r_hash_start, rbody.cur
+ , st, &st->st_msgid, FALSE);
- /* encrypt message, except for fixed part of header */
+ /* encrypt message, except for fixed part of header */
+
+ init_phase2_iv(isakmp_sa, &st->st_msgid);
+ st->st_new_iv_len = isakmp_sa->st_new_iv_len;
+ memcpy(st->st_new_iv, isakmp_sa->st_new_iv, st->st_new_iv_len);
- init_phase2_iv(isakmp_sa, &st->st_msgid);
- st->st_new_iv_len = isakmp_sa->st_new_iv_len;
- memcpy(st->st_new_iv, isakmp_sa->st_new_iv, st->st_new_iv_len);
+ if (!encrypt_message(&rbody, st))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
- if (!encrypt_message(&rbody, st))
- {
+ /* save packet, now that we know its size */
+ st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+
+ /* send the packet */
+
+ send_packet(st, "quick_outI1");
+
+ delete_event(st);
+ event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
+
+ if (replacing == SOS_NOBODY)
+ whack_log(RC_NEW_STATE + STATE_QUICK_I1
+ , "%s: initiate"
+ , enum_name(&state_names, st->st_state));
+ else
+ whack_log(RC_NEW_STATE + STATE_QUICK_I1
+ , "%s: initiate to replace #%lu"
+ , enum_name(&state_names, st->st_state)
+ , replacing);
reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
-
- /* save packet, now that we know its size */
- clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)
- , "reply packet from quick_outI1");
-
- /* send the packet */
-
- send_packet(st, "quick_outI1");
-
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
-
- if (replacing == SOS_NOBODY)
- whack_log(RC_NEW_STATE + STATE_QUICK_I1
- , "%s: initiate"
- , enum_name(&state_names, st->st_state));
- else
- whack_log(RC_NEW_STATE + STATE_QUICK_I1
- , "%s: initiate to replace #%lu"
- , enum_name(&state_names, st->st_state)
- , replacing);
- reset_cur_state();
- return STF_OK;
+ return STF_OK;
}
/*
* Decode the CERT payload of Phase 1.
*/
-static void
-decode_cert(struct msg_digest *md)
+static void decode_cert(struct msg_digest *md)
{
- struct payload_digest *p;
-
- for (p = md->chain[ISAKMP_NEXT_CERT]; p != NULL; p = p->next)
- {
- struct isakmp_cert *const cert = &p->payload.cert;
- chunk_t blob;
- time_t valid_until;
- blob.ptr = p->pbs.cur;
- blob.len = pbs_left(&p->pbs);
- if (cert->isacert_type == CERT_X509_SIGNATURE)
- {
- x509cert_t cert = empty_x509cert;
- if (parse_x509cert(blob, 0, &cert))
- {
- if (verify_x509cert(&cert, strict_crl_policy, &valid_until))
+ struct payload_digest *p;
+
+ for (p = md->chain[ISAKMP_NEXT_CERT]; p != NULL; p = p->next)
+ {
+ struct isakmp_cert *const cert = &p->payload.cert;
+ chunk_t blob;
+ time_t valid_until;
+ blob.ptr = p->pbs.cur;
+ blob.len = pbs_left(&p->pbs);
+ if (cert->isacert_type == CERT_X509_SIGNATURE)
+ {
+ x509cert_t cert = empty_x509cert;
+ if (parse_x509cert(blob, 0, &cert))
+ {
+ if (verify_x509cert(&cert, strict_crl_policy, &valid_until))
+ {
+ DBG(DBG_PARSING,
+ DBG_log("Public key validated")
+ )
+ add_x509_public_key(&cert, valid_until, DAL_SIGNED);
+ }
+ else
+ {
+ plog("X.509 certificate rejected");
+ }
+ DESTROY_IF(cert.public_key);
+ free_generalNames(cert.subjectAltName, FALSE);
+ free_generalNames(cert.crlDistributionPoints, FALSE);
+ }
+ else
+ plog("Syntax error in X.509 certificate");
+ }
+ else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509)
{
- DBG(DBG_PARSING,
- DBG_log("Public key validated")
- )
- add_x509_public_key(&cert, valid_until, DAL_SIGNED);
+ x509cert_t *cert = NULL;
+
+ if (pkcs7_parse_signedData(blob, NULL, &cert, NULL, NULL))
+ store_x509certs(&cert, strict_crl_policy);
+ else
+ plog("Syntax error in PKCS#7 wrapped X.509 certificates");
}
else
{
- plog("X.509 certificate rejected");
+ loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload",
+ enum_show(&cert_type_names, cert->isacert_type));
+ DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob);
}
- free_generalNames(cert.subjectAltName, FALSE);
- free_generalNames(cert.crlDistributionPoints, FALSE);
- }
- else
- plog("Syntax error in X.509 certificate");
- }
- else if (cert->isacert_type == CERT_PKCS7_WRAPPED_X509)
- {
- x509cert_t *cert = NULL;
-
- if (pkcs7_parse_signedData(blob, NULL, &cert, NULL, NULL))
- store_x509certs(&cert, strict_crl_policy);
- else
- plog("Syntax error in PKCS#7 wrapped X.509 certificates");
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "ignoring %s certificate payload",
- enum_show(&cert_type_names, cert->isacert_type));
- DBG_cond_dump_chunk(DBG_PARSING, "CERT:\n", blob);
}
- }
}
/*
* Decode the CR payload of Phase 1.
*/
-static void
-decode_cr(struct msg_digest *md, struct connection *c)
+static void decode_cr(struct msg_digest *md, struct connection *c)
{
- struct payload_digest *p;
+ struct payload_digest *p;
- for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
- {
- struct isakmp_cr *const cr = &p->payload.cr;
- chunk_t ca_name;
-
- ca_name.len = pbs_left(&p->pbs);
- ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;
+ for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next)
+ {
+ struct isakmp_cr *const cr = &p->payload.cr;
+ chunk_t ca_name;
+
+ ca_name.len = pbs_left(&p->pbs);
+ ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL;
- DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);
+ DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name);
- if (cr->isacr_type == CERT_X509_SIGNATURE)
- {
- char buf[BUF_LEN];
+ if (cr->isacr_type == CERT_X509_SIGNATURE)
+ {
+ char buf[BUF_LEN];
- if (ca_name.len > 0)
- {
- generalName_t *gn;
-
- if (!is_asn1(ca_name))
- continue;
-
- gn = alloc_thing(generalName_t, "generalName");
- clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name");
- gn->kind = GN_DIRECTORY_NAME;
- gn->name = ca_name;
- gn->next = c->requested_ca;
- c->requested_ca = gn;
- }
- c->got_certrequest = TRUE;
-
- DBG(DBG_PARSING | DBG_CONTROL,
- dntoa_or_null(buf, BUF_LEN, ca_name, "%any");
- DBG_log("requested CA: '%s'", buf);
- )
+ if (ca_name.len > 0)
+ {
+ generalName_t *gn;
+
+ if (!is_asn1(ca_name))
+ continue;
+
+ gn = malloc_thing(generalName_t);
+ ca_name = chunk_clone(ca_name);
+ gn->kind = GN_DIRECTORY_NAME;
+ gn->name = ca_name;
+ gn->next = c->requested_ca;
+ c->requested_ca = gn;
+ }
+ c->got_certrequest = TRUE;
+
+ DBG(DBG_PARSING | DBG_CONTROL,
+ dntoa_or_null(buf, BUF_LEN, ca_name, "%any");
+ DBG_log("requested CA: '%s'", buf);
+ )
+ }
+ else
+ loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
+ enum_show(&cert_type_names, cr->isacr_type));
}
- else
- loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload",
- enum_show(&cert_type_names, cr->isacr_type));
- }
}
/* Decode the ID payload of Phase 1 (main_inI3_outR3 and main_inR3)
* Note: we may change connections as a result.
* We must be called before SIG or HASH are decoded since we
- * may change the peer's RSA key or ID.
+ * may change the peer's public key or ID.
*/
-static bool
-decode_peer_id(struct msg_digest *md, struct id *peer)
+static bool decode_peer_id(struct msg_digest *md, struct id *peer)
{
- struct state *const st = md->st;
- struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
- const pb_stream *const id_pbs = &id_pld->pbs;
- struct isakmp_id *const id = &id_pld->payload.id;
-
- /* I think that RFC2407 (IPSEC DOI) 4.6.2 is confused.
- * It talks about the protocol ID and Port fields of the ID
- * Payload, but they don't exist as such in Phase 1.
- * We use more appropriate names.
- * isaid_doi_specific_a is in place of Protocol ID.
- * isaid_doi_specific_b is in place of Port.
- * Besides, there is no good reason for allowing these to be
- * other than 0 in Phase 1.
- */
- if ((st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
- && id->isaid_doi_specific_a == IPPROTO_UDP
- && (id->isaid_doi_specific_b == 0 || id->isaid_doi_specific_b == NAT_T_IKE_FLOAT_PORT))
- {
- DBG_log("protocol/port in Phase 1 ID Payload is %d/%d. "
- "accepted with port_floating NAT-T",
- id->isaid_doi_specific_a, id->isaid_doi_specific_b);
- }
- else if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
- && !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
- {
- loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must be 0/0 or %d/%d"
- " but are %d/%d"
- , IPPROTO_UDP, IKE_UDP_PORT
- , id->isaid_doi_specific_a, id->isaid_doi_specific_b);
- return FALSE;
- }
-
- peer->kind = id->isaid_idtype;
-
- switch (peer->kind)
- {
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- /* failure mode for initaddr is probably inappropriate address length */
+ struct state *const st = md->st;
+ struct payload_digest *const id_pld = md->chain[ISAKMP_NEXT_ID];
+ const pb_stream *const id_pbs = &id_pld->pbs;
+ struct isakmp_id *const id = &id_pld->payload.id;
+
+ /* I think that RFC2407 (IPSEC DOI) 4.6.2 is confused.
+ * It talks about the protocol ID and Port fields of the ID
+ * Payload, but they don't exist as such in Phase 1.
+ * We use more appropriate names.
+ * isaid_doi_specific_a is in place of Protocol ID.
+ * isaid_doi_specific_b is in place of Port.
+ * Besides, there is no good reason for allowing these to be
+ * other than 0 in Phase 1.
+ */
+ if ((st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
+ && id->isaid_doi_specific_a == IPPROTO_UDP
+ && (id->isaid_doi_specific_b == 0 || id->isaid_doi_specific_b == NAT_T_IKE_FLOAT_PORT))
{
- err_t ugh = initaddr(id_pbs->cur, pbs_left(id_pbs)
- , peer->kind == ID_IPV4_ADDR? AF_INET : AF_INET6
- , &peer->ip_addr);
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "improper %s identification payload: %s"
- , enum_show(&ident_names, peer->kind), ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
+ DBG_log("protocol/port in Phase 1 ID Payload is %d/%d. "
+ "accepted with port_floating NAT-T",
+ id->isaid_doi_specific_a, id->isaid_doi_specific_b);
}
- break;
-
- case ID_USER_FQDN:
- if (memchr(id_pbs->cur, '@', pbs_left(id_pbs)) == NULL)
+ else if (!(id->isaid_doi_specific_a == 0 && id->isaid_doi_specific_b == 0)
+ && !(id->isaid_doi_specific_a == IPPROTO_UDP && id->isaid_doi_specific_b == IKE_UDP_PORT))
{
- loglog(RC_LOG_SERIOUS, "peer's ID_USER_FQDN contains no @");
- return FALSE;
+ loglog(RC_LOG_SERIOUS, "protocol/port in Phase 1 ID Payload must be 0/0 or %d/%d"
+ " but are %d/%d"
+ , IPPROTO_UDP, IKE_UDP_PORT
+ , id->isaid_doi_specific_a, id->isaid_doi_specific_b);
+ return FALSE;
}
- /* FALLTHROUGH */
- case ID_FQDN:
- if (memchr(id_pbs->cur, '\0', pbs_left(id_pbs)) != NULL)
+
+ peer->kind = id->isaid_idtype;
+
+ switch (peer->kind)
{
- loglog(RC_LOG_SERIOUS, "Phase 1 ID Payload of type %s contains a NUL"
- , enum_show(&ident_names, peer->kind));
- return FALSE;
- }
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ /* failure mode for initaddr is probably inappropriate address length */
+ {
+ err_t ugh = initaddr(id_pbs->cur, pbs_left(id_pbs)
+ , peer->kind == ID_IPV4_ADDR? AF_INET : AF_INET6
+ , &peer->ip_addr);
+
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "improper %s identification payload: %s"
+ , enum_show(&ident_names, peer->kind), ugh);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ }
+ break;
+
+ case ID_USER_FQDN:
+ if (memchr(id_pbs->cur, '@', pbs_left(id_pbs)) == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "peer's ID_USER_FQDN contains no @");
+ return FALSE;
+ }
+ /* FALLTHROUGH */
+ case ID_FQDN:
+ if (memchr(id_pbs->cur, '\0', pbs_left(id_pbs)) != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "Phase 1 ID Payload of type %s contains a NUL"
+ , enum_show(&ident_names, peer->kind));
+ return FALSE;
+ }
- /* ??? ought to do some more sanity check, but what? */
+ /* ??? ought to do some more sanity check, but what? */
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- break;
+ peer->name = chunk_create(id_pbs->cur, pbs_left(id_pbs));
+ break;
- case ID_KEY_ID:
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- DBG(DBG_PARSING,
- DBG_dump_chunk("KEY ID:", peer->name));
- break;
+ case ID_KEY_ID:
+ peer->name = chunk_create(id_pbs->cur, pbs_left(id_pbs));
+ DBG(DBG_PARSING,
+ DBG_dump_chunk("KEY ID:", peer->name));
+ break;
- case ID_DER_ASN1_DN:
- setchunk(peer->name, id_pbs->cur, pbs_left(id_pbs));
- DBG(DBG_PARSING,
- DBG_dump_chunk("DER ASN1 DN:", peer->name));
- break;
+ case ID_DER_ASN1_DN:
+ peer->name = chunk_create(id_pbs->cur, pbs_left(id_pbs));
+ DBG(DBG_PARSING,
+ DBG_dump_chunk("DER ASN1 DN:", peer->name));
+ break;
- default:
- /* XXX Could send notification back */
- loglog(RC_LOG_SERIOUS, "Unacceptable identity type (%s) in Phase 1 ID Payload"
- , enum_show(&ident_names, peer->kind));
- return FALSE;
- }
+ default:
+ /* XXX Could send notification back */
+ loglog(RC_LOG_SERIOUS, "Unacceptable identity type (%s) in Phase 1 ID Payload"
+ , enum_show(&ident_names, peer->kind));
+ return FALSE;
+ }
- {
- char buf[BUF_LEN];
+ {
+ char buf[BUF_LEN];
- idtoa(peer, buf, sizeof(buf));
- plog("Peer ID is %s: '%s'",
- enum_show(&ident_names, id->isaid_idtype), buf);
- }
+ idtoa(peer, buf, sizeof(buf));
+ plog("Peer ID is %s: '%s'",
+ enum_show(&ident_names, id->isaid_idtype), buf);
+ }
- /* check for certificates */
- decode_cert(md);
- return TRUE;
+ /* check for certificates */
+ decode_cert(md);
+ return TRUE;
}
/* Now that we've decoded the ID payload, let's see if we
@@ -2454,111 +2298,111 @@ decode_peer_id(struct msg_digest *md, struct id *peer)
* - if the initiation was explicit, we'd be ignoring user's intent
* - if opportunistic, we'll lose our HOLD info
*/
-static bool
-switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
+static bool switch_connection(struct msg_digest *md, struct id *peer,
+ bool initiator)
{
- struct state *const st = md->st;
- struct connection *c = st->st_connection;
-
- chunk_t peer_ca = (st->st_peer_pubkey != NULL)
- ? st->st_peer_pubkey->issuer : empty_chunk;
+ struct state *const st = md->st;
+ struct connection *c = st->st_connection;
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
+ chunk_t peer_ca = (st->st_peer_pubkey != NULL)
+ ? st->st_peer_pubkey->issuer : chunk_empty;
- dntoa_or_null(buf, BUF_LEN, peer_ca, "%none");
- DBG_log("peer CA: '%s'", buf);
- )
+ DBG(DBG_CONTROL,
+ char buf[BUF_LEN];
- if (initiator)
- {
- int pathlen;
+ dntoa_or_null(buf, BUF_LEN, peer_ca, "%none");
+ DBG_log("peer CA: '%s'", buf);
+ )
- if (!same_id(&c->spd.that.id, peer))
+ if (initiator)
{
- char expect[BUF_LEN]
- , found[BUF_LEN];
+ int pathlen;
- idtoa(&c->spd.that.id, expect, sizeof(expect));
- idtoa(peer, found, sizeof(found));
- loglog(RC_LOG_SERIOUS
- , "we require peer to have ID '%s', but peer declares '%s'"
- , expect, found);
- return FALSE;
- }
+ if (!same_id(&c->spd.that.id, peer))
+ {
+ char expect[BUF_LEN]
+ , found[BUF_LEN];
+
+ idtoa(&c->spd.that.id, expect, sizeof(expect));
+ idtoa(peer, found, sizeof(found));
+ loglog(RC_LOG_SERIOUS
+ , "we require peer to have ID '%s', but peer declares '%s'"
+ , expect, found);
+ return FALSE;
+ }
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
+ DBG(DBG_CONTROL,
+ char buf[BUF_LEN];
- dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none");
- DBG_log("required CA: '%s'", buf);
- )
+ dntoa_or_null(buf, BUF_LEN, c->spd.that.ca, "%none");
+ DBG_log("required CA: '%s'", buf);
+ )
- if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen))
- {
- loglog(RC_LOG_SERIOUS
- , "we don't accept the peer's CA");
- return FALSE;
+ if (!trusted_ca(peer_ca, c->spd.that.ca, &pathlen))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "we don't accept the peer's CA");
+ return FALSE;
+ }
}
- }
- else
- {
- struct connection *r;
+ else
+ {
+ struct connection *r;
- /* check for certificate requests */
- decode_cr(md, c);
+ /* check for certificate requests */
+ decode_cr(md, c);
- r = refine_host_connection(st, peer, peer_ca);
+ r = refine_host_connection(st, peer, peer_ca);
- /* delete the collected certificate requests */
- free_generalNames(c->requested_ca, TRUE);
- c->requested_ca = NULL;
+ /* delete the collected certificate requests */
+ free_generalNames(c->requested_ca, TRUE);
+ c->requested_ca = NULL;
- if (r == NULL)
- {
- char buf[BUF_LEN];
+ if (r == NULL)
+ {
+ char buf[BUF_LEN];
- idtoa(peer, buf, sizeof(buf));
- loglog(RC_LOG_SERIOUS, "no suitable connection for peer '%s'", buf);
- return FALSE;
- }
+ idtoa(peer, buf, sizeof(buf));
+ loglog(RC_LOG_SERIOUS, "no suitable connection for peer '%s'", buf);
+ return FALSE;
+ }
- DBG(DBG_CONTROL,
- char buf[BUF_LEN];
+ DBG(DBG_CONTROL,
+ char buf[BUF_LEN];
- dntoa_or_null(buf, BUF_LEN, r->spd.this.ca, "%none");
- DBG_log("offered CA: '%s'", buf);
- )
+ dntoa_or_null(buf, BUF_LEN, r->spd.this.ca, "%none");
+ DBG_log("offered CA: '%s'", buf);
+ )
- if (r != c)
- {
- /* apparently, r is an improvement on c -- replace */
+ if (r != c)
+ {
+ /* apparently, r is an improvement on c -- replace */
- DBG(DBG_CONTROL
- , DBG_log("switched from \"%s\" to \"%s\"", c->name, r->name));
- if (r->kind == CK_TEMPLATE)
- {
- /* instantiate it, filling in peer's ID */
- r = rw_instantiate(r, &c->spd.that.host_addr
- , c->spd.that.host_port, NULL, peer);
- }
+ DBG(DBG_CONTROL
+ , DBG_log("switched from \"%s\" to \"%s\"", c->name, r->name));
+ if (r->kind == CK_TEMPLATE)
+ {
+ /* instantiate it, filling in peer's ID */
+ r = rw_instantiate(r, &c->spd.that.host_addr
+ , c->spd.that.host_port, NULL, peer);
+ }
- /* copy certificate request info */
- r->got_certrequest = c->got_certrequest;
+ /* copy certificate request info */
+ r->got_certrequest = c->got_certrequest;
- st->st_connection = r; /* kill reference to c */
- set_cur_connection(r);
- connection_discard(c);
- }
- else if (c->spd.that.has_id_wildcards)
- {
- free_id_content(&c->spd.that.id);
- c->spd.that.id = *peer;
- c->spd.that.has_id_wildcards = FALSE;
- unshare_id_content(&c->spd.that.id);
+ st->st_connection = r; /* kill reference to c */
+ set_cur_connection(r);
+ connection_discard(c);
+ }
+ else if (c->spd.that.has_id_wildcards)
+ {
+ free_id_content(&c->spd.that.id);
+ c->spd.that.id = *peer;
+ c->spd.that.has_id_wildcards = FALSE;
+ unshare_id_content(&c->spd.that.id);
+ }
}
- }
- return TRUE;
+ return TRUE;
}
/* Decode the variable part of an ID packet (during Quick Mode).
@@ -2566,227 +2410,218 @@ switch_connection(struct msg_digest *md, struct id *peer, bool initiator)
* Rejects 0.0.0.0/32 or IPv6 equivalent because
* (1) it is wrong and (2) we use this value for inband signalling.
*/
-static bool
-decode_net_id(struct isakmp_ipsec_id *id
-, pb_stream *id_pbs
-, ip_subnet *net
-, const char *which)
+static bool decode_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
+ ip_subnet *net, const char *which)
{
- const struct af_info *afi = NULL;
+ const struct af_info *afi = NULL;
- /* Note: the following may be a pointer into static memory
- * that may be recycled, but only if the type is not known.
- * That case is disposed of very early -- in the first switch.
- */
- const char *idtypename = enum_show(&ident_names, id->isaiid_idtype);
+ /* Note: the following may be a pointer into static memory
+ * that may be recycled, but only if the type is not known.
+ * That case is disposed of very early -- in the first switch.
+ */
+ const char *idtypename = enum_show(&ident_names, id->isaiid_idtype);
- switch (id->isaiid_idtype)
- {
- case ID_IPV4_ADDR:
- case ID_IPV4_ADDR_SUBNET:
- case ID_IPV4_ADDR_RANGE:
- afi = &af_inet4_info;
- break;
- case ID_IPV6_ADDR:
- case ID_IPV6_ADDR_SUBNET:
- case ID_IPV6_ADDR_RANGE:
- afi = &af_inet6_info;
- break;
- case ID_FQDN:
- return TRUE;
- default:
- /* XXX support more */
- loglog(RC_LOG_SERIOUS, "unsupported ID type %s"
- , idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
-
- switch (id->isaiid_idtype)
- {
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
+ switch (id->isaiid_idtype)
{
- ip_address temp_address;
- err_t ugh;
-
- ugh = initaddr(id_pbs->cur, pbs_left(id_pbs), afi->af, &temp_address);
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s has wrong length in Quick I1 (%s)"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
- if (isanyaddr(&temp_address))
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s is invalid (%s) in Quick I1"
- , which, idtypename, ip_str(&temp_address));
- /* XXX Could send notification back */
- return FALSE;
- }
- happy(addrtosubnet(&temp_address, net));
- DBG(DBG_PARSING | DBG_CONTROL
- , DBG_log("%s is %s", which, ip_str(&temp_address)));
- break;
+ case ID_IPV4_ADDR:
+ case ID_IPV4_ADDR_SUBNET:
+ case ID_IPV4_ADDR_RANGE:
+ afi = &af_inet4_info;
+ break;
+ case ID_IPV6_ADDR:
+ case ID_IPV6_ADDR_SUBNET:
+ case ID_IPV6_ADDR_RANGE:
+ afi = &af_inet6_info;
+ break;
+ case ID_FQDN:
+ return TRUE;
+ default:
+ /* XXX support more */
+ loglog(RC_LOG_SERIOUS, "unsupported ID type %s"
+ , idtypename);
+ /* XXX Could send notification back */
+ return FALSE;
}
- case ID_IPV4_ADDR_SUBNET:
- case ID_IPV6_ADDR_SUBNET:
+ switch (id->isaiid_idtype)
{
- ip_address temp_address, temp_mask;
- err_t ugh;
+ case ID_IPV4_ADDR:
+ case ID_IPV6_ADDR:
+ {
+ ip_address temp_address;
+ err_t ugh;
- if (pbs_left(id_pbs) != 2 * afi->ia_sz)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
- , which, idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
- ugh = initaddr(id_pbs->cur
- , afi->ia_sz, afi->af, &temp_address);
- if (ugh == NULL)
- ugh = initaddr(id_pbs->cur + afi->ia_sz
- , afi->ia_sz, afi->af, &temp_mask);
- if (ugh == NULL)
- ugh = initsubnet(&temp_address, masktocount(&temp_mask)
- , '0', net);
- if (ugh == NULL && subnetisnone(net))
- ugh = "contains only anyaddr";
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s bad subnet in Quick I1 (%s)"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
- DBG(DBG_PARSING | DBG_CONTROL,
+ ugh = initaddr(id_pbs->cur, pbs_left(id_pbs), afi->af, &temp_address);
+
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s has wrong length in Quick I1 (%s)"
+ , which, idtypename, ugh);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ if (isanyaddr(&temp_address))
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s is invalid (%s) in Quick I1"
+ , which, idtypename, ip_str(&temp_address));
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ happy(addrtosubnet(&temp_address, net));
+ DBG(DBG_PARSING | DBG_CONTROL
+ , DBG_log("%s is %s", which, ip_str(&temp_address)));
+ break;
+ }
+
+ case ID_IPV4_ADDR_SUBNET:
+ case ID_IPV6_ADDR_SUBNET:
{
- char temp_buff[SUBNETTOT_BUF];
+ ip_address temp_address, temp_mask;
+ err_t ugh;
- subnettot(net, 0, temp_buff, sizeof(temp_buff));
- DBG_log("%s is subnet %s", which, temp_buff);
- });
- break;
- }
+ if (pbs_left(id_pbs) != 2 * afi->ia_sz)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
+ , which, idtypename);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ ugh = initaddr(id_pbs->cur
+ , afi->ia_sz, afi->af, &temp_address);
+ if (ugh == NULL)
+ ugh = initaddr(id_pbs->cur + afi->ia_sz
+ , afi->ia_sz, afi->af, &temp_mask);
+ if (ugh == NULL)
+ ugh = initsubnet(&temp_address, masktocount(&temp_mask)
+ , '0', net);
+ if (ugh == NULL && subnetisnone(net))
+ ugh = "contains only anyaddr";
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s bad subnet in Quick I1 (%s)"
+ , which, idtypename, ugh);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ DBG(DBG_PARSING | DBG_CONTROL,
+ {
+ char temp_buff[SUBNETTOT_BUF];
- case ID_IPV4_ADDR_RANGE:
- case ID_IPV6_ADDR_RANGE:
- {
- ip_address temp_address_from, temp_address_to;
- err_t ugh;
+ subnettot(net, 0, temp_buff, sizeof(temp_buff));
+ DBG_log("%s is subnet %s", which, temp_buff);
+ });
+ break;
+ }
- if (pbs_left(id_pbs) != 2 * afi->ia_sz)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
- , which, idtypename);
- /* XXX Could send notification back */
- return FALSE;
- }
- ugh = initaddr(id_pbs->cur, afi->ia_sz, afi->af, &temp_address_from);
- if (ugh == NULL)
- ugh = initaddr(id_pbs->cur + afi->ia_sz
- , afi->ia_sz, afi->af, &temp_address_to);
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s ID payload %s malformed (%s) in Quick I1"
- , which, idtypename, ugh);
- /* XXX Could send notification back */
- return FALSE;
- }
-
- ugh = rangetosubnet(&temp_address_from, &temp_address_to, net);
- if (ugh == NULL && subnetisnone(net))
- ugh = "contains only anyaddr";
- if (ugh != NULL)
- {
- char temp_buff1[ADDRTOT_BUF], temp_buff2[ADDRTOT_BUF];
-
- addrtot(&temp_address_from, 0, temp_buff1, sizeof(temp_buff1));
- addrtot(&temp_address_to, 0, temp_buff2, sizeof(temp_buff2));
- loglog(RC_LOG_SERIOUS, "%s ID payload in Quick I1, %s"
- " %s - %s unacceptable: %s"
- , which, idtypename, temp_buff1, temp_buff2, ugh);
- return FALSE;
- }
- DBG(DBG_PARSING | DBG_CONTROL,
+ case ID_IPV4_ADDR_RANGE:
+ case ID_IPV6_ADDR_RANGE:
{
- char temp_buff[SUBNETTOT_BUF];
+ ip_address temp_address_from, temp_address_to;
+ err_t ugh;
- subnettot(net, 0, temp_buff, sizeof(temp_buff));
- DBG_log("%s is subnet %s (received as range)"
- , which, temp_buff);
- });
- break;
+ if (pbs_left(id_pbs) != 2 * afi->ia_sz)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s wrong length in Quick I1"
+ , which, idtypename);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+ ugh = initaddr(id_pbs->cur, afi->ia_sz, afi->af, &temp_address_from);
+ if (ugh == NULL)
+ ugh = initaddr(id_pbs->cur + afi->ia_sz
+ , afi->ia_sz, afi->af, &temp_address_to);
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID payload %s malformed (%s) in Quick I1"
+ , which, idtypename, ugh);
+ /* XXX Could send notification back */
+ return FALSE;
+ }
+
+ ugh = rangetosubnet(&temp_address_from, &temp_address_to, net);
+ if (ugh == NULL && subnetisnone(net))
+ ugh = "contains only anyaddr";
+ if (ugh != NULL)
+ {
+ char temp_buff1[ADDRTOT_BUF], temp_buff2[ADDRTOT_BUF];
+
+ addrtot(&temp_address_from, 0, temp_buff1, sizeof(temp_buff1));
+ addrtot(&temp_address_to, 0, temp_buff2, sizeof(temp_buff2));
+ loglog(RC_LOG_SERIOUS, "%s ID payload in Quick I1, %s"
+ " %s - %s unacceptable: %s"
+ , which, idtypename, temp_buff1, temp_buff2, ugh);
+ return FALSE;
+ }
+ DBG(DBG_PARSING | DBG_CONTROL,
+ {
+ char temp_buff[SUBNETTOT_BUF];
+
+ subnettot(net, 0, temp_buff, sizeof(temp_buff));
+ DBG_log("%s is subnet %s (received as range)"
+ , which, temp_buff);
+ });
+ break;
+ }
}
- }
- /* set the port selector */
- setportof(htons(id->isaiid_port), &net->addr);
+ /* set the port selector */
+ setportof(htons(id->isaiid_port), &net->addr);
- DBG(DBG_PARSING | DBG_CONTROL,
- DBG_log("%s protocol/port is %d/%d", which, id->isaiid_protoid, id->isaiid_port)
- )
+ DBG(DBG_PARSING | DBG_CONTROL,
+ DBG_log("%s protocol/port is %d/%d", which, id->isaiid_protoid, id->isaiid_port)
+ )
- return TRUE;
+ return TRUE;
}
/* like decode, but checks that what is received matches what was sent */
-static bool
-
-check_net_id(struct isakmp_ipsec_id *id
-, pb_stream *id_pbs
-, u_int8_t *protoid
-, u_int16_t *port
-, ip_subnet *net
-, const char *which)
+static bool check_net_id(struct isakmp_ipsec_id *id, pb_stream *id_pbs,
+ u_int8_t *protoid, u_int16_t *port, ip_subnet *net,
+ const char *which)
{
- ip_subnet net_temp;
+ ip_subnet net_temp;
- if (!decode_net_id(id, id_pbs, &net_temp, which))
- return FALSE;
+ if (!decode_net_id(id, id_pbs, &net_temp, which))
+ return FALSE;
- if (!samesubnet(net, &net_temp)
- || *protoid != id->isaiid_protoid || *port != id->isaiid_port)
- {
- loglog(RC_LOG_SERIOUS, "%s ID returned doesn't match my proposal", which);
- return FALSE;
- }
- return TRUE;
+ if (!samesubnet(net, &net_temp)
+ || *protoid != id->isaiid_protoid || *port != id->isaiid_port)
+ {
+ loglog(RC_LOG_SERIOUS, "%s ID returned doesn't match my proposal", which);
+ return FALSE;
+ }
+ return TRUE;
}
/*
* look for the existence of a non-expiring preloaded public key
*/
-static bool
-has_preloaded_public_key(struct state *st)
+static bool has_preloaded_public_key(struct state *st)
{
- struct connection *c = st->st_connection;
+ struct connection *c = st->st_connection;
- /* do not consider rw connections since
- * the peer's identity must be known
- */
- if (c->kind == CK_PERMANENT)
- {
- pubkey_list_t *p;
-
- /* look for a matching RSA public key */
- for (p = pubkeys; p != NULL; p = p->next)
+ /* do not consider rw connections since
+ * the peer's identity must be known
+ */
+ if (c->kind == CK_PERMANENT)
{
- pubkey_t *key = p->key;
+ pubkey_list_t *p;
- if (key->alg == PUBKEY_ALG_RSA &&
- same_id(&c->spd.that.id, &key->id) &&
- key->until_time == UNDEFINED_TIME)
- {
- /* found a preloaded public key */
- return TRUE;
- }
+ /* look for a matching RSA public key */
+ for (p = pubkeys; p != NULL; p = p->next)
+ {
+ pubkey_t *key = p->key;
+ key_type_t type = key->public_key->get_type(key->public_key);
+
+ if (type == KEY_RSA && same_id(&c->spd.that.id, &key->id) &&
+ key->until_time == UNDEFINED_TIME)
+ {
+ /* found a preloaded public key */
+ return TRUE;
+ }
+ }
}
- }
- return FALSE;
+ return FALSE;
}
/*
@@ -2794,161 +2629,181 @@ has_preloaded_public_key(struct state *st)
* RFC 2409 "IKE" section 5.5
* specifies how this is to be done.
*/
-static void
-compute_proto_keymat(struct state *st
-, u_int8_t protoid
-, struct ipsec_proto_info *pi)
+static void compute_proto_keymat(struct state *st, u_int8_t protoid,
+ struct ipsec_proto_info *pi)
{
- size_t needed_len = 0; /* bytes of keying material needed */
-
- /* Add up the requirements for keying material
- * (It probably doesn't matter if we produce too much!)
- */
- switch (protoid)
- {
- case PROTO_IPSEC_ESP:
- switch (pi->attrs.transid)
- {
- case ESP_NULL:
- needed_len = 0;
- break;
- case ESP_DES:
- needed_len = DES_CBC_BLOCK_SIZE;
- break;
- case ESP_3DES:
- needed_len = DES_CBC_BLOCK_SIZE * 3;
- break;
- default:
+ size_t needed_len = 0; /* bytes of keying material needed */
+
+ /* Add up the requirements for keying material
+ * (It probably doesn't matter if we produce too much!)
+ */
+ switch (protoid)
+ {
+ case PROTO_IPSEC_ESP:
+ switch (pi->attrs.transid)
+ {
+ case ESP_NULL:
+ needed_len = 0;
+ break;
+ case ESP_DES:
+ needed_len = DES_CBC_BLOCK_SIZE;
+ break;
+ case ESP_3DES:
+ needed_len = DES_CBC_BLOCK_SIZE * 3;
+ break;
+ default:
#ifndef NO_KERNEL_ALG
- if((needed_len=kernel_alg_esp_enc_keylen(pi->attrs.transid))>0) {
- /* XXX: check key_len "coupling with kernel.c's */
- if (pi->attrs.key_len) {
- needed_len=pi->attrs.key_len/8;
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "key_len=%d from peer",
- (int)needed_len));
- }
- break;
- }
+ if((needed_len=kernel_alg_esp_enc_keylen(pi->attrs.transid))>0) {
+ /* XXX: check key_len "coupling with kernel.c's */
+ if (pi->attrs.key_len) {
+ needed_len=pi->attrs.key_len/8;
+ DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
+ "key_len=%d from peer",
+ (int)needed_len));
+ }
+ break;
+ }
#endif
- bad_case(pi->attrs.transid);
- }
+ bad_case(pi->attrs.transid);
+ }
#ifndef NO_KERNEL_ALG
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "needed_len (after ESP enc)=%d",
- (int)needed_len));
- if (kernel_alg_esp_auth_ok(pi->attrs.auth, NULL)) {
- needed_len += kernel_alg_esp_auth_keylen(pi->attrs.auth);
- } else
+ DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
+ "needed_len (after ESP enc)=%d",
+ (int)needed_len));
+ if (kernel_alg_esp_auth_ok(pi->attrs.auth, NULL)) {
+ needed_len += kernel_alg_esp_auth_keylen(pi->attrs.auth);
+ } else
#endif
- switch (pi->attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- break;
- case AUTH_ALGORITHM_HMAC_MD5:
- needed_len += HMAC_MD5_KEY_LEN;
- break;
- case AUTH_ALGORITHM_HMAC_SHA1:
- needed_len += HMAC_SHA1_KEY_LEN;
- break;
- case AUTH_ALGORITHM_DES_MAC:
- default:
- bad_case(pi->attrs.auth);
- }
- DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
- "needed_len (after ESP auth)=%d",
- (int)needed_len));
- break;
-
- case PROTO_IPSEC_AH:
- switch (pi->attrs.transid)
- {
- case AH_MD5:
- needed_len = HMAC_MD5_KEY_LEN;
- break;
- case AH_SHA:
- needed_len = HMAC_SHA1_KEY_LEN;
- break;
- default:
- bad_case(pi->attrs.transid);
- }
- break;
-
- default:
- bad_case(protoid);
- }
-
- pi->keymat_len = needed_len;
-
- /* Allocate space for the keying material.
- * Although only needed_len bytes are desired, we
- * must round up to a multiple of ctx.hmac_digest_size
- * so that our buffer isn't overrun.
- */
- {
- struct hmac_ctx ctx_me, ctx_peer;
- size_t needed_space; /* space needed for keying material (rounded up) */
- size_t i;
-
- hmac_init_chunk(&ctx_me, st->st_oakley.hasher, st->st_skeyid_d);
- ctx_peer = ctx_me; /* duplicate initial conditions */
-
- needed_space = needed_len + pad_up(needed_len, ctx_me.hmac_digest_size);
- replace(pi->our_keymat, alloc_bytes(needed_space, "keymat in compute_keymat()"));
- replace(pi->peer_keymat, alloc_bytes(needed_space, "peer_keymat in quick_inI1_outR1()"));
-
- for (i = 0;; )
- {
- if (st->st_shared.ptr != NULL)
- {
- /* PFS: include the g^xy */
- hmac_update_chunk(&ctx_me, st->st_shared);
- hmac_update_chunk(&ctx_peer, st->st_shared);
- }
- hmac_update(&ctx_me, &protoid, sizeof(protoid));
- hmac_update(&ctx_peer, &protoid, sizeof(protoid));
-
- hmac_update(&ctx_me, (u_char *)&pi->our_spi, sizeof(pi->our_spi));
- hmac_update(&ctx_peer, (u_char *)&pi->attrs.spi, sizeof(pi->attrs.spi));
-
- hmac_update_chunk(&ctx_me, st->st_ni);
- hmac_update_chunk(&ctx_peer, st->st_ni);
-
- hmac_update_chunk(&ctx_me, st->st_nr);
- hmac_update_chunk(&ctx_peer, st->st_nr);
-
- hmac_final(pi->our_keymat + i, &ctx_me);
- hmac_final(pi->peer_keymat + i, &ctx_peer);
-
- i += ctx_me.hmac_digest_size;
- if (i >= needed_space)
- break;
+ switch (pi->attrs.auth)
+ {
+ case AUTH_ALGORITHM_NONE:
+ break;
+ case AUTH_ALGORITHM_HMAC_MD5:
+ needed_len += HMAC_MD5_KEY_LEN;
+ break;
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ needed_len += HMAC_SHA1_KEY_LEN;
+ break;
+ case AUTH_ALGORITHM_DES_MAC:
+ default:
+ bad_case(pi->attrs.auth);
+ }
+ DBG(DBG_PARSING, DBG_log("compute_proto_keymat:"
+ "needed_len (after ESP auth)=%d",
+ (int)needed_len));
+ break;
+
+ case PROTO_IPSEC_AH:
+ switch (pi->attrs.transid)
+ {
+ case AH_MD5:
+ needed_len = HMAC_MD5_KEY_LEN;
+ break;
+ case AH_SHA:
+ needed_len = HMAC_SHA1_KEY_LEN;
+ break;
+ default:
+ bad_case(pi->attrs.transid);
+ }
+ break;
+
+ default:
+ bad_case(protoid);
+ }
+
+ pi->keymat_len = needed_len;
+
+ /* Allocate space for the keying material. Although only needed_len bytes
+ * are desired, we must round up to a multiple of hash_size
+ * so that our buffer isn't overrun.
+ */
+ {
+ size_t needed_space; /* space needed for keying material (rounded up) */
+ size_t i, prf_block_size;
+ chunk_t protoid_chunk = chunk_from_thing(protoid);
+ chunk_t spi_our = chunk_from_thing(pi->our_spi);
+ chunk_t spi_peer = chunk_from_thing(pi->attrs.spi);
+ pseudo_random_function_t prf_alg;
+ prf_t *prf_our, *prf_peer;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf_our = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf_peer = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf_our->set_key(prf_our, st->st_skeyid_d);
+ prf_peer->set_key(prf_peer, st->st_skeyid_d);
+ prf_block_size = prf_our->get_block_size(prf_our);
+
+ needed_space = needed_len + pad_up(needed_len, prf_block_size);
+ replace(pi->our_keymat, malloc(needed_space));
+ replace(pi->peer_keymat, malloc(needed_space));
+
+ for (i = 0;; )
+ {
+ char *keymat_i_our = pi->our_keymat + i;
+ char *keymat_i_peer = pi->peer_keymat + i;
+ chunk_t keymat_our = { keymat_i_our, prf_block_size };
+ chunk_t keymat_peer = { keymat_i_peer, prf_block_size };
+
+ if (st->st_shared.ptr != NULL)
+ {
+ /* PFS: include the g^xy */
+ prf_our->get_bytes(prf_our, st->st_shared, NULL);
+ prf_peer->get_bytes(prf_peer, st->st_shared, NULL);
+ }
+ prf_our->get_bytes(prf_our, protoid_chunk, NULL);
+ prf_peer->get_bytes(prf_peer, protoid_chunk, NULL);
+
+ prf_our->get_bytes(prf_our, spi_our, NULL);
+ prf_peer->get_bytes(prf_peer, spi_peer, NULL);
- /* more keying material needed: prepare to go around again */
+ prf_our->get_bytes(prf_our, st->st_ni, NULL);
+ prf_peer->get_bytes(prf_peer, st->st_ni, NULL);
- hmac_reinit(&ctx_me);
- hmac_reinit(&ctx_peer);
+ prf_our->get_bytes(prf_our, st->st_nr, keymat_i_our);
+ prf_peer->get_bytes(prf_peer, st->st_nr, keymat_i_peer);
+
+ i += prf_block_size;
+ if (i >= needed_space)
+ {
+ break;
+ }
- hmac_update(&ctx_me, pi->our_keymat + i - ctx_me.hmac_digest_size
- , ctx_me.hmac_digest_size);
- hmac_update(&ctx_peer, pi->peer_keymat + i - ctx_peer.hmac_digest_size
- , ctx_peer.hmac_digest_size);
+ /* more keying material needed: prepare to go around again */
+ prf_our->get_bytes(prf_our, keymat_our, NULL);
+ prf_peer->get_bytes(prf_peer, keymat_peer, NULL);
+ }
+ prf_our->destroy(prf_our);
+ prf_peer->destroy(prf_peer);
}
- }
+ DBG(DBG_CRYPT,
+ DBG_dump("KEYMAT computed:\n", pi->our_keymat, pi->keymat_len);
+ DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat, pi->keymat_len));
+}
- DBG(DBG_CRYPT,
- DBG_dump("KEYMAT computed:\n", pi->our_keymat, pi->keymat_len);
- DBG_dump("Peer KEYMAT computed:\n", pi->peer_keymat, pi->keymat_len));
+static void compute_keymats(struct state *st)
+{
+ if (st->st_ah.present)
+ compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah);
+ if (st->st_esp.present)
+ compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp);
}
-static void
-compute_keymats(struct state *st)
+static bool uses_pubkey_auth(int auth)
{
- if (st->st_ah.present)
- compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah);
- if (st->st_esp.present)
- compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp);
+ switch (auth)
+ {
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ return TRUE;
+ default:
+ return FALSE;
+ }
}
/* State Transition Functions.
@@ -2973,261 +2828,272 @@ compute_keymats(struct state *st)
/* Handle a Main Mode Oakley first packet (responder side).
* HDR;SA --> HDR;SA
*/
-stf_status
-main_inI1_outR1(struct msg_digest *md)
+stf_status main_inI1_outR1(struct msg_digest *md)
{
- struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
- struct state *st;
- struct connection *c;
- struct isakmp_proposal proposal;
- pb_stream proposal_pbs;
- pb_stream r_sa_pbs;
- u_int32_t ipsecdoisit;
- lset_t policy = LEMPTY;
- int vids_to_send = 0;
-
- /* We preparse the peer's proposal in order to determine
- * the requested authentication policy (RSA or PSK)
- */
- RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
- , &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
-
- backup_pbs(&proposal_pbs);
- RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
- , proposal.isap_notrans, &policy));
- restore_pbs(&proposal_pbs);
-
- /* We are only considering candidate connections that match
- * the requested authentication policy (RSA or PSK)
- */
- c = find_host_connection(&md->iface->addr, pluto_port
- , &md->sender, md->sender_port, policy);
-
- if (c == NULL && md->iface->ike_float)
- {
- c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
- , &md->sender, md->sender_port, policy);
- }
-
- if (c == NULL)
- {
- /* See if a wildcarded connection can be found.
- * We cannot pick the right connection, so we're making a guess.
- * All Road Warrior connections are fair game:
- * we pick the first we come across (if any).
- * If we don't find any, we pick the first opportunistic
- * with the smallest subnet that includes the peer.
- * There is, of course, no necessary relationship between
- * an Initiator's address and that of its client,
- * but Food Groups kind of assumes one.
+ struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
+ struct state *st;
+ struct connection *c;
+ struct isakmp_proposal proposal;
+ pb_stream proposal_pbs;
+ pb_stream r_sa_pbs;
+ u_int32_t ipsecdoisit;
+ lset_t policy = LEMPTY;
+ int vids_to_send = 0;
+
+ /* We preparse the peer's proposal in order to determine
+ * the requested authentication policy (RSA or PSK)
+ */
+ RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sa_pd->payload.sa
+ , &sa_pd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
+
+ backup_pbs(&proposal_pbs);
+ RETURN_STF_FAILURE(parse_isakmp_policy(&proposal_pbs
+ , proposal.isap_notrans, &policy));
+ restore_pbs(&proposal_pbs);
+
+ /* We are only considering candidate connections that match
+ * the requested authentication policy (RSA or PSK)
*/
+ c = find_host_connection(&md->iface->addr, pluto_port
+ , &md->sender, md->sender_port, policy);
+
+ if (c == NULL && md->iface->ike_float)
{
- struct connection *d;
+ c = find_host_connection(&md->iface->addr, NAT_T_IKE_FLOAT_PORT
+ , &md->sender, md->sender_port, policy);
+ }
- d = find_host_connection(&md->iface->addr
- , pluto_port, (ip_address*)NULL, md->sender_port, policy);
+ if (c == NULL)
+ {
+ /* See if a wildcarded connection can be found.
+ * We cannot pick the right connection, so we're making a guess.
+ * All Road Warrior connections are fair game:
+ * we pick the first we come across (if any).
+ * If we don't find any, we pick the first opportunistic
+ * with the smallest subnet that includes the peer.
+ * There is, of course, no necessary relationship between
+ * an Initiator's address and that of its client,
+ * but Food Groups kind of assumes one.
+ */
+ {
+ struct connection *d;
+
+ d = find_host_connection(&md->iface->addr
+ , pluto_port, (ip_address*)NULL, md->sender_port, policy);
+
+ for (; d != NULL; d = d->hp_next)
+ {
+ if (d->kind == CK_GROUP)
+ {
+ /* ignore */
+ }
+ else
+ {
+ if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO))
+ {
+ /* must be Road Warrior: we have a winner */
+ c = d;
+ break;
+ }
+
+ /* Opportunistic or Shunt: pick tightest match */
+ if (addrinsubnet(&md->sender, &d->spd.that.client)
+ && (c == NULL || !subnetinsubnet(&c->spd.that.client, &d->spd.that.client)))
+ c = d;
+ }
+ }
+ }
- for (; d != NULL; d = d->hp_next)
- {
- if (d->kind == CK_GROUP)
+ if (c == NULL)
{
- /* ignore */
+ loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
+ " but no connection has been authorized%s%s"
+ , ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr))
+ , (policy != LEMPTY) ? " with policy=" : ""
+ , (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
+ /* XXX notification is in order! */
+ return STF_IGNORE;
+ }
+ else if (c->kind != CK_TEMPLATE)
+ {
+ loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
+ " but \"%s\" forbids connection"
+ , ip_str(&md->iface->addr), pluto_port, c->name);
+ /* XXX notification is in order! */
+ return STF_IGNORE;
}
else
{
- if (d->kind == CK_TEMPLATE && !(d->policy & POLICY_OPPO))
- {
- /* must be Road Warrior: we have a winner */
- c = d;
- break;
- }
-
- /* Opportunistic or Shunt: pick tightest match */
- if (addrinsubnet(&md->sender, &d->spd.that.client)
- && (c == NULL || !subnetinsubnet(&c->spd.that.client, &d->spd.that.client)))
- c = d;
+ /* Create a temporary connection that is a copy of this one.
+ * His ID isn't declared yet.
+ */
+ c = rw_instantiate(c, &md->sender, md->sender_port, NULL, NULL);
}
- }
+ }
+ else if (c->kind == CK_TEMPLATE)
+ {
+ /* Create an instance
+ * This is a rare case: wildcard peer ID but static peer IP address
+ */
+ c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
}
- if (c == NULL)
+ /* Set up state */
+ md->st = st = new_state();
+ st->st_connection = c;
+ set_cur_state(st); /* (caller will reset cur_state) */
+ st->st_try = 0; /* not our job to try again from start */
+ st->st_policy = c->policy & ~POLICY_IPSEC_MASK; /* only as accurate as connection */
+
+ memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
+ get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);
+
+ insert_state(st); /* needs cookies, connection, and msgid (0) */
+
+ st->st_doi = ISAKMP_DOI_IPSEC;
+ st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */
+
+ if ((c->kind == CK_INSTANCE) && (c->spd.that.host_port != pluto_port))
{
- loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
- " but no connection has been authorized%s%s"
- , ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr))
- , (policy != LEMPTY) ? " with policy=" : ""
- , (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
- /* XXX notification is in order! */
- return STF_IGNORE;
+ plog("responding to Main Mode from unknown peer %s:%u"
+ , ip_str(&c->spd.that.host_addr), c->spd.that.host_port);
}
- else if (c->kind != CK_TEMPLATE)
+ else if (c->kind == CK_INSTANCE)
{
- loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
- " but \"%s\" forbids connection"
- , ip_str(&md->iface->addr), pluto_port, c->name);
- /* XXX notification is in order! */
- return STF_IGNORE;
+ plog("responding to Main Mode from unknown peer %s"
+ , ip_str(&c->spd.that.host_addr));
}
else
{
- /* Create a temporary connection that is a copy of this one.
- * His ID isn't declared yet.
- */
- c = rw_instantiate(c, &md->sender, md->sender_port, NULL, NULL);
+ plog("responding to Main Mode");
}
- }
- else if (c->kind == CK_TEMPLATE)
- {
- /* Create an instance
- * This is a rare case: wildcard peer ID but static peer IP address
- */
- c = rw_instantiate(c, &md->sender, md->sender_port, NULL, &c->spd.that.id);
- }
-
- /* Set up state */
- md->st = st = new_state();
- st->st_connection = c;
- set_cur_state(st); /* (caller will reset cur_state) */
- st->st_try = 0; /* not our job to try again from start */
- st->st_policy = c->policy & ~POLICY_IPSEC_MASK; /* only as accurate as connection */
-
- memcpy(st->st_icookie, md->hdr.isa_icookie, COOKIE_SIZE);
- get_cookie(FALSE, st->st_rcookie, COOKIE_SIZE, &md->sender);
-
- insert_state(st); /* needs cookies, connection, and msgid (0) */
-
- st->st_doi = ISAKMP_DOI_IPSEC;
- st->st_situation = SIT_IDENTITY_ONLY; /* We only support this */
-
- if ((c->kind == CK_INSTANCE) && (c->spd.that.host_port != pluto_port))
- {
- plog("responding to Main Mode from unknown peer %s:%u"
- , ip_str(&c->spd.that.host_addr), c->spd.that.host_port);
- }
- else if (c->kind == CK_INSTANCE)
- {
- plog("responding to Main Mode from unknown peer %s"
- , ip_str(&c->spd.that.host_addr));
- }
- else
- {
- plog("responding to Main Mode");
- }
-
- /* parse_isakmp_sa also spits out a winning SA into our reply,
- * so we have to build our md->reply and emit HDR before calling it.
- */
-
- /* determine how many Vendor ID payloads we will be sending */
- if (SEND_PLUTO_VID)
- vids_to_send++;
- if (SEND_CISCO_UNITY_VID)
- vids_to_send++;
- if (md->openpgp)
- vids_to_send++;
- if (SEND_XAUTH_VID)
- vids_to_send++;
- /* always send DPD Vendor ID */
- vids_to_send++;
- if (md->nat_traversal_vid && nat_traversal_enabled)
- vids_to_send++;
-
- /* HDR out.
- * We can't leave this to comm_handle() because we must
- * fill in the cookie.
- */
- {
- struct isakmp_hdr r_hdr = md->hdr;
-
- r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
- memcpy(r_hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- r_hdr.isa_np = ISAKMP_NEXT_SA;
- if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
- return STF_INTERNAL_ERROR;
- }
- /* start of SA out */
- {
- struct isakmp_sa r_sa = sa_pd->payload.sa;
+ /* parse_isakmp_sa also spits out a winning SA into our reply,
+ * so we have to build our md->reply and emit HDR before calling it.
+ */
- r_sa.isasa_np = vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE;
+ /* determine how many Vendor ID payloads we will be sending */
+ if (SEND_PLUTO_VID)
+ {
+ vids_to_send++;
+ }
+ if (SEND_CISCO_UNITY_VID)
+ {
+ vids_to_send++;
+ }
+ if (md->openpgp)
+ {
+ vids_to_send++;
+ }
+ if (SEND_XAUTH_VID)
+ {
+ vids_to_send++;
+ }
+ /* always send DPD Vendor ID */
+ vids_to_send++;
+ if (md->nat_traversal_vid && nat_traversal_enabled)
+ {
+ vids_to_send++;
+ }
- if (!out_struct(&r_sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
- return STF_INTERNAL_ERROR;
- }
+ /* HDR out.
+ * We can't leave this to comm_handle() because we must
+ * fill in the cookie.
+ */
+ {
+ struct isakmp_hdr r_hdr = md->hdr;
- /* SA body in and out */
- RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
- ,&proposal, &r_sa_pbs, st, FALSE));
+ r_hdr.isa_flags &= ~ISAKMP_FLAG_COMMIT; /* we won't ever turn on this bit */
+ memcpy(r_hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
+ r_hdr.isa_np = ISAKMP_NEXT_SA;
+ if (!out_struct(&r_hdr, &isakmp_hdr_desc, &md->reply, &md->rbody))
+ return STF_INTERNAL_ERROR;
+ }
- /* if enabled send Pluto Vendor ID */
- if (SEND_PLUTO_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_STRONGSWAN))
+ /* start of SA out */
{
- return STF_INTERNAL_ERROR;
+ struct isakmp_sa r_sa = sa_pd->payload.sa;
+
+ r_sa.isasa_np = vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE;
+
+ if (!out_struct(&r_sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
+ return STF_INTERNAL_ERROR;
}
- }
- /* if enabled send Cisco Unity Vendor ID */
- if (SEND_CISCO_UNITY_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_CISCO_UNITY))
+ /* SA body in and out */
+ RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit, &proposal_pbs
+ ,&proposal, &r_sa_pbs, st, FALSE));
+
+ /* if enabled send Pluto Vendor ID */
+ if (SEND_PLUTO_VID)
{
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_STRONGSWAN))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /*
- * if the peer sent an OpenPGP Vendor ID we offer the same capability
- */
- if (md->openpgp)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_OPENPGP))
+ /* if enabled send Cisco Unity Vendor ID */
+ if (SEND_CISCO_UNITY_VID)
{
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_CISCO_UNITY))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* Announce our ability to do eXtended AUTHentication to the peer */
- if (SEND_XAUTH_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_XAUTH))
+ /*
+ * if the peer sent an OpenPGP Vendor ID we offer the same capability
+ */
+ if (md->openpgp)
{
- return STF_INTERNAL_ERROR;
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_OPENPGP))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* Announce our ability to do Dead Peer Detection to the peer */
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_DPD))
- {
- return STF_INTERNAL_ERROR;
- }
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (SEND_XAUTH_VID)
+ {
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_XAUTH))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+ }
- if (md->nat_traversal_vid && nat_traversal_enabled)
- {
- /* reply if NAT-Traversal draft is supported */
- st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
+ /* Announce our ability to do Dead Peer Detection to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_DPD))
+ {
+ return STF_INTERNAL_ERROR;
+ }
- if (st->nat_traversal
- && !out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, md->nat_traversal_vid))
+ if (md->nat_traversal_vid && nat_traversal_enabled)
{
- return STF_INTERNAL_ERROR;
+ /* reply if NAT-Traversal draft is supported */
+ st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
+
+ if (st->nat_traversal
+ && !out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, md->nat_traversal_vid))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- close_message(&md->rbody);
+ close_message(&md->rbody);
- /* save initiator SA for HASH */
- clonereplacechunk(st->st_p1isa, sa_pd->pbs.start, pbs_room(&sa_pd->pbs), "sa in main_inI1_outR1()");
+ /* save initiator SA for HASH */
+ free(st->st_p1isa.ptr);
+ st->st_p1isa = chunk_create(sa_pd->pbs.start, pbs_room(&sa_pd->pbs));
+ st->st_p1isa = chunk_clone(st->st_p1isa);
- return STF_OK;
+ return STF_OK;
}
/* STATE_MAIN_I1: HDR, SA --> auth dependent
@@ -3240,95 +3106,94 @@ main_inI1_outR1(struct msg_digest *md)
*
* We must verify that the proposal received matches one we sent.
*/
-stf_status
-main_inR1_outI2(struct msg_digest *md)
+stf_status main_inR1_outI2(struct msg_digest *md)
{
- struct state *const st = md->st;
+ struct state *const st = md->st;
- u_int8_t np = ISAKMP_NEXT_NONE;
+ u_int8_t np = ISAKMP_NEXT_NONE;
- /* verify echoed SA */
- {
- u_int32_t ipsecdoisit;
- pb_stream proposal_pbs;
- struct isakmp_proposal proposal;
- struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
-
- RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sapd->payload.sa
- ,&sapd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
- if (proposal.isap_notrans != 1)
- {
- loglog(RC_LOG_SERIOUS, "a single Transform is required in a selecting Oakley Proposal; found %u"
- , (unsigned)proposal.isap_notrans);
- RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
- }
- RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
- , &proposal_pbs, &proposal, NULL, st, TRUE));
- }
-
- if (nat_traversal_enabled && md->nat_traversal_vid)
- {
- st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
- plog("enabling possible NAT-traversal with method %s"
- , bitnamesof(natt_type_bitnames, st->nat_traversal));
- }
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
- }
-
- /**************** build output packet HDR;KE;Ni ****************/
-
- /* HDR out.
- * We can't leave this to comm_handle() because the isa_np
- * depends on the type of Auth (eventually).
- */
- echo_hdr(md, FALSE, ISAKMP_NEXT_KE);
-
- /* KE out */
- if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group
- , &md->rbody, ISAKMP_NEXT_NONCE))
- return STF_INTERNAL_ERROR;
+ /* verify echoed SA */
+ {
+ u_int32_t ipsecdoisit;
+ pb_stream proposal_pbs;
+ struct isakmp_proposal proposal;
+ struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
+
+ RETURN_STF_FAILURE(preparse_isakmp_sa_body(&sapd->payload.sa
+ ,&sapd->pbs, &ipsecdoisit, &proposal_pbs, &proposal));
+ if (proposal.isap_notrans != 1)
+ {
+ loglog(RC_LOG_SERIOUS, "a single Transform is required in a selecting Oakley Proposal; found %u"
+ , (unsigned)proposal.isap_notrans);
+ RETURN_STF_FAILURE(BAD_PROPOSAL_SYNTAX);
+ }
+ RETURN_STF_FAILURE(parse_isakmp_sa_body(ipsecdoisit
+ , &proposal_pbs, &proposal, NULL, st, TRUE));
+ }
+
+ if (nat_traversal_enabled && md->nat_traversal_vid)
+ {
+ st->nat_traversal = nat_traversal_vid_to_method(md->nat_traversal_vid);
+ plog("enabling possible NAT-traversal with method %s"
+ , bitnamesof(natt_type_bitnames, st->nat_traversal));
+ }
+ if (st->nat_traversal & NAT_T_WITH_NATD)
+ {
+ np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
+ ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
+ }
+
+ /**************** build output packet HDR;KE;Ni ****************/
+
+ /* HDR out.
+ * We can't leave this to comm_handle() because the isa_np
+ * depends on the type of Auth (eventually).
+ */
+ echo_hdr(md, FALSE, ISAKMP_NEXT_KE);
+
+ /* KE out */
+ if (!build_and_ship_KE(st, &st->st_gi, st->st_oakley.group
+ , &md->rbody, ISAKMP_NEXT_NONCE))
+ return STF_INTERNAL_ERROR;
#ifdef DEBUG
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &md->rbody
- , (cur_debugging & IMPAIR_BUST_MI2)? ISAKMP_NEXT_VID : np, "Ni"))
- return STF_INTERNAL_ERROR;
-
- if (cur_debugging & IMPAIR_BUST_MI2)
- {
- /* generate a pointless large VID payload to push message over MTU */
- pb_stream vid_pbs;
-
- if (!out_generic(np, &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&vid_pbs);
- }
+ /* Ni out */
+ if (!build_and_ship_nonce(&st->st_ni, &md->rbody
+ , (cur_debugging & IMPAIR_BUST_MI2)? ISAKMP_NEXT_VID : np, "Ni"))
+ return STF_INTERNAL_ERROR;
+
+ if (cur_debugging & IMPAIR_BUST_MI2)
+ {
+ /* generate a pointless large VID payload to push message over MTU */
+ pb_stream vid_pbs;
+
+ if (!out_generic(np, &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
+ return STF_INTERNAL_ERROR;
+ if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&vid_pbs);
+ }
#else
- /* Ni out */
- if (!build_and_ship_nonce(&st->st_ni, &md->rbody, np, "Ni"))
- return STF_INTERNAL_ERROR;
+ /* Ni out */
+ if (!build_and_ship_nonce(&st->st_ni, &md->rbody, np, "Ni"))
+ return STF_INTERNAL_ERROR;
#endif
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
- return STF_INTERNAL_ERROR;
- }
+ if (st->nat_traversal & NAT_T_WITH_NATD)
+ {
+ if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
+ return STF_INTERNAL_ERROR;
+ }
- /* finish message */
- close_message(&md->rbody);
+ /* finish message */
+ close_message(&md->rbody);
- /* Reinsert the state, using the responder cookie we just received */
- unhash_state(st);
- memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE);
- insert_state(st); /* needs cookies, connection, and msgid (0) */
+ /* Reinsert the state, using the responder cookie we just received */
+ unhash_state(st);
+ memcpy(st->st_rcookie, md->hdr.isa_rcookie, COOKIE_SIZE);
+ insert_state(st); /* needs cookies, connection, and msgid (0) */
- return STF_OK;
+ return STF_OK;
}
/* STATE_MAIN_R1:
@@ -3336,140 +3201,137 @@ main_inR1_outI2(struct msg_digest *md)
*
* The following are not yet implemented:
* PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
- * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
+ * --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
* RPKE_AUTH:
- * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
- * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
+ * HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]
+ * --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
*/
-stf_status
-main_inI2_outR2(struct msg_digest *md)
+stf_status main_inI2_outR2(struct msg_digest *md)
{
- struct state *const st = md->st;
- pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
-
- /* send CR if auth is RSA and no preloaded RSA public key exists*/
- bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
- bool send_cr = !no_cr_send && RSA_auth && !has_preloaded_public_key(st);
+ struct state *const st = md->st;
+ pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
+
+ /* send CR if auth is RSA or ECDSA and no preloaded public key exists*/
+ bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
+ bool send_cr = !no_cr_send && pubkey_auth && !has_preloaded_public_key(st);
- u_int8_t np = ISAKMP_NEXT_NONE;
+ u_int8_t np = ISAKMP_NEXT_NONE;
- /* KE in */
- RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group, keyex_pbs));
+ /* KE in */
+ RETURN_STF_FAILURE(accept_KE(&st->st_gi, "Gi", st->st_oakley.group, keyex_pbs));
- /* Ni in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
+ /* Ni in */
+ RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- nat_traversal_natd_lookup(md);
+ if (st->nat_traversal & NAT_T_WITH_NATD)
+ {
+ nat_traversal_natd_lookup(md);
- np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
- ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
- }
- if (st->nat_traversal)
- {
- nat_traversal_show_result(st->nat_traversal, md->sender_port);
- }
- if (st->nat_traversal & NAT_T_WITH_KA)
- {
- nat_traversal_new_ka_event();
- }
+ np = (st->nat_traversal & NAT_T_WITH_RFC_VALUES) ?
+ ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS;
+ }
+ if (st->nat_traversal)
+ {
+ nat_traversal_show_result(st->nat_traversal, md->sender_port);
+ }
+ if (st->nat_traversal & NAT_T_WITH_KA)
+ {
+ nat_traversal_new_ka_event();
+ }
- /* decode certificate requests */
- st->st_connection->got_certrequest = FALSE;
- decode_cr(md, st->st_connection);
+ /* decode certificate requests */
+ st->st_connection->got_certrequest = FALSE;
+ decode_cr(md, st->st_connection);
- /**************** build output packet HDR;KE;Nr ****************/
+ /**************** build output packet HDR;KE;Nr ****************/
- /* HDR out done */
+ /* HDR out done */
- /* KE out */
- if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group
- , &md->rbody, ISAKMP_NEXT_NONCE))
- return STF_INTERNAL_ERROR;
+ /* KE out */
+ if (!build_and_ship_KE(st, &st->st_gr, st->st_oakley.group
+ , &md->rbody, ISAKMP_NEXT_NONCE))
+ return STF_INTERNAL_ERROR;
#ifdef DEBUG
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody
- , (cur_debugging & IMPAIR_BUST_MR2)? ISAKMP_NEXT_VID
- : (send_cr? ISAKMP_NEXT_CR : np), "Nr"))
- return STF_INTERNAL_ERROR;
-
- if (cur_debugging & IMPAIR_BUST_MR2)
- {
- /* generate a pointless large VID payload to push message over MTU */
- pb_stream vid_pbs;
-
- if (!out_generic((send_cr)? ISAKMP_NEXT_CR : np,
- &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&vid_pbs);
- }
+ /* Nr out */
+ if (!build_and_ship_nonce(&st->st_nr, &md->rbody
+ , (cur_debugging & IMPAIR_BUST_MR2)? ISAKMP_NEXT_VID
+ : (send_cr? ISAKMP_NEXT_CR : np), "Nr"))
+ return STF_INTERNAL_ERROR;
+
+ if (cur_debugging & IMPAIR_BUST_MR2)
+ {
+ /* generate a pointless large VID payload to push message over MTU */
+ pb_stream vid_pbs;
+
+ if (!out_generic((send_cr)? ISAKMP_NEXT_CR : np,
+ &isakmp_vendor_id_desc, &md->rbody, &vid_pbs))
+ return STF_INTERNAL_ERROR;
+ if (!out_zero(1500 /*MTU?*/, &vid_pbs, "Filler VID"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&vid_pbs);
+ }
#else
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody,
- (send_cr)? ISAKMP_NEXT_CR : np, "Nr"))
- return STF_INTERNAL_ERROR;
+ /* Nr out */
+ if (!build_and_ship_nonce(&st->st_nr, &md->rbody,
+ (send_cr)? ISAKMP_NEXT_CR : np, "Nr"))
+ return STF_INTERNAL_ERROR;
#endif
- /* CR out */
- if (send_cr)
- {
- if (st->st_connection->kind == CK_PERMANENT)
+ /* CR out */
+ if (send_cr)
{
- if (!build_and_ship_CR(CERT_X509_SIGNATURE
- , st->st_connection->spd.that.ca
- , &md->rbody, np))
- return STF_INTERNAL_ERROR;
+ if (st->st_connection->kind == CK_PERMANENT)
+ {
+ if (!build_and_ship_CR(CERT_X509_SIGNATURE
+ , st->st_connection->spd.that.ca
+ , &md->rbody, np))
+ return STF_INTERNAL_ERROR;
+ }
+ else
+ {
+ generalName_t *ca = NULL;
+
+ if (collect_rw_ca_candidates(md, &ca))
+ {
+ generalName_t *gn;
+
+ for (gn = ca; gn != NULL; gn = gn->next)
+ {
+ if (!build_and_ship_CR(CERT_X509_SIGNATURE, gn->name
+ , &md->rbody
+ , gn->next == NULL ? np : ISAKMP_NEXT_CR))
+ return STF_INTERNAL_ERROR;
+ }
+ free_generalNames(ca, FALSE);
+ }
+ else
+ {
+ if (!build_and_ship_CR(CERT_X509_SIGNATURE, chunk_empty
+ , &md->rbody, np))
+ return STF_INTERNAL_ERROR;
+ }
+ }
}
- else
+
+ if (st->nat_traversal & NAT_T_WITH_NATD)
{
- generalName_t *ca = NULL;
+ if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
+ return STF_INTERNAL_ERROR;
+ }
- if (collect_rw_ca_candidates(md, &ca))
- {
- generalName_t *gn;
+ /* finish message */
+ close_message(&md->rbody);
- for (gn = ca; gn != NULL; gn = gn->next)
- {
- if (!build_and_ship_CR(CERT_X509_SIGNATURE, gn->name
- , &md->rbody
- , gn->next == NULL ? np : ISAKMP_NEXT_CR))
- return STF_INTERNAL_ERROR;
- }
- free_generalNames(ca, FALSE);
- }
- else
- {
- if (!build_and_ship_CR(CERT_X509_SIGNATURE, empty_chunk
- , &md->rbody, np))
- return STF_INTERNAL_ERROR;
- }
- }
- }
-
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- if (!nat_traversal_add_natd(ISAKMP_NEXT_NONE, &md->rbody, md))
- return STF_INTERNAL_ERROR;
- }
-
- /* finish message */
- close_message(&md->rbody);
-
- /* next message will be encrypted, but not this one.
- * We could defer this calculation.
- */
- compute_dh_shared(st, st->st_gi, st->st_oakley.group);
- if (!generate_skeyids_iv(st))
- return STF_FAIL + AUTHENTICATION_FAILED;
- update_iv(st);
-
- return STF_OK;
+ /* next message will be encrypted, but not this one.
+ * We could defer this calculation.
+ */
+ compute_dh_shared(st, st->st_gi);
+ if (!generate_skeyids_iv(st))
+ return STF_FAIL + AUTHENTICATION_FAILED;
+ update_iv(st);
+
+ return STF_OK;
}
/* STATE_MAIN_I2:
@@ -3478,172 +3340,174 @@ main_inI2_outR2(struct msg_digest *md)
*
* The following are not yet implemented.
* SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
- * --> HDR*, HASH_I
+ * --> HDR*, HASH_I
* SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r
- * --> HDR*, HASH_I
+ * --> HDR*, HASH_I
*/
-stf_status
-main_inR2_outI3(struct msg_digest *md)
+stf_status main_inR2_outI3(struct msg_digest *md)
{
- struct state *const st = md->st;
- pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
- pb_stream id_pbs; /* ID Payload; also used for hash calculation */
-
- certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
- cert_t mycert = st->st_connection->spd.this.cert;
- bool requested, send_cert, send_cr;
-
- bool RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
-
- int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
- /* KE in */
- RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
-
- /* Nr in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
-
- /* decode certificate requests */
- st->st_connection->got_certrequest = FALSE;
- decode_cr(md, st->st_connection);
-
- /* free collected certificate requests since as initiator
- * we don't heed them anyway
- */
- free_generalNames(st->st_connection->requested_ca, TRUE);
- st->st_connection->requested_ca = NULL;
-
- /* send certificate if auth is RSA, we have one and we want
- * or are requested to send it
- */
- requested = cert_policy == CERT_SEND_IF_ASKED
- && st->st_connection->got_certrequest;
- send_cert = RSA_auth && mycert.type != CERT_NONE
- && (cert_policy == CERT_ALWAYS_SEND || requested);
-
- /* send certificate request if we don't have a preloaded RSA public key */
- send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
-
- /* done parsing; initialize crypto */
- compute_dh_shared(st, st->st_gr, st->st_oakley.group);
- if (!generate_skeyids_iv(st))
- return STF_FAIL + AUTHENTICATION_FAILED;
-
- if (st->nat_traversal & NAT_T_WITH_NATD)
- {
- nat_traversal_natd_lookup(md);
- }
- if (st->nat_traversal)
- {
- nat_traversal_show_result(st->nat_traversal, md->sender_port);
- }
- if (st->nat_traversal & NAT_T_WITH_KA)
- {
- nat_traversal_new_ka_event();
- }
-
- /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
- /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
-
- /* HDR* out done */
-
- /* IDii out */
- {
- struct isakmp_ipsec_id id_hd;
- chunk_t id_b;
-
- build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
- id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
- if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs)
- || !out_chunk(id_b, &id_pbs, "my identity"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&id_pbs);
- }
+ struct state *const st = md->st;
+ pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
+ pb_stream id_pbs; /* ID Payload; also used for hash calculation */
- /* CERT out */
- if (RSA_auth)
- {
- DBG(DBG_CONTROL,
- DBG_log("our certificate policy is %s"
- , enum_name(&cert_policy_names, cert_policy))
- )
- if (mycert.type != CERT_NONE)
- {
- const char *request_text = "";
+ certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
+ cert_t mycert = st->st_connection->spd.this.cert;
+ bool requested, send_cert, send_cr;
+ bool pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
+
+ int auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
+ /* KE in */
+ RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
+
+ /* Nr in */
+ RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
+
+ /* decode certificate requests */
+ st->st_connection->got_certrequest = FALSE;
+ decode_cr(md, st->st_connection);
+
+ /* free collected certificate requests since as initiator
+ * we don't heed them anyway
+ */
+ free_generalNames(st->st_connection->requested_ca, TRUE);
+ st->st_connection->requested_ca = NULL;
+
+ /* send certificate if auth is RSA, we have one and we want
+ * or are requested to send it
+ */
+ requested = cert_policy == CERT_SEND_IF_ASKED
+ && st->st_connection->got_certrequest;
+ send_cert = pubkey_auth && mycert.type != CERT_NONE
+ && (cert_policy == CERT_ALWAYS_SEND || requested);
+
+ /* send certificate request if we don't have a preloaded RSA public key */
+ send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st);
- if (cert_policy == CERT_SEND_IF_ASKED)
- request_text = (send_cert)? "upon request":"without request";
- plog("we have a cert %s sending it %s"
- , send_cert? "and are":"but are not", request_text);
+ /* done parsing; initialize crypto */
+ compute_dh_shared(st, st->st_gr);
+ if (!generate_skeyids_iv(st))
+ return STF_FAIL + AUTHENTICATION_FAILED;
+
+ if (st->nat_traversal & NAT_T_WITH_NATD)
+ {
+ nat_traversal_natd_lookup(md);
}
- else
+ if (st->nat_traversal)
+ {
+ nat_traversal_show_result(st->nat_traversal, md->sender_port);
+ }
+ if (st->nat_traversal & NAT_T_WITH_KA)
{
- plog("we don't have a cert");
+ nat_traversal_new_ka_event();
}
- }
- if (send_cert)
- {
- pb_stream cert_pbs;
- struct isakmp_cert cert_hd;
- cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
+ /*************** build output packet HDR*;IDii;HASH/SIG_I ***************/
+ /* ??? NOTE: this is almost the same as main_inI3_outR3's code */
- if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&cert_pbs);
- }
+ /* HDR* out done */
- /* CR out */
- if (send_cr)
- {
- if (!build_and_ship_CR(mycert.type, st->st_connection->spd.that.ca
- , &md->rbody, ISAKMP_NEXT_SIG))
- return STF_INTERNAL_ERROR;
- }
+ /* IDii out */
+ {
+ struct isakmp_ipsec_id id_hd;
+ chunk_t id_b;
- /* HASH_I or SIG_I out */
- {
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len = main_mode_hash(st, hash_val, TRUE, &id_pbs);
+ build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
+ id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
+ if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &id_pbs)
+ || !out_chunk(id_b, &id_pbs, "my identity"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&id_pbs);
+ }
- if (auth_payload == ISAKMP_NEXT_HASH)
+ /* CERT out */
+ if (pubkey_auth)
{
- /* HASH_I out */
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody
- , hash_val, hash_len, "HASH_I"))
- return STF_INTERNAL_ERROR;
+ DBG(DBG_CONTROL,
+ DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
+ )
+ if (mycert.type != CERT_NONE)
+ {
+ const char *request_text = "";
+
+ if (cert_policy == CERT_SEND_IF_ASKED)
+ request_text = (send_cert)? "upon request":"without request";
+ plog("we have a cert %s sending it %s"
+ , send_cert? "and are":"but are not", request_text);
+ }
+ else
+ {
+ plog("we don't have a cert");
+ }
}
- else
+ if (send_cert)
{
- /* SIG_I out */
- u_char sig_val[RSA_MAX_OCTETS];
- size_t sig_len = RSA_sign_hash(st->st_connection
- , sig_val, hash_val, hash_len);
+ pb_stream cert_pbs;
- if (sig_len == 0)
- {
- loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature");
- return STF_FAIL + AUTHENTICATION_FAILED;
- }
+ struct isakmp_cert cert_hd;
+ cert_hd.isacert_np = (send_cr)? ISAKMP_NEXT_CR : ISAKMP_NEXT_SIG;
+ cert_hd.isacert_type = mycert.type;
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
- , &md->rbody, sig_val, sig_len, "SIG_I"))
- return STF_INTERNAL_ERROR;
+ if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
+ return STF_INTERNAL_ERROR;
+ if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&cert_pbs);
+ }
+
+ /* CR out */
+ if (send_cr)
+ {
+ if (!build_and_ship_CR(mycert.type, st->st_connection->spd.that.ca
+ , &md->rbody, ISAKMP_NEXT_SIG))
+ return STF_INTERNAL_ERROR;
+ }
+
+ /* HASH_I or SIG_I out */
+ {
+ u_char hash_buf[MAX_DIGEST_LEN];
+ chunk_t hash = chunk_from_buf(hash_buf);
+
+ main_mode_hash(st, &hash, TRUE, &id_pbs);
+
+ if (auth_payload == ISAKMP_NEXT_HASH)
+ {
+ /* HASH_I out */
+ if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody,
+ hash.ptr, hash.len, "HASH_I"))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ /* SIG_I out */
+ u_char sig_val[RSA_MAX_OCTETS];
+ signature_scheme_t scheme;
+ size_t sig_len;
+
+ scheme = oakley_to_signature_scheme(st->st_oakley.auth);
+
+ sig_len = sign_hash(scheme, st->st_connection, sig_val, hash);
+ if (sig_len == 0)
+ {
+ loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature");
+ return STF_FAIL + AUTHENTICATION_FAILED;
+ }
+
+ if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
+ , &md->rbody, sig_val, sig_len, "SIG_I"))
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* encrypt message, except for fixed part of header */
+ /* encrypt message, except for fixed part of header */
- /* st_new_iv was computed by generate_skeyids_iv */
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
+ /* st_new_iv was computed by generate_skeyids_iv */
+ if (!encrypt_message(&md->rbody, st))
+ return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
- return STF_OK;
+ return STF_OK;
}
/* Shared logic for asynchronous lookup of DNS KEY records.
@@ -3651,31 +3515,31 @@ main_inR2_outI3(struct msg_digest *md)
*/
enum key_oppo_step {
- kos_null,
- kos_his_txt
+ kos_null,
+ kos_his_txt
#ifdef USE_KEYRR
- , kos_his_key
+ , kos_his_key
#endif
};
struct key_continuation {
- struct adns_continuation ac; /* common prefix */
- struct msg_digest *md;
- enum key_oppo_step step;
- bool failure_ok;
- err_t last_ugh;
+ struct adns_continuation ac; /* common prefix */
+ struct msg_digest *md;
+ enum key_oppo_step step;
+ bool failure_ok;
+ err_t last_ugh;
};
typedef stf_status (key_tail_fn)(struct msg_digest *md
- , struct key_continuation *kc);
-static void
-report_key_dns_failure(struct id *id, err_t ugh)
+ , struct key_continuation *kc);
+
+static void report_key_dns_failure(struct id *id, err_t ugh)
{
- char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
+ char id_buf[BUF_LEN]; /* arbitrary limit on length of ID reported */
- (void) idtoa(id, id_buf, sizeof(id_buf));
- loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
- "; DNS search for KEY failed (%s)", id_buf, ugh);
+ (void) idtoa(id, id_buf, sizeof(id_buf));
+ loglog(RC_LOG_SERIOUS, "no RSA public key known for '%s'"
+ "; DNS search for KEY failed (%s)", id_buf, ugh);
}
@@ -3688,135 +3552,145 @@ report_key_dns_failure(struct id *id, err_t ugh)
*/
static stf_status
main_id_and_auth(struct msg_digest *md
- , bool initiator /* are we the Initiator? */
- , cont_fn_t cont_fn /* continuation function */
- , const struct key_continuation *kc /* current state, can be NULL */
+ , bool initiator /* are we the Initiator? */
+ , cont_fn_t cont_fn /* continuation function */
+ , const struct key_continuation *kc /* current state, can be NULL */
)
{
- struct state *st = md->st;
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len;
- struct id peer;
- stf_status r = STF_OK;
-
- /* ID Payload in */
- if (!decode_peer_id(md, &peer))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* Hash the ID Payload.
- * main_mode_hash requires idpl->cur to be at end of payload
- * so we temporarily set if so.
- */
- {
- pb_stream *idpl = &md->chain[ISAKMP_NEXT_ID]->pbs;
- u_int8_t *old_cur = idpl->cur;
-
- idpl->cur = idpl->roof;
- hash_len = main_mode_hash(st, hash_val, !initiator, idpl);
- idpl->cur = old_cur;
- }
-
- switch (st->st_oakley.auth)
- {
- case OAKLEY_PRESHARED_KEY:
- case XAUTHInitPreShared:
- case XAUTHRespPreShared:
- {
- pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
-
- if (pbs_left(hash_pbs) != hash_len
- || memcmp(hash_pbs->cur, hash_val, hash_len) != 0)
- {
- DBG_cond_dump(DBG_CRYPT, "received HASH:"
- , hash_pbs->cur, pbs_left(hash_pbs));
- loglog(RC_LOG_SERIOUS, "received Hash Payload does not match computed value");
- /* XXX Could send notification back */
- r = STF_FAIL + INVALID_HASH_INFORMATION;
- }
+ u_char hash_buf[MAX_DIGEST_LEN];
+ chunk_t hash = chunk_from_buf(hash_buf);
+ struct state *st = md->st;
+ struct id peer;
+ stf_status r = STF_OK;
+
+ /* ID Payload in */
+ if (!decode_peer_id(md, &peer))
+ return STF_FAIL + INVALID_ID_INFORMATION;
+
+ /* Hash the ID Payload.
+ * main_mode_hash requires idpl->cur to be at end of payload
+ * so we temporarily set if so.
+ */
+ {
+ pb_stream *idpl = &md->chain[ISAKMP_NEXT_ID]->pbs;
+ u_int8_t *old_cur = idpl->cur;
+
+ idpl->cur = idpl->roof;
+ main_mode_hash(st, &hash, !initiator, idpl);
+ idpl->cur = old_cur;
}
- break;
- case OAKLEY_RSA_SIG:
- case XAUTHInitRSA:
- case XAUTHRespRSA:
- r = RSA_check_signature(&peer, st, hash_val, hash_len
- , &md->chain[ISAKMP_NEXT_SIG]->pbs
+ switch (st->st_oakley.auth)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ case XAUTHInitPreShared:
+ case XAUTHRespPreShared:
+ {
+ pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs;
+
+ if (pbs_left(hash_pbs) != hash.len
+ || memcmp(hash_pbs->cur, hash.ptr, hash.len) != 0)
+ {
+ DBG_cond_dump(DBG_CRYPT, "received HASH:"
+ , hash_pbs->cur, pbs_left(hash_pbs));
+ loglog(RC_LOG_SERIOUS, "received Hash Payload does not match computed value");
+ /* XXX Could send notification back */
+ r = STF_FAIL + INVALID_HASH_INFORMATION;
+ }
+ }
+ break;
+
+ case OAKLEY_RSA_SIG:
+ case XAUTHInitRSA:
+ case XAUTHRespRSA:
+ r = check_signature(KEY_RSA, &peer, st, hash,
+ &md->chain[ISAKMP_NEXT_SIG]->pbs,
#ifdef USE_KEYRR
- , kc == NULL? NULL : kc->ac.keys_from_dns
+ kc == NULL? NULL : kc->ac.keys_from_dns,
#endif /* USE_KEYRR */
- , kc == NULL? NULL : kc->ac.gateways_from_dns
- );
-
- if (r == STF_SUSPEND)
- {
- /* initiate/resume asynchronous DNS lookup for key */
- struct key_continuation *nkc
- = alloc_thing(struct key_continuation, "key continuation");
- enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
- err_t ugh = NULL;
+ kc == NULL? NULL : kc->ac.gateways_from_dns
+ );
+
+ if (r == STF_SUSPEND)
+ {
+ /* initiate/resume asynchronous DNS lookup for key */
+ struct key_continuation *nkc = malloc_thing(struct key_continuation);
+ enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
+ err_t ugh = NULL;
- /* Record that state is used by a suspended md */
- passert(st->st_suspended_md == NULL);
- st->st_suspended_md = md;
+ /* Record that state is used by a suspended md */
+ passert(st->st_suspended_md == NULL);
+ st->st_suspended_md = md;
- nkc->failure_ok = FALSE;
- nkc->md = md;
+ nkc->failure_ok = FALSE;
+ nkc->md = md;
- switch (step_done)
- {
- case kos_null:
- /* first try: look for the TXT records */
- nkc->step = kos_his_txt;
+ switch (step_done)
+ {
+ case kos_null:
+ /* first try: look for the TXT records */
+ nkc->step = kos_his_txt;
#ifdef USE_KEYRR
- nkc->failure_ok = TRUE;
+ nkc->failure_ok = TRUE;
#endif
- ugh = start_adns_query(&peer
- , &peer /* SG itself */
- , T_TXT
- , cont_fn
- , &nkc->ac);
- break;
+ ugh = start_adns_query(&peer
+ , &peer /* SG itself */
+ , T_TXT
+ , cont_fn
+ , &nkc->ac);
+ break;
#ifdef USE_KEYRR
- case kos_his_txt:
- /* second try: look for the KEY records */
- nkc->step = kos_his_key;
- ugh = start_adns_query(&peer
- , NULL /* no sgw for KEY */
- , T_KEY
- , cont_fn
- , &nkc->ac);
- break;
+ case kos_his_txt:
+ /* second try: look for the KEY records */
+ nkc->step = kos_his_key;
+ ugh = start_adns_query(&peer
+ , NULL /* no sgw for KEY */
+ , T_KEY
+ , cont_fn
+ , &nkc->ac);
+ break;
#endif /* USE_KEYRR */
- default:
- bad_case(step_done);
- }
+ default:
+ bad_case(step_done);
+ }
- if (ugh != NULL)
- {
- report_key_dns_failure(&peer, ugh);
- st->st_suspended_md = NULL;
- r = STF_FAIL + INVALID_KEY_INFORMATION;
- }
- }
- break;
+ if (ugh != NULL)
+ {
+ report_key_dns_failure(&peer, ugh);
+ st->st_suspended_md = NULL;
+ r = STF_FAIL + INVALID_KEY_INFORMATION;
+ }
+ }
+ break;
- default:
- bad_case(st->st_oakley.auth);
- }
- if (r != STF_OK)
- return r;
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ r = check_signature(KEY_ECDSA, &peer, st, hash,
+ &md->chain[ISAKMP_NEXT_SIG]->pbs,
+#ifdef USE_KEYRR
+ NULL,
+#endif /* USE_KEYRR */
+ NULL);
+ break;
+
+ default:
+ bad_case(st->st_oakley.auth);
+ }
+ if (r != STF_OK)
+ return r;
- DBG(DBG_CRYPT, DBG_log("authentication succeeded"));
+ DBG(DBG_CRYPT, DBG_log("authentication succeeded"));
- /*
- * With the peer ID known, let's see if we need to switch connections.
- */
- if (!switch_connection(md, &peer, initiator))
- return STF_FAIL + INVALID_ID_INFORMATION;
+ /*
+ * With the peer ID known, let's see if we need to switch connections.
+ */
+ if (!switch_connection(md, &peer, initiator))
+ return STF_FAIL + INVALID_ID_INFORMATION;
- return r;
+ return r;
}
/* This continuation is called as part of either
@@ -3840,46 +3714,44 @@ main_id_and_auth(struct msg_digest *md
* to find authentication, or we run out of things
* to try.
*/
-static void
-key_continue(struct adns_continuation *cr
-, err_t ugh
-, key_tail_fn *tail)
+static void key_continue(struct adns_continuation *cr, err_t ugh,
+ key_tail_fn *tail)
{
- struct key_continuation *kc = (void *)cr;
- struct state *st = kc->md->st;
+ struct key_continuation *kc = (void *)cr;
+ struct state *st = kc->md->st;
- passert(cur_state == NULL);
+ passert(cur_state == NULL);
- /* if st == NULL, our state has been deleted -- just clean up */
- if (st != NULL)
- {
- stf_status r;
+ /* if st == NULL, our state has been deleted -- just clean up */
+ if (st != NULL)
+ {
+ stf_status r;
- passert(st->st_suspended_md == kc->md);
- st->st_suspended_md = NULL; /* no longer connected or suspended */
- cur_state = st;
+ passert(st->st_suspended_md == kc->md);
+ st->st_suspended_md = NULL; /* no longer connected or suspended */
+ cur_state = st;
- if (!kc->failure_ok && ugh != NULL)
- {
- report_key_dns_failure(&st->st_connection->spd.that.id, ugh);
- r = STF_FAIL + INVALID_KEY_INFORMATION;
- }
- else
- {
+ if (!kc->failure_ok && ugh != NULL)
+ {
+ report_key_dns_failure(&st->st_connection->spd.that.id, ugh);
+ r = STF_FAIL + INVALID_KEY_INFORMATION;
+ }
+ else
+ {
#ifdef USE_KEYRR
- passert(kc->step == kos_his_txt || kc->step == kos_his_key);
+ passert(kc->step == kos_his_txt || kc->step == kos_his_key);
#else
- passert(kc->step == kos_his_txt);
+ passert(kc->step == kos_his_txt);
#endif
- kc->last_ugh = ugh; /* record previous error in case we need it */
- r = (*tail)(kc->md, kc);
- }
- complete_state_transition(&kc->md, r);
- }
- if (kc->md != NULL)
- release_md(kc->md);
- cur_state = NULL;
+ kc->last_ugh = ugh; /* record previous error in case we need it */
+ r = (*tail)(kc->md, kc);
+ }
+ complete_state_transition(&kc->md, r);
+ }
+ if (kc->md != NULL)
+ release_md(kc->md);
+ cur_state = NULL;
}
/* STATE_MAIN_R2:
@@ -3893,174 +3765,173 @@ key_continue(struct adns_continuation *cr
* - main_inI3_outR3_tail to finish or suspend for DNS lookup
* - main_inI3_outR3_continue to start main_inI3_outR3_tail again
*/
-static key_tail_fn main_inI3_outR3_tail; /* forward */
+static key_tail_fn main_inI3_outR3_tail; /* forward */
-stf_status
-main_inI3_outR3(struct msg_digest *md)
+stf_status main_inI3_outR3(struct msg_digest *md)
{
- return main_inI3_outR3_tail(md, NULL);
+ return main_inI3_outR3_tail(md, NULL);
}
-static void
-main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
+static void main_inI3_outR3_continue(struct adns_continuation *cr, err_t ugh)
{
- key_continue(cr, ugh, main_inI3_outR3_tail);
+ key_continue(cr, ugh, main_inI3_outR3_tail);
}
static stf_status
main_inI3_outR3_tail(struct msg_digest *md
, struct key_continuation *kc)
{
- struct state *const st = md->st;
- u_int8_t auth_payload;
- pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
- certpolicy_t cert_policy;
- cert_t mycert;
- bool RSA_auth;
- bool send_cert;
- bool requested;
-
- /* ID and HASH_I or SIG_I in
- * Note: this may switch the connection being used!
- */
- {
- stf_status r = main_id_and_auth(md, FALSE
- , main_inI3_outR3_continue
- , kc);
-
- if (r != STF_OK)
- return r;
- }
-
- /* send certificate if auth is RSA, we have one and we want
- * or are requested to send it
- */
- cert_policy = st->st_connection->spd.this.sendcert;
- mycert = st->st_connection->spd.this.cert;
- requested = cert_policy == CERT_SEND_IF_ASKED
- && st->st_connection->got_certrequest;
- RSA_auth = st->st_oakley.auth == OAKLEY_RSA_SIG
- || st->st_oakley.auth == XAUTHInitRSA
- || st->st_oakley.auth == XAUTHRespRSA;
- send_cert = RSA_auth
- && mycert.type != CERT_NONE
- && (cert_policy == CERT_ALWAYS_SEND || requested);
-
- /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
- /* proccess_packet() would automatically generate the HDR*
- * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
- * We don't do this because we wish there to be no partially
- * built output packet if we need to suspend for asynch DNS.
- */
- /* ??? NOTE: this is almost the same as main_inR2_outI3's code */
-
- /* HDR* out
- * If auth were PKE_AUTH or RPKE_AUTH, ISAKMP_NEXT_HASH would
- * be first payload.
- */
- echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
-
- auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
-
- /* IDir out */
- {
- /* id_hd should be struct isakmp_id, but struct isakmp_ipsec_id
- * allows build_id_payload() to work for both phases.
+ struct state *const st = md->st;
+ u_int8_t auth_payload;
+ pb_stream r_id_pbs; /* ID Payload; also used for hash calculation */
+ certpolicy_t cert_policy;
+ cert_t mycert;
+ bool pubkey_auth, send_cert, requested;
+
+ /* ID and HASH_I or SIG_I in
+ * Note: this may switch the connection being used!
*/
- struct isakmp_ipsec_id id_hd;
- chunk_t id_b;
-
- build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
- id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
- if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &r_id_pbs)
- || !out_chunk(id_b, &r_id_pbs, "my identity"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&r_id_pbs);
- }
-
- /* CERT out */
- if (RSA_auth)
- {
- DBG(DBG_CONTROL,
- DBG_log("our certificate policy is %s"
- , enum_name(&cert_policy_names, cert_policy))
- )
- if (mycert.type != CERT_NONE)
{
- const char *request_text = "";
+ stf_status r = main_id_and_auth(md, FALSE
+ , main_inI3_outR3_continue
+ , kc);
- if (cert_policy == CERT_SEND_IF_ASKED)
- request_text = (send_cert)? "upon request":"without request";
- plog("we have a cert %s sending it %s"
- , send_cert? "and are":"but are not", request_text);
+ if (r != STF_OK)
+ return r;
}
- else
+
+ /* send certificate if pubkey authentication is used, we have one
+ * and we want or are requested to send it
+ */
+ cert_policy = st->st_connection->spd.this.sendcert;
+ mycert = st->st_connection->spd.this.cert;
+ requested = cert_policy == CERT_SEND_IF_ASKED
+ && st->st_connection->got_certrequest;
+ pubkey_auth = uses_pubkey_auth(st->st_oakley.auth);
+ send_cert = pubkey_auth && mycert.type != CERT_NONE &&
+ (cert_policy == CERT_ALWAYS_SEND || requested);
+
+ /*************** build output packet HDR*;IDir;HASH/SIG_R ***************/
+ /* proccess_packet() would automatically generate the HDR*
+ * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
+ * We don't do this because we wish there to be no partially
+ * built output packet if we need to suspend for asynch DNS.
+ */
+ /* ??? NOTE: this is almost the same as main_inR2_outI3's code */
+
+ /* HDR* out
+ * If auth were PKE_AUTH or RPKE_AUTH, ISAKMP_NEXT_HASH would
+ * be first payload.
+ */
+ echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
+
+ auth_payload = pubkey_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
+ /* IDir out */
{
- plog("we don't have a cert");
+ /* id_hd should be struct isakmp_id, but struct isakmp_ipsec_id
+ * allows build_id_payload() to work for both phases.
+ */
+ struct isakmp_ipsec_id id_hd;
+ chunk_t id_b;
+
+ build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);
+ id_hd.isaiid_np = (send_cert)? ISAKMP_NEXT_CERT : auth_payload;
+ if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &md->rbody, &r_id_pbs)
+ || !out_chunk(id_b, &r_id_pbs, "my identity"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&r_id_pbs);
}
- }
- if (send_cert)
- {
- pb_stream cert_pbs;
- struct isakmp_cert cert_hd;
- cert_hd.isacert_np = ISAKMP_NEXT_SIG;
- cert_hd.isacert_type = mycert.type;
+ /* CERT out */
+ if (pubkey_auth)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("our certificate policy is %N", cert_policy_names, cert_policy)
+ )
+ if (mycert.type != CERT_NONE)
+ {
+ const char *request_text = "";
- if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_chunk(get_mycert(mycert), &cert_pbs, "CERT"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&cert_pbs);
- }
+ if (cert_policy == CERT_SEND_IF_ASKED)
+ request_text = (send_cert)? "upon request":"without request";
+ plog("we have a cert %s sending it %s"
+ , send_cert? "and are":"but are not", request_text);
+ }
+ else
+ {
+ plog("we don't have a cert");
+ }
+ }
+ if (send_cert)
+ {
+ pb_stream cert_pbs;
- /* HASH_R or SIG_R out */
- {
- u_char hash_val[MAX_DIGEST_LEN];
- size_t hash_len = main_mode_hash(st, hash_val, FALSE, &r_id_pbs);
+ struct isakmp_cert cert_hd;
+ cert_hd.isacert_np = ISAKMP_NEXT_SIG;
+ cert_hd.isacert_type = mycert.type;
- if (auth_payload == ISAKMP_NEXT_HASH)
- {
- /* HASH_R out */
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody
- , hash_val, hash_len, "HASH_R"))
+ if (!out_struct(&cert_hd, &isakmp_ipsec_certificate_desc, &md->rbody, &cert_pbs))
return STF_INTERNAL_ERROR;
+ if (!out_chunk(cert_get_encoding(mycert), &cert_pbs, "CERT"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&cert_pbs);
}
- else
+
+ /* HASH_R or SIG_R out */
{
- /* SIG_R out */
- u_char sig_val[RSA_MAX_OCTETS];
- size_t sig_len = RSA_sign_hash(st->st_connection
- , sig_val, hash_val, hash_len);
+ u_char hash_buf[MAX_DIGEST_LEN];
+ chunk_t hash = chunk_from_buf(hash_buf);
- if (sig_len == 0)
- {
- loglog(RC_LOG_SERIOUS, "unable to locate my private key for RSA Signature");
- return STF_FAIL + AUTHENTICATION_FAILED;
- }
+ main_mode_hash(st, &hash, FALSE, &r_id_pbs);
- if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
- , &md->rbody, sig_val, sig_len, "SIG_R"))
- return STF_INTERNAL_ERROR;
+ if (auth_payload == ISAKMP_NEXT_HASH)
+ {
+ /* HASH_R out */
+ if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_hash_desc, &md->rbody,
+ hash.ptr, hash.len, "HASH_R"))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ /* SIG_R out */
+ u_char sig_val[RSA_MAX_OCTETS];
+ signature_scheme_t scheme;
+ size_t sig_len;
+
+ scheme = oakley_to_signature_scheme(st->st_oakley.auth);
+
+ sig_len = sign_hash(scheme, st->st_connection, sig_val, hash);
+ if (sig_len == 0)
+ {
+ loglog(RC_LOG_SERIOUS, "unable to locate my private key for signature");
+ return STF_FAIL + AUTHENTICATION_FAILED;
+ }
+
+ if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_signature_desc
+ , &md->rbody, sig_val, sig_len, "SIG_R"))
+ return STF_INTERNAL_ERROR;
+ }
}
- }
- /* encrypt message, sans fixed part of header */
+ /* encrypt message, sans fixed part of header */
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
+ if (!encrypt_message(&md->rbody, st))
+ return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
- /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */
- DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:"
- , st->st_new_iv, st->st_new_iv_len);
+ /* Last block of Phase 1 (R3), kept for Phase 2 IV generation */
+ DBG_cond_dump(DBG_CRYPT, "last encrypted block of Phase 1:"
+ , st->st_new_iv, st->st_new_iv_len);
- ISAKMP_SA_established(st->st_connection, st->st_serialno);
+ ISAKMP_SA_established(st->st_connection, st->st_serialno);
- /* Save Phase 1 IV */
- st->st_ph1_iv_len = st->st_new_iv_len;
- set_ph1_iv(st, st->st_new_iv);
+ /* Save Phase 1 IV */
+ st->st_ph1_iv_len = st->st_new_iv_len;
+ set_ph1_iv(st, st->st_new_iv);
- return STF_OK;
+ return STF_OK;
}
/* STATE_MAIN_I3:
@@ -4073,48 +3944,45 @@ main_inI3_outR3_tail(struct msg_digest *md
* - main_inR3_continue to start main_inR3_tail again
*/
-static key_tail_fn main_inR3_tail; /* forward */
+static key_tail_fn main_inR3_tail; /* forward */
-stf_status
-main_inR3(struct msg_digest *md)
+stf_status main_inR3(struct msg_digest *md)
{
- return main_inR3_tail(md, NULL);
+ return main_inR3_tail(md, NULL);
}
-static void
-main_inR3_continue(struct adns_continuation *cr, err_t ugh)
+static void main_inR3_continue(struct adns_continuation *cr, err_t ugh)
{
- key_continue(cr, ugh, main_inR3_tail);
+ key_continue(cr, ugh, main_inR3_tail);
}
-static stf_status
-main_inR3_tail(struct msg_digest *md
-, struct key_continuation *kc)
+static stf_status main_inR3_tail(struct msg_digest *md,
+ struct key_continuation *kc)
{
- struct state *const st = md->st;
+ struct state *const st = md->st;
- /* ID and HASH_R or SIG_R in
- * Note: this may switch the connection being used!
- */
- {
- stf_status r = main_id_and_auth(md, TRUE, main_inR3_continue, kc);
+ /* ID and HASH_R or SIG_R in
+ * Note: this may switch the connection being used!
+ */
+ {
+ stf_status r = main_id_and_auth(md, TRUE, main_inR3_continue, kc);
- if (r != STF_OK)
- return r;
- }
+ if (r != STF_OK)
+ return r;
+ }
- /**************** done input ****************/
+ /**************** done input ****************/
- ISAKMP_SA_established(st->st_connection, st->st_serialno);
+ ISAKMP_SA_established(st->st_connection, st->st_serialno);
- /* Save Phase 1 IV */
- st->st_ph1_iv_len = st->st_new_iv_len;
- set_ph1_iv(st, st->st_new_iv);
+ /* Save Phase 1 IV */
+ st->st_ph1_iv_len = st->st_new_iv_len;
+ set_ph1_iv(st, st->st_new_iv);
- update_iv(st); /* finalize our Phase 1 IV */
+ update_iv(st); /* finalize our Phase 1 IV */
- return STF_OK;
+ return STF_OK;
}
/* Handle first message of Phase 2 -- Quick Mode.
@@ -4182,15 +4050,15 @@ main_inR3_tail(struct msg_digest *md
*/
enum verify_oppo_step {
- vos_fail,
- vos_start,
- vos_our_client,
- vos_our_txt,
+ vos_fail,
+ vos_start,
+ vos_our_client,
+ vos_our_txt,
#ifdef USE_KEYRR
- vos_our_key,
+ vos_our_key,
#endif /* USE_KEYRR */
- vos_his_client,
- vos_done
+ vos_his_client,
+ vos_done
};
static const char *const verify_step_name[] = {
@@ -4207,834 +4075,833 @@ static const char *const verify_step_name[] = {
/* hold anything we can handle of a Phase 2 ID */
struct p2id {
- ip_subnet net;
- u_int8_t proto;
- u_int16_t port;
+ ip_subnet net;
+ u_int8_t proto;
+ u_int16_t port;
};
struct verify_oppo_bundle {
- enum verify_oppo_step step;
- bool failure_ok; /* if true, quick_inI1_outR1_continue will try
- * other things on DNS failure */
- struct msg_digest *md;
- struct p2id my, his;
- unsigned int new_iv_len; /* p1st's might change */
- u_char new_iv[MAX_DIGEST_LEN];
- /* int whackfd; */ /* not needed because we are Responder */
+ enum verify_oppo_step step;
+ bool failure_ok; /* if true, quick_inI1_outR1_continue will try
+ * other things on DNS failure */
+ struct msg_digest *md;
+ struct p2id my, his;
+ unsigned int new_iv_len; /* p1st's might change */
+ u_char new_iv[MAX_DIGEST_LEN];
+ /* int whackfd; */ /* not needed because we are Responder */
};
struct verify_oppo_continuation {
- struct adns_continuation ac; /* common prefix */
- struct verify_oppo_bundle b;
+ struct adns_continuation ac; /* common prefix */
+ struct verify_oppo_bundle b;
};
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b
- , struct adns_continuation *ac);
+ , struct adns_continuation *ac);
-stf_status
-quick_inI1_outR1(struct msg_digest *md)
+stf_status quick_inI1_outR1(struct msg_digest *md)
{
- const struct state *const p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
- struct verify_oppo_bundle b;
-
- /* HASH(1) in */
- CHECK_QUICK_HASH(md
- , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
- , p1st, &md->hdr.isa_msgid, FALSE)
- , "HASH(1)", "Quick I1");
-
- /* [ IDci, IDcr ] in
- * We do this now (probably out of physical order) because
- * we wish to select the correct connection before we consult
- * it for policy.
- */
-
- if (id_pd != NULL)
- {
- /* ??? we are assuming IPSEC_DOI */
-
- /* IDci (initiator is peer) */
-
- if (!decode_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
- , &b.his.net, "peer client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- /* Hack for MS 818043 NAT-T Update */
-
- if (id_pd->payload.ipsec_id.isaiid_idtype == ID_FQDN)
- happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
-
- /* End Hack for MS 818043 NAT-T Update */
-
- b.his.proto = id_pd->payload.ipsec_id.isaiid_protoid;
- b.his.port = id_pd->payload.ipsec_id.isaiid_port;
- b.his.net.addr.u.v4.sin_port = htons(b.his.port);
-
- /* IDcr (we are responder) */
-
- if (!decode_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
- , &b.my.net, "our client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
-
- b.my.proto = id_pd->next->payload.ipsec_id.isaiid_protoid;
- b.my.port = id_pd->next->payload.ipsec_id.isaiid_port;
- b.my.net.addr.u.v4.sin_port = htons(b.my.port);
- }
- else
- {
- /* implicit IDci and IDcr: peer and self */
- if (!sameaddrtype(&c->spd.this.host_addr, &c->spd.that.host_addr))
- return STF_FAIL;
-
- happy(addrtosubnet(&c->spd.this.host_addr, &b.my.net));
- happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
- b.his.proto = b.my.proto = 0;
- b.his.port = b.my.port = 0;
- }
- b.step = vos_start;
- b.md = md;
- b.new_iv_len = p1st->st_new_iv_len;
- memcpy(b.new_iv, p1st->st_new_iv, p1st->st_new_iv_len);
- return quick_inI1_outR1_tail(&b, NULL);
+ const struct state *const p1st = md->st;
+ struct connection *c = p1st->st_connection;
+ struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
+ struct verify_oppo_bundle b;
+
+ /* HASH(1) in */
+ CHECK_QUICK_HASH(md
+ , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
+ , p1st, &md->hdr.isa_msgid, FALSE)
+ , "HASH(1)", "Quick I1");
+
+ /* [ IDci, IDcr ] in
+ * We do this now (probably out of physical order) because
+ * we wish to select the correct connection before we consult
+ * it for policy.
+ */
+
+ if (id_pd != NULL)
+ {
+ /* ??? we are assuming IPSEC_DOI */
+
+ /* IDci (initiator is peer) */
+
+ if (!decode_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
+ , &b.his.net, "peer client"))
+ return STF_FAIL + INVALID_ID_INFORMATION;
+
+ /* Hack for MS 818043 NAT-T Update */
+
+ if (id_pd->payload.ipsec_id.isaiid_idtype == ID_FQDN)
+ happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
+
+ /* End Hack for MS 818043 NAT-T Update */
+
+ b.his.proto = id_pd->payload.ipsec_id.isaiid_protoid;
+ b.his.port = id_pd->payload.ipsec_id.isaiid_port;
+ b.his.net.addr.u.v4.sin_port = htons(b.his.port);
+
+ /* IDcr (we are responder) */
+
+ if (!decode_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
+ , &b.my.net, "our client"))
+ return STF_FAIL + INVALID_ID_INFORMATION;
+
+ b.my.proto = id_pd->next->payload.ipsec_id.isaiid_protoid;
+ b.my.port = id_pd->next->payload.ipsec_id.isaiid_port;
+ b.my.net.addr.u.v4.sin_port = htons(b.my.port);
+ }
+ else
+ {
+ /* implicit IDci and IDcr: peer and self */
+ if (!sameaddrtype(&c->spd.this.host_addr, &c->spd.that.host_addr))
+ return STF_FAIL;
+
+ happy(addrtosubnet(&c->spd.this.host_addr, &b.my.net));
+ happy(addrtosubnet(&c->spd.that.host_addr, &b.his.net));
+ b.his.proto = b.my.proto = 0;
+ b.his.port = b.my.port = 0;
+ }
+ b.step = vos_start;
+ b.md = md;
+ b.new_iv_len = p1st->st_new_iv_len;
+ memcpy(b.new_iv, p1st->st_new_iv, p1st->st_new_iv_len);
+ return quick_inI1_outR1_tail(&b, NULL);
}
static void
report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
{
- struct state *st = b->md->st;
- char fgwb[ADDRTOT_BUF]
- , cb[ADDRTOT_BUF];
- ip_address client;
- err_t which = NULL;
-
- switch (b->step)
- {
- case vos_our_client:
- case vos_our_txt:
+ struct state *st = b->md->st;
+ char fgwb[ADDRTOT_BUF]
+ , cb[ADDRTOT_BUF];
+ ip_address client;
+ err_t which = NULL;
+
+ switch (b->step)
+ {
+ case vos_our_client:
+ case vos_our_txt:
#ifdef USE_KEYRR
- case vos_our_key:
+ case vos_our_key:
#endif /* USE_KEYRR */
- which = "our";
- networkof(&b->my.net, &client);
- break;
-
- case vos_his_client:
- which = "his";
- networkof(&b->his.net, &client);
- break;
-
- case vos_start:
- case vos_done:
- case vos_fail:
- default:
- bad_case(b->step);
- }
-
- addrtot(&st->st_connection->spd.that.host_addr, 0, fgwb, sizeof(fgwb));
- addrtot(&client, 0, cb, sizeof(cb));
- loglog(RC_OPPOFAILURE
- , "gateway %s wants connection with %s as %s client, but DNS fails to confirm delegation: %s"
- , fgwb, cb, which, ugh);
+ which = "our";
+ networkof(&b->my.net, &client);
+ break;
+
+ case vos_his_client:
+ which = "his";
+ networkof(&b->his.net, &client);
+ break;
+
+ case vos_start:
+ case vos_done:
+ case vos_fail:
+ default:
+ bad_case(b->step);
+ }
+
+ addrtot(&st->st_connection->spd.that.host_addr, 0, fgwb, sizeof(fgwb));
+ addrtot(&client, 0, cb, sizeof(cb));
+ loglog(RC_OPPOFAILURE
+ , "gateway %s wants connection with %s as %s client, but DNS fails to confirm delegation: %s"
+ , fgwb, cb, which, ugh);
}
-static void
-quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
+static void quick_inI1_outR1_continue(struct adns_continuation *cr, err_t ugh)
{
- stf_status r;
- struct verify_oppo_continuation *vc = (void *)cr;
- struct verify_oppo_bundle *b = &vc->b;
- struct state *st = b->md->st;
-
- passert(cur_state == NULL);
- /* if st == NULL, our state has been deleted -- just clean up */
- if (st != NULL)
- {
- passert(st->st_suspended_md == b->md);
- st->st_suspended_md = NULL; /* no longer connected or suspended */
- cur_state = st;
- if (!b->failure_ok && ugh != NULL)
- {
- report_verify_failure(b, ugh);
- r = STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
+ stf_status r;
+ struct verify_oppo_continuation *vc = (void *)cr;
+ struct verify_oppo_bundle *b = &vc->b;
+ struct state *st = b->md->st;
+
+ passert(cur_state == NULL);
+ /* if st == NULL, our state has been deleted -- just clean up */
+ if (st != NULL)
{
- r = quick_inI1_outR1_tail(b, cr);
+ passert(st->st_suspended_md == b->md);
+ st->st_suspended_md = NULL; /* no longer connected or suspended */
+ cur_state = st;
+ if (!b->failure_ok && ugh != NULL)
+ {
+ report_verify_failure(b, ugh);
+ r = STF_FAIL + INVALID_ID_INFORMATION;
+ }
+ else
+ {
+ r = quick_inI1_outR1_tail(b, cr);
+ }
+ complete_state_transition(&b->md, r);
}
- complete_state_transition(&b->md, r);
- }
- if (b->md != NULL)
- release_md(b->md);
- cur_state = NULL;
+ if (b->md != NULL)
+ release_md(b->md);
+ cur_state = NULL;
}
-static stf_status
-quick_inI1_outR1_start_query(struct verify_oppo_bundle *b
-, enum verify_oppo_step next_step)
+static stf_status quick_inI1_outR1_start_query(struct verify_oppo_bundle *b,
+ enum verify_oppo_step next_step)
{
- struct msg_digest *md = b->md;
- struct state *p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct verify_oppo_continuation *vc
- = alloc_thing(struct verify_oppo_continuation, "verify continuation");
- struct id id /* subject of query */
- , *our_id /* needed for myid playing */
- , our_id_space; /* ephemeral: no need for unshare_id_content */
- ip_address client;
- err_t ugh = NULL;
-
- /* Record that state is used by a suspended md */
- b->step = next_step; /* not just vc->b.step */
- vc->b = *b;
- passert(p1st->st_suspended_md == NULL);
- p1st->st_suspended_md = b->md;
-
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
- DBG_log("responding with DNS query - from %s to %s new state: %s"
- , ours, his, verify_step_name[b->step]);
- });
-
- /* Resolve %myid in a cheesy way.
- * We have to do the resolution because start_adns_query
- * et al have insufficient information to do so.
- * If %myid is already known, we'll use that value
- * (XXX this may be a mistake: it could be stale).
- * If %myid is unknown, we should check to see if
- * there are credentials for the IP address or the FQDN.
- * Instead, we'll just assume the IP address since we are
- * acting as the responder and only the IP address would
- * have gotten it to us.
- * We don't even try to do this for the other side:
- * %myid makes no sense for the other side (but it is syntactically
- * legal).
- */
- our_id = resolve_myid(&c->spd.this.id);
- if (our_id->kind == ID_NONE)
- {
- iptoid(&c->spd.this.host_addr, &our_id_space);
- our_id = &our_id_space;
- }
-
- switch (next_step)
- {
- case vos_our_client:
- networkof(&b->my.net, &client);
- iptoid(&client, &id);
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&id
- , our_id
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-
- case vos_our_txt:
- vc->b.failure_ok = b->failure_ok = TRUE;
- ugh = start_adns_query(our_id
- , our_id /* self as SG */
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
+ struct msg_digest *md = b->md;
+ struct state *p1st = md->st;
+ struct connection *c = p1st->st_connection;
+ struct verify_oppo_continuation *vc = malloc_thing(struct verify_oppo_continuation);
+ struct id id /* subject of query */
+ , *our_id /* needed for myid playing */
+ , our_id_space; /* ephemeral: no need for unshare_id_content */
+ ip_address client;
+ err_t ugh = NULL;
+
+ /* Record that state is used by a suspended md */
+ b->step = next_step; /* not just vc->b.step */
+ vc->b = *b;
+ passert(p1st->st_suspended_md == NULL);
+ p1st->st_suspended_md = b->md;
+
+ DBG(DBG_CONTROL,
+ {
+ char ours[SUBNETTOT_BUF];
+ char his[SUBNETTOT_BUF];
+
+ subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
+ subnettot(&c->spd.that.client, 0, his, sizeof(his));
+
+ DBG_log("responding with DNS query - from %s to %s new state: %s"
+ , ours, his, verify_step_name[b->step]);
+ });
+
+ /* Resolve %myid in a cheesy way.
+ * We have to do the resolution because start_adns_query
+ * et al have insufficient information to do so.
+ * If %myid is already known, we'll use that value
+ * (XXX this may be a mistake: it could be stale).
+ * If %myid is unknown, we should check to see if
+ * there are credentials for the IP address or the FQDN.
+ * Instead, we'll just assume the IP address since we are
+ * acting as the responder and only the IP address would
+ * have gotten it to us.
+ * We don't even try to do this for the other side:
+ * %myid makes no sense for the other side (but it is syntactically
+ * legal).
+ */
+ our_id = resolve_myid(&c->spd.this.id);
+ if (our_id->kind == ID_ANY)
+ {
+ iptoid(&c->spd.this.host_addr, &our_id_space);
+ our_id = &our_id_space;
+ }
+
+ switch (next_step)
+ {
+ case vos_our_client:
+ networkof(&b->my.net, &client);
+ iptoid(&client, &id);
+ vc->b.failure_ok = b->failure_ok = FALSE;
+ ugh = start_adns_query(&id
+ , our_id
+ , T_TXT
+ , quick_inI1_outR1_continue
+ , &vc->ac);
+ break;
+
+ case vos_our_txt:
+ vc->b.failure_ok = b->failure_ok = TRUE;
+ ugh = start_adns_query(our_id
+ , our_id /* self as SG */
+ , T_TXT
+ , quick_inI1_outR1_continue
+ , &vc->ac);
+ break;
#ifdef USE_KEYRR
- case vos_our_key:
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(our_id
- , NULL
- , T_KEY
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
+ case vos_our_key:
+ vc->b.failure_ok = b->failure_ok = FALSE;
+ ugh = start_adns_query(our_id
+ , NULL
+ , T_KEY
+ , quick_inI1_outR1_continue
+ , &vc->ac);
+ break;
#endif
- case vos_his_client:
- networkof(&b->his.net, &client);
- iptoid(&client, &id);
- vc->b.failure_ok = b->failure_ok = FALSE;
- ugh = start_adns_query(&id
- , &c->spd.that.id
- , T_TXT
- , quick_inI1_outR1_continue
- , &vc->ac);
- break;
-
- default:
- bad_case(next_step);
- }
-
- if (ugh != NULL)
- {
- /* note: we'd like to use vc->b but vc has been freed
- * so we have to use b. This is why we plunked next_state
- * into b, not just vc->b.
- */
- report_verify_failure(b, ugh);
- p1st->st_suspended_md = NULL;
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
- {
- return STF_SUSPEND;
- }
+ case vos_his_client:
+ networkof(&b->his.net, &client);
+ iptoid(&client, &id);
+ vc->b.failure_ok = b->failure_ok = FALSE;
+ ugh = start_adns_query(&id
+ , &c->spd.that.id
+ , T_TXT
+ , quick_inI1_outR1_continue
+ , &vc->ac);
+ break;
+
+ default:
+ bad_case(next_step);
+ }
+
+ if (ugh != NULL)
+ {
+ /* note: we'd like to use vc->b but vc has been freed
+ * so we have to use b. This is why we plunked next_state
+ * into b, not just vc->b.
+ */
+ report_verify_failure(b, ugh);
+ p1st->st_suspended_md = NULL;
+ return STF_FAIL + INVALID_ID_INFORMATION;
+ }
+ else
+ {
+ return STF_SUSPEND;
+ }
}
-static enum verify_oppo_step
-quick_inI1_outR1_process_answer(struct verify_oppo_bundle *b
-, struct adns_continuation *ac
-, struct state *p1st)
+static enum verify_oppo_step quick_inI1_outR1_process_answer(
+ struct verify_oppo_bundle *b,
+ struct adns_continuation *ac,
+ struct state *p1st)
{
- struct connection *c = p1st->st_connection;
- enum verify_oppo_step next_step = vos_our_client;
- err_t ugh = NULL;
-
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
- DBG_log("responding on demand from %s to %s state: %s"
- , ours, his, verify_step_name[b->step]);
- });
-
- /* process just completed DNS query (if any) */
- switch (b->step)
- {
- case vos_start:
- /* no query to digest */
- next_step = vos_our_client;
- break;
-
- case vos_our_client:
- next_step = vos_his_client;
- {
- const struct RSA_private_key *pri = get_RSA_private_key(c);
- struct gw_info *gwp;
-
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
- break;
- }
- ugh = "our client does not delegate us as its Security Gateway";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- ugh = "our client delegates us as its Security Gateway but with the wrong public key";
- /* If there is no key in the TXT record,
- * we count it as a win, but we will have
- * to separately fetch and check the KEY record.
- * If there is a key from the TXT record,
- * we count it as a win if we match the key.
- */
- if (!gwp->gw_key_present)
- {
- next_step = vos_our_txt;
- ugh = NULL; /* good! */
- break;
- }
- else if (same_RSA_public_key(&pri->pub, &gwp->key->u.rsa))
+ struct connection *c = p1st->st_connection;
+ enum verify_oppo_step next_step = vos_our_client;
+ err_t ugh = NULL;
+
+ DBG(DBG_CONTROL,
{
- ugh = NULL; /* good! */
- break;
- }
- }
- }
- break;
+ char ours[SUBNETTOT_BUF];
+ char his[SUBNETTOT_BUF];
+
+ subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
+ subnettot(&c->spd.that.client, 0, his, sizeof(his));
+ DBG_log("responding on demand from %s to %s state: %s"
+ , ours, his, verify_step_name[b->step]);
+ });
- case vos_our_txt:
- next_step = vos_his_client;
+ /* process just completed DNS query (if any) */
+ switch (b->step)
{
- const struct RSA_private_key *pri = get_RSA_private_key(c);
+ case vos_start:
+ /* no query to digest */
+ next_step = vos_our_client;
+ break;
+
+ case vos_our_client:
+ next_step = vos_his_client;
+ {
+ private_key_t *private = get_private_key(c);
+ struct gw_info *gwp;
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
+ if (private == NULL)
+ {
+ ugh = "we don't know our own key";
+ break;
+ }
+ ugh = "our client does not delegate us as its Security Gateway";
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ ugh = "our client delegates us as its Security Gateway but with the wrong public key";
+ /* If there is no key in the TXT record,
+ * we count it as a win, but we will have
+ * to separately fetch and check the KEY record.
+ * If there is a key from the TXT record,
+ * we count it as a win if we match the key.
+ */
+ if (!gwp->gw_key_present)
+ {
+ next_step = vos_our_txt;
+ ugh = NULL; /* good! */
+ break;
+ }
+ else if (private->belongs_to(private, gwp->key->public_key))
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
break;
- }
- {
- struct gw_info *gwp;
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ case vos_our_txt:
+ next_step = vos_his_client;
{
+ private_key_t *private = get_private_key(c);
+
+ if (private == NULL)
+ {
+ ugh = "we don't know our own key";
+ break;
+ }
+ {
+ struct gw_info *gwp;
+
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
#ifdef USE_KEYRR
- /* not an error yet, because we have to check KEY RR as well */
- ugh = NULL;
+ /* not an error yet, because we have to check KEY RR as well */
+ ugh = NULL;
#else
- ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
+ ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
#endif
- if (gwp->gw_key_present
- && same_RSA_public_key(&pri->pub, &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
+ if (gwp->gw_key_present
+ && private->belongs_to(private, gwp->key->public_key))
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
#ifdef USE_KEYRR
- next_step = vos_our_key;
+ next_step = vos_our_key;
#endif
+ }
+ }
}
- }
- }
- break;
+ break;
#ifdef USE_KEYRR
- case vos_our_key:
- next_step = vos_his_client;
- {
- const struct RSA_private_key *pri = get_RSA_private_key(c);
+ case vos_our_key:
+ next_step = vos_his_client;
+ {
+ private_key_t *private = get_private_key(c);
- if (pri == NULL)
- {
- ugh = "we don't know our own key";
+ if (private == NULL)
+ {
+ ugh = "we don't know our own key";
+ break;
+ }
+ {
+ pubkey_list_t *kp;
+
+ ugh = "our client delegation depends on our missing " RRNAME " record";
+ for (kp = ac->keys_from_dns; kp != NULL; kp = kp->next)
+ {
+ ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
+ if (private->belongs_to(private, kp->key->public_key))
+ {
+ /* do this only once a day */
+ if (!logged_txt_warning)
+ {
+ loglog(RC_LOG_SERIOUS, "found KEY RR but not TXT RR. See http://www.freeswan.org/err/txt-change.html.");
+ logged_txt_warning = TRUE;
+ }
+ ugh = NULL; /* good! */
+ break;
+ }
+ }
+ }
+ }
break;
- }
- {
- pubkey_list_t *kp;
+#endif /* USE_KEYRR */
- ugh = "our client delegation depends on our missing " RRNAME " record";
- for (kp = ac->keys_from_dns; kp != NULL; kp = kp->next)
+ case vos_his_client:
+ next_step = vos_done;
{
- ugh = "our client delegation depends on our " RRNAME " record, but it has the wrong public key";
- if (same_RSA_public_key(&pri->pub, &kp->key->u.rsa))
- {
- /* do this only once a day */
- if (!logged_txt_warning)
+ public_key_t *pub_key;
+ identification_t *p1st_keyid;
+ struct gw_info *gwp;
+
+ /* check that the public key that authenticated
+ * the ISAKMP SA (p1st) will do for this gateway.
+ */
+ pub_key = p1st->st_peer_pubkey->public_key;
+ p1st_keyid = pub_key->get_id(pub_key, ID_PUBKEY_INFO_SHA1);
+
+ ugh = "peer's client does not delegate to peer";
+ for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
{
- loglog(RC_LOG_SERIOUS, "found KEY RR but not TXT RR. See http://www.freeswan.org/err/txt-change.html.");
- logged_txt_warning = TRUE;
+ ugh = "peer and its client disagree about public key";
+ /* If there is a key from the TXT record,
+ * we count it as a win if we match the key.
+ * If there was no key, we claim a match since
+ * it implies fetching a KEY from the same
+ * place we must have gotten it.
+ */
+ if (!gwp->gw_key_present || p1st_keyid->equals(p1st_keyid,
+ gwp->key->public_key->get_id(gwp->key->public_key,
+ ID_PUBKEY_INFO_SHA1))
+ )
+ {
+ ugh = NULL; /* good! */
+ break;
+ }
}
- ugh = NULL; /* good! */
- break;
- }
}
- }
+ break;
+
+ default:
+ bad_case(b->step);
}
- break;
-#endif /* USE_KEYRR */
- case vos_his_client:
- next_step = vos_done;
+ if (ugh != NULL)
{
- struct gw_info *gwp;
-
- /* check that the public key that authenticated
- * the ISAKMP SA (p1st) will do for this gateway.
- */
-
- ugh = "peer's client does not delegate to peer";
- for (gwp = ac->gateways_from_dns; gwp != NULL; gwp = gwp->next)
- {
- ugh = "peer and its client disagree about public key";
- /* If there is a key from the TXT record,
- * we count it as a win if we match the key.
- * If there was no key, we claim a match since
- * it implies fetching a KEY from the same
- * place we must have gotten it.
- */
- if (!gwp->gw_key_present
- || same_RSA_public_key(&p1st->st_peer_pubkey->u.rsa
- , &gwp->key->u.rsa))
- {
- ugh = NULL; /* good! */
- break;
- }
- }
+ report_verify_failure(b, ugh);
+ next_step = vos_fail;
}
- break;
-
- default:
- bad_case(b->step);
- }
-
- if (ugh != NULL)
- {
- report_verify_failure(b, ugh);
- next_step = vos_fail;
- }
- return next_step;
+ return next_step;
}
-static stf_status
-quick_inI1_outR1_tail(struct verify_oppo_bundle *b
-, struct adns_continuation *ac)
+static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
+ struct adns_continuation *ac)
{
- struct msg_digest *md = b->md;
- struct state *const p1st = md->st;
- struct connection *c = p1st->st_connection;
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
- ip_subnet *our_net = &b->my.net
- , *his_net = &b->his.net;
-
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* from where to start hashing */
-
- /* Now that we have identities of client subnets, we must look for
- * a suitable connection (our current one only matches for hosts).
- */
- {
- struct connection *p = find_client_connection(c
- , our_net, his_net, b->my.proto, b->my.port, b->his.proto, b->his.port);
-
- if (p == NULL)
- {
- /* This message occurs in very puzzling circumstances
- * so we must add as much information and beauty as we can.
- */
- struct end
- me = c->spd.this,
- he = c->spd.that;
- char buf[2*SUBNETTOT_BUF + 2*ADDRTOT_BUF + 2*BUF_LEN + 2*ADDRTOT_BUF + 12]; /* + 12 for separating */
- size_t l;
-
- me.client = *our_net;
- me.has_client = !subnetisaddr(our_net, &me.host_addr);
- me.protocol = b->my.proto;
- me.port = b->my.port;
-
- he.client = *his_net;
- he.has_client = !subnetisaddr(his_net, &he.host_addr);
- he.protocol = b->his.proto;
- he.port = b->his.port;
-
- l = format_end(buf, sizeof(buf), &me, NULL, TRUE, LEMPTY);
- l += snprintf(buf + l, sizeof(buf) - l, "...");
- (void)format_end(buf + l, sizeof(buf) - l, &he, NULL, FALSE, LEMPTY);
- plog("cannot respond to IPsec SA request"
- " because no connection is known for %s"
- , buf);
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else if (p != c)
- {
- /* We've got a better connection: it can support the
- * specified clients. But it may need instantiation.
- */
- if (p->kind == CK_TEMPLATE)
- {
- /* Yup, it needs instantiation. How much?
- * Is it a Road Warrior connection (simple)
- * or is it an Opportunistic connection (needing gw validation)?
- */
- if (p->policy & POLICY_OPPO)
- {
- /* Opportunistic case: delegation must be verified.
- * Here be dragons.
- */
- enum verify_oppo_step next_step;
- ip_address our_client, his_client;
-
- passert(subnetishost(our_net) && subnetishost(his_net));
- networkof(our_net, &our_client);
- networkof(his_net, &his_client);
-
- next_step = quick_inI1_outR1_process_answer(b, ac, p1st);
- if (next_step == vos_fail)
- return STF_FAIL + INVALID_ID_INFORMATION;
+ struct msg_digest *md = b->md;
+ struct state *const p1st = md->st;
+ struct connection *c = p1st->st_connection;
+ struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
+ ip_subnet *our_net = &b->my.net
+ , *his_net = &b->his.net;
- /* short circuit: if peer's client is self,
- * accept that we've verified delegation in Phase 1
- */
- if (next_step == vos_his_client
- && sameaddr(&c->spd.that.host_addr, &his_client))
- next_step = vos_done;
+ u_char /* set by START_HASH_PAYLOAD: */
+ *r_hashval, /* where in reply to jam hash value */
+ *r_hash_start; /* from where to start hashing */
- /* the second chunk: initiate the next DNS query (if any) */
- DBG(DBG_CONTROL,
- {
- char ours[SUBNETTOT_BUF];
- char his[SUBNETTOT_BUF];
-
- subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
- subnettot(&c->spd.that.client, 0, his, sizeof(his));
-
- DBG_log("responding on demand from %s to %s new state: %s"
- , ours, his, verify_step_name[next_step]);
- });
-
- /* start next DNS query and suspend (if necessary) */
- if (next_step != vos_done)
- return quick_inI1_outR1_start_query(b, next_step);
-
- /* Instantiate inbound Opportunistic connection,
- * carrying over authenticated peer ID
- * and filling in a few more details.
- * We used to include gateways_from_dns, but that
- * seems pointless at this stage of negotiation.
- * We should record DNS sec use, if any -- belongs in
- * state during perhaps.
- */
- p = oppo_instantiate(p, &c->spd.that.host_addr, &c->spd.that.id
- , NULL, &our_client, &his_client);
- }
- else
+ /* Now that we have identities of client subnets, we must look for
+ * a suitable connection (our current one only matches for hosts).
+ */
+ {
+ struct connection *p = find_client_connection(c
+ , our_net, his_net, b->my.proto, b->my.port, b->his.proto, b->his.port);
+
+ if (p == NULL)
{
- /* Plain Road Warrior:
- * instantiate, carrying over authenticated peer ID
- */
- p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
- , his_net, &c->spd.that.id);
+ /* This message occurs in very puzzling circumstances
+ * so we must add as much information and beauty as we can.
+ */
+ struct end
+ me = c->spd.this,
+ he = c->spd.that;
+ char buf[2*SUBNETTOT_BUF + 2*ADDRTOT_BUF + 2*BUF_LEN + 2*ADDRTOT_BUF + 12]; /* + 12 for separating */
+ size_t l;
+
+ me.client = *our_net;
+ me.has_client = !subnetisaddr(our_net, &me.host_addr);
+ me.protocol = b->my.proto;
+ me.port = b->my.port;
+
+ he.client = *his_net;
+ he.has_client = !subnetisaddr(his_net, &he.host_addr);
+ he.protocol = b->his.proto;
+ he.port = b->his.port;
+
+ l = format_end(buf, sizeof(buf), &me, NULL, TRUE, LEMPTY);
+ l += snprintf(buf + l, sizeof(buf) - l, "...");
+ (void)format_end(buf + l, sizeof(buf) - l, &he, NULL, FALSE, LEMPTY);
+ plog("cannot respond to IPsec SA request"
+ " because no connection is known for %s"
+ , buf);
+ return STF_FAIL + INVALID_ID_INFORMATION;
}
- }
+ else if (p != c)
+ {
+ /* We've got a better connection: it can support the
+ * specified clients. But it may need instantiation.
+ */
+ if (p->kind == CK_TEMPLATE)
+ {
+ /* Yup, it needs instantiation. How much?
+ * Is it a Road Warrior connection (simple)
+ * or is it an Opportunistic connection (needing gw validation)?
+ */
+ if (p->policy & POLICY_OPPO)
+ {
+ /* Opportunistic case: delegation must be verified.
+ * Here be dragons.
+ */
+ enum verify_oppo_step next_step;
+ ip_address our_client, his_client;
+
+ passert(subnetishost(our_net) && subnetishost(his_net));
+ networkof(our_net, &our_client);
+ networkof(his_net, &his_client);
+
+ next_step = quick_inI1_outR1_process_answer(b, ac, p1st);
+ if (next_step == vos_fail)
+ return STF_FAIL + INVALID_ID_INFORMATION;
+
+ /* short circuit: if peer's client is self,
+ * accept that we've verified delegation in Phase 1
+ */
+ if (next_step == vos_his_client
+ && sameaddr(&c->spd.that.host_addr, &his_client))
+ next_step = vos_done;
+
+ /* the second chunk: initiate the next DNS query (if any) */
+ DBG(DBG_CONTROL,
+ {
+ char ours[SUBNETTOT_BUF];
+ char his[SUBNETTOT_BUF];
+
+ subnettot(&c->spd.this.client, 0, ours, sizeof(ours));
+ subnettot(&c->spd.that.client, 0, his, sizeof(his));
+
+ DBG_log("responding on demand from %s to %s new state: %s"
+ , ours, his, verify_step_name[next_step]);
+ });
+
+ /* start next DNS query and suspend (if necessary) */
+ if (next_step != vos_done)
+ return quick_inI1_outR1_start_query(b, next_step);
+
+ /* Instantiate inbound Opportunistic connection,
+ * carrying over authenticated peer ID
+ * and filling in a few more details.
+ * We used to include gateways_from_dns, but that
+ * seems pointless at this stage of negotiation.
+ * We should record DNS sec use, if any -- belongs in
+ * state during perhaps.
+ */
+ p = oppo_instantiate(p, &c->spd.that.host_addr, &c->spd.that.id
+ , NULL, &our_client, &his_client);
+ }
+ else
+ {
+ /* Plain Road Warrior:
+ * instantiate, carrying over authenticated peer ID
+ */
+ p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
+ , his_net, &c->spd.that.id);
+ }
+ }
#ifdef DEBUG
- /* temporarily bump up cur_debugging to get "using..." message
- * printed if we'd want it with new connection.
- */
- {
- lset_t old_cur_debugging = cur_debugging;
-
- cur_debugging |= p->extra_debugging;
- DBG(DBG_CONTROL, DBG_log("using connection \"%s\"", p->name));
- cur_debugging = old_cur_debugging;
- }
+ /* temporarily bump up cur_debugging to get "using..." message
+ * printed if we'd want it with new connection.
+ */
+ {
+ lset_t old_cur_debugging = cur_debugging;
+
+ cur_debugging |= p->extra_debugging;
+ DBG(DBG_CONTROL, DBG_log("using connection \"%s\"", p->name));
+ cur_debugging = old_cur_debugging;
+ }
#endif
- c = p;
- }
- /* fill in the client's true ip address/subnet */
- if (p->spd.that.has_client_wildcard)
- {
- p->spd.that.client = *his_net;
- p->spd.that.has_client_wildcard = FALSE;
- }
- else if (is_virtual_connection(c))
- {
- c->spd.that.client = *his_net;
- c->spd.that.virt = NULL;
- if (subnetishost(his_net) && addrinsubnet(&c->spd.that.host_addr, his_net))
- c->spd.that.has_client = FALSE;
- }
+ c = p;
+ }
+ /* fill in the client's true ip address/subnet */
+ if (p->spd.that.has_client_wildcard)
+ {
+ p->spd.that.client = *his_net;
+ p->spd.that.has_client_wildcard = FALSE;
+ }
+ else if (is_virtual_connection(c))
+ {
+ c->spd.that.client = *his_net;
+ c->spd.that.virt = NULL;
+ if (subnetishost(his_net) && addrinsubnet(&c->spd.that.host_addr, his_net))
+ c->spd.that.has_client = FALSE;
+ }
- /* fill in the client's true port */
- if (p->spd.that.has_port_wildcard)
- {
- int port = htons(b->his.port);
+ /* fill in the client's true port */
+ if (p->spd.that.has_port_wildcard)
+ {
+ int port = htons(b->his.port);
- setportof(port, &p->spd.that.host_addr);
- setportof(port, &p->spd.that.client.addr);
+ setportof(port, &p->spd.that.host_addr);
+ setportof(port, &p->spd.that.client.addr);
- p->spd.that.port = b->his.port;
- p->spd.that.has_port_wildcard = FALSE;
+ p->spd.that.port = b->his.port;
+ p->spd.that.has_port_wildcard = FALSE;
+ }
}
- }
-
- /* now that we are sure of our connection, create our new state */
- {
- struct state *const st = duplicate_state(p1st);
-
- /* first: fill in missing bits of our new state object
- * note: we don't copy over st_peer_pubkey, the public key
- * that authenticated the ISAKMP SA. We only need it in this
- * routine, so we can "reach back" to p1st to get it.
- */
- if (st->st_connection != c)
+ /* now that we are sure of our connection, create our new state */
{
- struct connection *t = st->st_connection;
+ struct state *const st = duplicate_state(p1st);
- st->st_connection = c;
- set_cur_connection(c);
- connection_discard(t);
- }
+ /* first: fill in missing bits of our new state object
+ * note: we don't copy over st_peer_pubkey, the public key
+ * that authenticated the ISAKMP SA. We only need it in this
+ * routine, so we can "reach back" to p1st to get it.
+ */
- st->st_try = 0; /* not our job to try again from start */
+ if (st->st_connection != c)
+ {
+ struct connection *t = st->st_connection;
- st->st_msgid = md->hdr.isa_msgid;
+ st->st_connection = c;
+ set_cur_connection(c);
+ connection_discard(t);
+ }
- st->st_new_iv_len = b->new_iv_len;
- memcpy(st->st_new_iv, b->new_iv, b->new_iv_len);
+ st->st_try = 0; /* not our job to try again from start */
- set_cur_state(st); /* (caller will reset) */
- md->st = st; /* feed back new state */
+ st->st_msgid = md->hdr.isa_msgid;
- st->st_peeruserprotoid = b->his.proto;
- st->st_peeruserport = b->his.port;
- st->st_myuserprotoid = b->my.proto;
- st->st_myuserport = b->my.port;
+ st->st_new_iv_len = b->new_iv_len;
+ memcpy(st->st_new_iv, b->new_iv, b->new_iv_len);
- insert_state(st); /* needs cookies, connection, and msgid */
+ set_cur_state(st); /* (caller will reset) */
+ md->st = st; /* feed back new state */
- /* copy the connection's
- * IPSEC policy into our state. The ISAKMP policy is water under
- * the bridge, I think. It will reflect the ISAKMP SA that we
- * are using.
- */
- st->st_policy = (p1st->st_policy & POLICY_ISAKMP_MASK)
- | (c->policy & ~POLICY_ISAKMP_MASK);
+ st->st_peeruserprotoid = b->his.proto;
+ st->st_peeruserport = b->his.port;
+ st->st_myuserprotoid = b->my.proto;
+ st->st_myuserport = b->my.port;
- if (p1st->nat_traversal & NAT_T_DETECTED)
- {
- st->nat_traversal = p1st->nat_traversal;
- nat_traversal_change_port_lookup(md, md->st);
- }
- else
- {
- st->nat_traversal = 0;
- }
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->nat_traversal & NAT_T_WITH_NATOA))
- {
- nat_traversal_natoa_lookup(md);
- }
+ insert_state(st); /* needs cookies, connection, and msgid */
- /* Start the output packet.
- *
- * proccess_packet() would automatically generate the HDR*
- * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
- * We don't do this because we wish there to be no partially
- * built output packet if we need to suspend for asynch DNS.
- *
- * We build the reply packet as we parse the message since
- * the parse_ipsec_sa_body emits the reply SA
- */
+ /* copy the connection's
+ * IPSEC policy into our state. The ISAKMP policy is water under
+ * the bridge, I think. It will reflect the ISAKMP SA that we
+ * are using.
+ */
+ st->st_policy = (p1st->st_policy & POLICY_ISAKMP_MASK)
+ | (c->policy & ~POLICY_ISAKMP_MASK);
- /* HDR* out */
- echo_hdr(md, TRUE, ISAKMP_NEXT_HASH);
+ if (p1st->nat_traversal & NAT_T_DETECTED)
+ {
+ st->nat_traversal = p1st->nat_traversal;
+ nat_traversal_change_port_lookup(md, md->st);
+ }
+ else
+ {
+ st->nat_traversal = 0;
+ }
+ if ((st->nat_traversal & NAT_T_DETECTED)
+ && (st->nat_traversal & NAT_T_WITH_NATOA))
+ {
+ nat_traversal_natoa_lookup(md);
+ }
- /* HASH(2) out -- first pass */
- START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_SA);
+ /* Start the output packet.
+ *
+ * proccess_packet() would automatically generate the HDR*
+ * payload if smc->first_out_payload is not ISAKMP_NEXT_NONE.
+ * We don't do this because we wish there to be no partially
+ * built output packet if we need to suspend for asynch DNS.
+ *
+ * We build the reply packet as we parse the message since
+ * the parse_ipsec_sa_body emits the reply SA
+ */
- /* process SA (in and out) */
- {
- struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
- pb_stream r_sa_pbs;
- struct isakmp_sa sa = sapd->payload.sa;
+ /* HDR* out */
+ echo_hdr(md, TRUE, ISAKMP_NEXT_HASH);
- /* sa header is unchanged -- except for np */
- sa.isasa_np = ISAKMP_NEXT_NONCE;
- if (!out_struct(&sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
- return STF_INTERNAL_ERROR;
+ /* HASH(2) out -- first pass */
+ START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_SA);
- /* parse and accept body */
- st->st_pfs_group = &unset_group;
- RETURN_STF_FAILURE(parse_ipsec_sa_body(&sapd->pbs
- , &sapd->payload.sa, &r_sa_pbs, FALSE, st));
- }
+ /* process SA (in and out) */
+ {
+ struct payload_digest *const sapd = md->chain[ISAKMP_NEXT_SA];
+ pb_stream r_sa_pbs;
+ struct isakmp_sa sa = sapd->payload.sa;
+
+ /* sa header is unchanged -- except for np */
+ sa.isasa_np = ISAKMP_NEXT_NONCE;
+ if (!out_struct(&sa, &isakmp_sa_desc, &md->rbody, &r_sa_pbs))
+ return STF_INTERNAL_ERROR;
+
+ /* parse and accept body */
+ st->st_pfs_group = &unset_group;
+ RETURN_STF_FAILURE(parse_ipsec_sa_body(&sapd->pbs
+ , &sapd->payload.sa, &r_sa_pbs, FALSE, st));
+ }
- passert(st->st_pfs_group != &unset_group);
+ passert(st->st_pfs_group != &unset_group);
- if ((st->st_policy & POLICY_PFS) && st->st_pfs_group == NULL)
- {
- loglog(RC_LOG_SERIOUS, "we require PFS but Quick I1 SA specifies no GROUP_DESCRIPTION");
- return STF_FAIL + NO_PROPOSAL_CHOSEN; /* ??? */
- }
+ if ((st->st_policy & POLICY_PFS) && st->st_pfs_group == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "we require PFS but Quick I1 SA specifies no GROUP_DESCRIPTION");
+ return STF_FAIL + NO_PROPOSAL_CHOSEN; /* ??? */
+ }
- /* Ni in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
+ /* Ni in */
+ RETURN_STF_FAILURE(accept_nonce(md, &st->st_ni, "Ni"));
- /* [ KE ] in (for PFS) */
- RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gi, "Gi", "Quick Mode I1"));
+ /* [ KE ] in (for PFS) */
+ RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gi, "Gi", "Quick Mode I1"));
- plog("responding to Quick Mode");
+ plog("responding to Quick Mode");
- /**** finish reply packet: Nr [, KE ] [, IDci, IDcr ] ****/
+ /**** finish reply packet: Nr [, KE ] [, IDci, IDcr ] ****/
- /* Nr out */
- if (!build_and_ship_nonce(&st->st_nr, &md->rbody
- , st->st_pfs_group != NULL? ISAKMP_NEXT_KE : id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE
- , "Nr"))
- return STF_INTERNAL_ERROR;
+ /* Nr out */
+ if (!build_and_ship_nonce(&st->st_nr, &md->rbody
+ , st->st_pfs_group != NULL? ISAKMP_NEXT_KE : id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE
+ , "Nr"))
+ return STF_INTERNAL_ERROR;
- /* [ KE ] out (for PFS) */
+ /* [ KE ] out (for PFS) */
- if (st->st_pfs_group != NULL)
- {
- if (!build_and_ship_KE(st, &st->st_gr, st->st_pfs_group
- , &md->rbody, id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE))
- return STF_INTERNAL_ERROR;
+ if (st->st_pfs_group != NULL)
+ {
+ if (!build_and_ship_KE(st, &st->st_gr, st->st_pfs_group
+ , &md->rbody, id_pd != NULL? ISAKMP_NEXT_ID : ISAKMP_NEXT_NONE))
+ return STF_INTERNAL_ERROR;
- /* MPZ-Operations might be done after sending the packet... */
- compute_dh_shared(st, st->st_gi, st->st_pfs_group);
- }
+ /* MPZ-Operations might be done after sending the packet... */
+ compute_dh_shared(st, st->st_gi);
+ }
- /* [ IDci, IDcr ] out */
- if (id_pd != NULL)
- {
- struct isakmp_ipsec_id *p = (void *)md->rbody.cur; /* UGH! */
+ /* [ IDci, IDcr ] out */
+ if (id_pd != NULL)
+ {
+ struct isakmp_ipsec_id *p = (void *)md->rbody.cur; /* UGH! */
- if (!out_raw(id_pd->pbs.start, pbs_room(&id_pd->pbs), &md->rbody, "IDci"))
- return STF_INTERNAL_ERROR;
- p->isaiid_np = ISAKMP_NEXT_ID;
+ if (!out_raw(id_pd->pbs.start, pbs_room(&id_pd->pbs), &md->rbody, "IDci"))
+ return STF_INTERNAL_ERROR;
+ p->isaiid_np = ISAKMP_NEXT_ID;
- p = (void *)md->rbody.cur; /* UGH! */
+ p = (void *)md->rbody.cur; /* UGH! */
- if (!out_raw(id_pd->next->pbs.start, pbs_room(&id_pd->next->pbs), &md->rbody, "IDcr"))
- return STF_INTERNAL_ERROR;
- p->isaiid_np = ISAKMP_NEXT_NONE;
- }
+ if (!out_raw(id_pd->next->pbs.start, pbs_room(&id_pd->next->pbs), &md->rbody, "IDcr"))
+ return STF_INTERNAL_ERROR;
+ p->isaiid_np = ISAKMP_NEXT_NONE;
+ }
- if ((st->nat_traversal & NAT_T_WITH_NATOA)
- && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
- && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT))
- {
- /** Send NAT-OA if our address is NATed and if we use Transport Mode */
- if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &md->rbody, md->st))
- {
- return STF_INTERNAL_ERROR;
- }
- }
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT)
- && (c->spd.that.has_client))
- {
- /** Remove client **/
- addrtosubnet(&c->spd.that.host_addr, &c->spd.that.client);
- c->spd.that.has_client = FALSE;
- }
+ if ((st->nat_traversal & NAT_T_WITH_NATOA)
+ && (st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME))
+ && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT))
+ {
+ /** Send NAT-OA if our address is NATed and if we use Transport Mode */
+ if (!nat_traversal_add_natoa(ISAKMP_NEXT_NONE, &md->rbody, md->st))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+ }
+ if ((st->nat_traversal & NAT_T_DETECTED)
+ && (st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TRANSPORT)
+ && (c->spd.that.has_client))
+ {
+ /** Remove client **/
+ addrtosubnet(&c->spd.that.host_addr, &c->spd.that.client);
+ c->spd.that.has_client = FALSE;
+ }
- /* Compute reply HASH(2) and insert in output */
- (void)quick_mode_hash12(r_hashval, r_hash_start, md->rbody.cur
- , st, &st->st_msgid, TRUE);
+ /* Compute reply HASH(2) and insert in output */
+ (void)quick_mode_hash12(r_hashval, r_hash_start, md->rbody.cur
+ , st, &st->st_msgid, TRUE);
- /* Derive new keying material */
- compute_keymats(st);
+ /* Derive new keying material */
+ compute_keymats(st);
- /* Tell the kernel to establish the new inbound SA
- * (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_inbound_ipsec_sa(st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
+ /* Tell the kernel to establish the new inbound SA
+ * (unless the commit bit is set -- which we don't support).
+ * We do this before any state updating so that
+ * failure won't look like success.
+ */
+ if (!install_inbound_ipsec_sa(st))
+ return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
- /* encrypt message, except for fixed part of header */
+ /* encrypt message, except for fixed part of header */
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
+ if (!encrypt_message(&md->rbody, st))
+ return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
- return STF_OK;
- }
+ return STF_OK;
+ }
}
/*
* Initialize RFC 3706 Dead Peer Detection
*/
-static void
-dpd_init(struct state *st)
+static void dpd_init(struct state *st)
{
- struct state *p1st = find_state(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr, 0);
-
- if (p1st == NULL)
- loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");
- else if (p1st->st_dpd)
- {
- plog("Dead Peer Detection (RFC 3706) enabled");
- /* randomize the first DPD event */
-
- event_schedule(EVENT_DPD
- , (0.5 + rand()/(RAND_MAX + 1.E0)) * st->st_connection->dpd_delay
- , st);
- }
+ struct state *p1st = find_state(st->st_icookie, st->st_rcookie
+ , &st->st_connection->spd.that.host_addr, 0);
+
+ if (p1st == NULL)
+ loglog(RC_LOG_SERIOUS, "could not find phase 1 state for DPD");
+ else if (p1st->st_dpd)
+ {
+ plog("Dead Peer Detection (RFC 3706) enabled");
+ /* randomize the first DPD event */
+
+ event_schedule(EVENT_DPD
+ , (0.5 + rand()/(RAND_MAX + 1.E0)) * st->st_connection->dpd_delay
+ , st);
+ }
}
/* Handle (the single) message from Responder in Quick Mode.
@@ -5043,152 +4910,151 @@ dpd_init(struct state *st)
* (see RFC 2409 "IKE" 5.5)
* Installs inbound and outbound IPsec SAs, routing, etc.
*/
-stf_status
-quick_inR1_outI2(struct msg_digest *md)
+stf_status quick_inR1_outI2(struct msg_digest *md)
{
- struct state *const st = md->st;
- const struct connection *c = st->st_connection;
+ struct state *const st = md->st;
+ const struct connection *c = st->st_connection;
- /* HASH(2) in */
- CHECK_QUICK_HASH(md
- , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
- , st, &st->st_msgid, TRUE)
- , "HASH(2)", "Quick R1");
-
- /* SA in */
- {
- struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
+ /* HASH(2) in */
+ CHECK_QUICK_HASH(md
+ , quick_mode_hash12(hash_val, hash_pbs->roof, md->message_pbs.roof
+ , st, &st->st_msgid, TRUE)
+ , "HASH(2)", "Quick R1");
- RETURN_STF_FAILURE(parse_ipsec_sa_body(&sa_pd->pbs
- , &sa_pd->payload.sa, NULL, TRUE, st));
- }
+ /* SA in */
+ {
+ struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
- /* Nr in */
- RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
+ RETURN_STF_FAILURE(parse_ipsec_sa_body(&sa_pd->pbs
+ , &sa_pd->payload.sa, NULL, TRUE, st));
+ }
- /* [ KE ] in (for PFS) */
- RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1"));
+ /* Nr in */
+ RETURN_STF_FAILURE(accept_nonce(md, &st->st_nr, "Nr"));
- if (st->st_pfs_group != NULL)
- compute_dh_shared(st, st->st_gr, st->st_pfs_group);
+ /* [ KE ] in (for PFS) */
+ RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1"));
- /* [ IDci, IDcr ] in; these must match what we sent */
+ if (st->st_pfs_group != NULL)
+ compute_dh_shared(st, st->st_gr);
- {
- struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
+ /* [ IDci, IDcr ] in; these must match what we sent */
- if (id_pd != NULL)
{
- /* ??? we are assuming IPSEC_DOI */
+ struct payload_digest *const id_pd = md->chain[ISAKMP_NEXT_ID];
- /* IDci (we are initiator) */
+ if (id_pd != NULL)
+ {
+ /* ??? we are assuming IPSEC_DOI */
- if (!check_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
- , &st->st_myuserprotoid, &st->st_myuserport
- , &st->st_connection->spd.this.client
- , "our client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
+ /* IDci (we are initiator) */
- /* IDcr (responder is peer) */
+ if (!check_net_id(&id_pd->payload.ipsec_id, &id_pd->pbs
+ , &st->st_myuserprotoid, &st->st_myuserport
+ , &st->st_connection->spd.this.client
+ , "our client"))
+ return STF_FAIL + INVALID_ID_INFORMATION;
- if (!check_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
- , &st->st_peeruserprotoid, &st->st_peeruserport
- , &st->st_connection->spd.that.client
- , "peer client"))
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- else
- {
- /* no IDci, IDcr: we must check that the defaults match our proposal */
- if (!subnetisaddr(&c->spd.this.client, &c->spd.this.host_addr)
- || !subnetisaddr(&c->spd.that.client, &c->spd.that.host_addr))
- {
- loglog(RC_LOG_SERIOUS, "IDci, IDcr payloads missing in message"
- " but default does not match proposal");
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
+ /* IDcr (responder is peer) */
+
+ if (!check_net_id(&id_pd->next->payload.ipsec_id, &id_pd->next->pbs
+ , &st->st_peeruserprotoid, &st->st_peeruserport
+ , &st->st_connection->spd.that.client
+ , "peer client"))
+ return STF_FAIL + INVALID_ID_INFORMATION;
+ }
+ else
+ {
+ /* no IDci, IDcr: we must check that the defaults match our proposal */
+ if (!subnetisaddr(&c->spd.this.client, &c->spd.this.host_addr)
+ || !subnetisaddr(&c->spd.that.client, &c->spd.that.host_addr))
+ {
+ loglog(RC_LOG_SERIOUS, "IDci, IDcr payloads missing in message"
+ " but default does not match proposal");
+ return STF_FAIL + INVALID_ID_INFORMATION;
+ }
+ }
}
- }
- /* check the peer's group attributes */
-
- {
- const ietfAttrList_t *peer_list = NULL;
+ /* check the peer's group attributes */
- get_peer_ca_and_groups(st->st_connection, &peer_list);
-
- if (!group_membership(peer_list, st->st_connection->name
- , st->st_connection->spd.that.groups))
{
- char buf[BUF_LEN];
+ const ietfAttrList_t *peer_list = NULL;
+
+ get_peer_ca_and_groups(st->st_connection, &peer_list);
- format_groups(st->st_connection->spd.that.groups, buf, BUF_LEN);
- loglog(RC_LOG_SERIOUS, "peer is not member of one of the groups: %s"
- , buf);
- return STF_FAIL + INVALID_ID_INFORMATION;
- }
- }
+ if (!group_membership(peer_list, st->st_connection->name
+ , st->st_connection->spd.that.groups))
+ {
+ char buf[BUF_LEN];
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->nat_traversal & NAT_T_WITH_NATOA))
- {
- nat_traversal_natoa_lookup(md);
+ format_groups(st->st_connection->spd.that.groups, buf, BUF_LEN);
+ loglog(RC_LOG_SERIOUS, "peer is not member of one of the groups: %s"
+ , buf);
+ return STF_FAIL + INVALID_ID_INFORMATION;
+ }
}
- /* ??? We used to copy the accepted proposal into the state, but it was
- * never used. From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).
- */
+ if ((st->nat_traversal & NAT_T_DETECTED)
+ && (st->nat_traversal & NAT_T_WITH_NATOA))
+ {
+ nat_traversal_natoa_lookup(md);
+ }
+
+ /* ??? We used to copy the accepted proposal into the state, but it was
+ * never used. From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).
+ */
- /**************** build reply packet HDR*, HASH(3) ****************/
+ /**************** build reply packet HDR*, HASH(3) ****************/
- /* HDR* out done */
+ /* HDR* out done */
- /* HASH(3) out -- since this is the only content, no passes needed */
- {
- u_char /* set by START_HASH_PAYLOAD: */
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
+ /* HASH(3) out -- since this is the only content, no passes needed */
+ {
+ u_char /* set by START_HASH_PAYLOAD: */
+ *r_hashval, /* where in reply to jam hash value */
+ *r_hash_start; /* start of what is to be hashed */
- START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_NONE);
- (void)quick_mode_hash3(r_hashval, st);
- }
+ START_HASH_PAYLOAD(md->rbody, ISAKMP_NEXT_NONE);
+ (void)quick_mode_hash3(r_hashval, st);
+ }
- /* Derive new keying material */
- compute_keymats(st);
+ /* Derive new keying material */
+ compute_keymats(st);
- /* Tell the kernel to establish the inbound, outbound, and routing part
- * of the new SA (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_ipsec_sa(st, TRUE))
- return STF_INTERNAL_ERROR;
+ /* Tell the kernel to establish the inbound, outbound, and routing part
+ * of the new SA (unless the commit bit is set -- which we don't support).
+ * We do this before any state updating so that
+ * failure won't look like success.
+ */
+ if (!install_ipsec_sa(st, TRUE))
+ return STF_INTERNAL_ERROR;
- /* encrypt message, except for fixed part of header */
+ /* encrypt message, except for fixed part of header */
- if (!encrypt_message(&md->rbody, st))
- return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
+ if (!encrypt_message(&md->rbody, st))
+ return STF_INTERNAL_ERROR; /* ??? we may be partly committed */
- {
- DBG(DBG_CONTROLMORE, DBG_log("inR1_outI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
- , st->st_connection->name
- , st->st_connection->instance_serial
- , st->st_serialno
- , st->st_connection->newest_ipsec_sa
- , st->st_connection->spd.eroute_owner));
- }
-
- st->st_connection->newest_ipsec_sa = st->st_serialno;
+ {
+ DBG(DBG_CONTROLMORE, DBG_log("inR1_outI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
+ , st->st_connection->name
+ , st->st_connection->instance_serial
+ , st->st_serialno
+ , st->st_connection->newest_ipsec_sa
+ , st->st_connection->spd.eroute_owner));
+ }
+
+ st->st_connection->newest_ipsec_sa = st->st_serialno;
- /* note (presumed) success */
- if (c->gw_info != NULL)
- c->gw_info->key->last_worked_time = now();
+ /* note (presumed) success */
+ if (c->gw_info != NULL)
+ c->gw_info->key->last_worked_time = now();
- /* If we want DPD on this connection then initialize it */
- if (st->st_connection->dpd_action != DPD_ACTION_NONE)
- dpd_init(st);
+ /* If we want DPD on this connection then initialize it */
+ if (st->st_connection->dpd_action != DPD_ACTION_NONE)
+ dpd_init(st);
- return STF_OK;
+ return STF_OK;
}
/* Handle last message of Quick Mode.
@@ -5196,245 +5062,253 @@ quick_inR1_outI2(struct msg_digest *md)
* (see RFC 2409 "IKE" 5.5)
* Installs outbound IPsec SAs, routing, etc.
*/
-stf_status
-quick_inI2(struct msg_digest *md)
+stf_status quick_inI2(struct msg_digest *md)
{
- struct state *const st = md->st;
-
- /* HASH(3) in */
- CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st)
- , "HASH(3)", "Quick I2");
-
- /* Tell the kernel to establish the outbound and routing part of the new SA
- * (the previous state established inbound)
- * (unless the commit bit is set -- which we don't support).
- * We do this before any state updating so that
- * failure won't look like success.
- */
- if (!install_ipsec_sa(st, FALSE))
- return STF_INTERNAL_ERROR;
-
- {
- DBG(DBG_CONTROLMORE, DBG_log("inI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
- , st->st_connection->name
- , st->st_connection->instance_serial
- , st->st_serialno
- , st->st_connection->newest_ipsec_sa
- , st->st_connection->spd.eroute_owner));
- }
-
- st->st_connection->newest_ipsec_sa = st->st_serialno;
-
- update_iv(st); /* not actually used, but tidy */
-
- /* note (presumed) success */
- {
- struct gw_info *gw = st->st_connection->gw_info;
-
- if (gw != NULL)
- gw->key->last_worked_time = now();
- }
-
- /* If we want DPD on this connection then initialize it */
- if (st->st_connection->dpd_action != DPD_ACTION_NONE)
- dpd_init(st);
-
- return STF_OK;
+ struct state *const st = md->st;
+
+ /* HASH(3) in */
+ CHECK_QUICK_HASH(md, quick_mode_hash3(hash_val, st)
+ , "HASH(3)", "Quick I2");
+
+ /* Tell the kernel to establish the outbound and routing part of the new SA
+ * (the previous state established inbound)
+ * (unless the commit bit is set -- which we don't support).
+ * We do this before any state updating so that
+ * failure won't look like success.
+ */
+ if (!install_ipsec_sa(st, FALSE))
+ return STF_INTERNAL_ERROR;
+
+ {
+ DBG(DBG_CONTROLMORE, DBG_log("inI2: instance %s[%ld], setting newest_ipsec_sa to #%ld (was #%ld) (spd.eroute=#%ld)"
+ , st->st_connection->name
+ , st->st_connection->instance_serial
+ , st->st_serialno
+ , st->st_connection->newest_ipsec_sa
+ , st->st_connection->spd.eroute_owner));
+ }
+
+ st->st_connection->newest_ipsec_sa = st->st_serialno;
+
+ update_iv(st); /* not actually used, but tidy */
+
+ /* note (presumed) success */
+ {
+ struct gw_info *gw = st->st_connection->gw_info;
+
+ if (gw != NULL)
+ gw->key->last_worked_time = now();
+ }
+
+ /* If we want DPD on this connection then initialize it */
+ if (st->st_connection->dpd_action != DPD_ACTION_NONE)
+ dpd_init(st);
+
+ return STF_OK;
}
-static stf_status
-send_isakmp_notification(struct state *st, u_int16_t type
- , const void *data, size_t len)
+static stf_status send_isakmp_notification(struct state *st, u_int16_t type,
+ const void *data, size_t len)
{
- msgid_t msgid;
- pb_stream reply;
- pb_stream rbody;
- u_char
- *r_hashval, /* where in reply to jam hash value */
- *r_hash_start; /* start of what is to be hashed */
-
- msgid = generate_msgid(st);
-
- init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "ISAKMP notify");
-
- /* HDR* */
- {
- struct isakmp_hdr hdr;
-
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_INFO;
- hdr.isa_msgid = msgid;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
- impossible();
- }
- /* HASH -- create and note space to be filled later */
- START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_N);
-
- /* NOTIFY */
- {
- pb_stream notify_pbs;
- struct isakmp_notification isan;
-
- isan.isan_np = ISAKMP_NEXT_NONE;
- isan.isan_doi = ISAKMP_DOI_IPSEC;
- isan.isan_protoid = PROTO_ISAKMP;
- isan.isan_spisize = COOKIE_SIZE * 2;
- isan.isan_type = type;
- if (!out_struct(&isan, &isakmp_notification_desc, &rbody, &notify_pbs))
- return STF_INTERNAL_ERROR;
- if (!out_raw(st->st_icookie, COOKIE_SIZE, &notify_pbs, "notify icookie"))
- return STF_INTERNAL_ERROR;
- if (!out_raw(st->st_rcookie, COOKIE_SIZE, &notify_pbs, "notify rcookie"))
- return STF_INTERNAL_ERROR;
- if (data != NULL && len > 0)
- if (!out_raw(data, len, &notify_pbs, "notify data"))
- return STF_INTERNAL_ERROR;
- close_output_pbs(&notify_pbs);
- }
-
- {
- /* finish computing HASH */
- struct hmac_ctx ctx;
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &msgid, sizeof(msgid_t));
- hmac_update(&ctx, r_hash_start, rbody.cur-r_hash_start);
- hmac_final(r_hashval, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("HASH computed:");
- DBG_dump("", r_hashval, ctx.hmac_digest_size));
- }
-
- /* Encrypt message (preserve st_iv and st_new_iv) */
- {
- u_char old_iv[MAX_DIGEST_LEN];
- u_char new_iv[MAX_DIGEST_LEN];
+ msgid_t msgid;
+ pb_stream reply;
+ pb_stream rbody;
+ u_char
+ *r_hashval, /* where in reply to jam hash value */
+ *r_hash_start; /* start of what is to be hashed */
+
+ msgid = generate_msgid(st);
+
+ init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "ISAKMP notify");
+
+ /* HDR* */
+ {
+ struct isakmp_hdr hdr;
+
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_HASH;
+ hdr.isa_xchg = ISAKMP_XCHG_INFO;
+ hdr.isa_msgid = msgid;
+ hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
+ memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))
+ impossible();
+ }
+ /* HASH -- create and note space to be filled later */
+ START_HASH_PAYLOAD(rbody, ISAKMP_NEXT_N);
- u_int old_iv_len = st->st_iv_len;
- u_int new_iv_len = st->st_new_iv_len;
+ /* NOTIFY */
+ {
+ pb_stream notify_pbs;
+ struct isakmp_notification isan;
+
+ isan.isan_np = ISAKMP_NEXT_NONE;
+ isan.isan_doi = ISAKMP_DOI_IPSEC;
+ isan.isan_protoid = PROTO_ISAKMP;
+ isan.isan_spisize = COOKIE_SIZE * 2;
+ isan.isan_type = type;
+ if (!out_struct(&isan, &isakmp_notification_desc, &rbody, &notify_pbs))
+ return STF_INTERNAL_ERROR;
+ if (!out_raw(st->st_icookie, COOKIE_SIZE, &notify_pbs, "notify icookie"))
+ return STF_INTERNAL_ERROR;
+ if (!out_raw(st->st_rcookie, COOKIE_SIZE, &notify_pbs, "notify rcookie"))
+ return STF_INTERNAL_ERROR;
+ if (data != NULL && len > 0)
+ if (!out_raw(data, len, &notify_pbs, "notify data"))
+ return STF_INTERNAL_ERROR;
+ close_output_pbs(&notify_pbs);
+ }
+
+ {
+ /* finish computing HASH */
+ chunk_t msgid_chunk = chunk_from_thing(msgid);
+ chunk_t msg_chunk = { r_hash_start, rbody.cur-r_hash_start };
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, msg_chunk, r_hashval);
+
+ DBG(DBG_CRYPT,
+ DBG_log("HASH computed:");
+ DBG_dump("", r_hashval, prf->get_block_size(prf));
+ )
+ prf->destroy(prf);
+ }
+
+ /* Encrypt message (preserve st_iv and st_new_iv) */
+ {
+ u_char old_iv[MAX_DIGEST_LEN];
+ u_char new_iv[MAX_DIGEST_LEN];
- if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
- return STF_INTERNAL_ERROR;
+ u_int old_iv_len = st->st_iv_len;
+ u_int new_iv_len = st->st_new_iv_len;
- memcpy(old_iv, st->st_iv, old_iv_len);
- memcpy(new_iv, st->st_new_iv, new_iv_len);
+ if (old_iv_len > MAX_DIGEST_LEN || new_iv_len > MAX_DIGEST_LEN)
+ return STF_INTERNAL_ERROR;
- init_phase2_iv(st, &msgid);
- if (!encrypt_message(&rbody, st))
- return STF_INTERNAL_ERROR;
-
- /* restore preserved st_iv and st_new_iv */
- memcpy(st->st_iv, old_iv, old_iv_len);
- memcpy(st->st_new_iv, new_iv, new_iv_len);
- st->st_iv_len = old_iv_len;
- st->st_new_iv_len = new_iv_len;
- }
-
- /* Send packet (preserve st_tpacket) */
- {
- chunk_t saved_tpacket = st->st_tpacket;
-
- setchunk(st->st_tpacket, reply.start, pbs_offset(&reply));
- send_packet(st, "ISAKMP notify");
- st->st_tpacket = saved_tpacket;
- }
-
- return STF_IGNORE;
+ memcpy(old_iv, st->st_iv, old_iv_len);
+ memcpy(new_iv, st->st_new_iv, new_iv_len);
+
+ init_phase2_iv(st, &msgid);
+ if (!encrypt_message(&rbody, st))
+ return STF_INTERNAL_ERROR;
+
+ /* restore preserved st_iv and st_new_iv */
+ memcpy(st->st_iv, old_iv, old_iv_len);
+ memcpy(st->st_new_iv, new_iv, new_iv_len);
+ st->st_iv_len = old_iv_len;
+ st->st_new_iv_len = new_iv_len;
+ }
+
+ /* Send packet (preserve st_tpacket) */
+ {
+ chunk_t saved_tpacket = st->st_tpacket;
+
+ st->st_tpacket = chunk_create(reply.start, pbs_offset(&reply));
+ send_packet(st, "ISAKMP notify");
+ st->st_tpacket = saved_tpacket;
+ }
+
+ return STF_IGNORE;
}
/*
* DPD Out Initiator
*/
-void
-dpd_outI(struct state *p2st)
+void dpd_outI(struct state *p2st)
{
- struct state *st;
- u_int32_t seqno;
- time_t tm;
- time_t idle_time;
- time_t delay = p2st->st_connection->dpd_delay;
- time_t timeout = p2st->st_connection->dpd_timeout;
-
- /* find the newest related Phase 1 state */
- st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
-
- if (st == NULL)
- {
- loglog(RC_LOG_SERIOUS, "DPD: Could not find newest phase 1 state");
- return;
- }
-
- /* If no DPD, then get out of here */
- if (!st->st_dpd)
- return;
-
- /* schedule the next periodic DPD event */
- event_schedule(EVENT_DPD, delay, p2st);
-
- /* Current time */
- tm = now();
-
- /* Make sure we really need to invoke DPD */
- if (!was_eroute_idle(p2st, delay, &idle_time))
- {
+ struct state *st;
+ u_int32_t seqno;
+ time_t tm;
+ time_t idle_time;
+ time_t delay = p2st->st_connection->dpd_delay;
+ time_t timeout = p2st->st_connection->dpd_timeout;
+
+ /* find the newest related Phase 1 state */
+ st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);
+
+ if (st == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: Could not find newest phase 1 state");
+ return;
+ }
+
+ /* If no DPD, then get out of here */
+ if (!st->st_dpd)
+ return;
+
+ /* schedule the next periodic DPD event */
+ event_schedule(EVENT_DPD, delay, p2st);
+
+ /* Current time */
+ tm = now();
+
+ /* Make sure we really need to invoke DPD */
+ if (!was_eroute_idle(p2st, delay, &idle_time))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("recent eroute activity %u seconds ago, "
+ "no need to send DPD notification"
+ , (int)idle_time)
+ )
+ st->st_last_dpd = tm;
+ delete_dpd_event(st);
+ return;
+ }
+
+ /* If an R_U_THERE has been sent or received recently, or if a
+ * companion Phase 2 SA has shown eroute activity,
+ * then we don't need to invoke DPD.
+ */
+ if (tm < st->st_last_dpd + delay)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("recent DPD activity %u seconds ago, "
+ "no need to send DPD notification"
+ , (int)(tm - st->st_last_dpd))
+ )
+ return;
+ }
+
+ if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ return;
+
+ if (!st->st_dpd_seqno)
+ {
+ rng_t *rng;
+
+ /* Get a non-zero random value that has room to grow */
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ rng->get_bytes(rng, sizeof(st->st_dpd_seqno), (u_char *)&st->st_dpd_seqno);
+ rng->destroy(rng);
+ st->st_dpd_seqno &= 0x7fff;
+ st->st_dpd_seqno++;
+ }
+ seqno = htonl(st->st_dpd_seqno);
+
+ if (send_isakmp_notification(st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: Could not send R_U_THERE");
+ return;
+ }
DBG(DBG_CONTROL,
- DBG_log("recent eroute activity %u seconds ago, "
- "no need to send DPD notification"
- , (int)idle_time)
+ DBG_log("sent DPD notification R_U_THERE with seqno = %u", st->st_dpd_seqno)
)
+ st->st_dpd_expectseqno = st->st_dpd_seqno++;
st->st_last_dpd = tm;
- delete_dpd_event(st);
- return;
- }
-
- /* If an R_U_THERE has been sent or received recently, or if a
- * companion Phase 2 SA has shown eroute activity,
- * then we don't need to invoke DPD.
- */
- if (tm < st->st_last_dpd + delay)
- {
- DBG(DBG_CONTROL,
- DBG_log("recent DPD activity %u seconds ago, "
- "no need to send DPD notification"
- , (int)(tm - st->st_last_dpd))
- )
- return;
- }
-
- if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- return;
-
- if (!st->st_dpd_seqno)
- {
- /* Get a non-zero random value that has room to grow */
- get_rnd_bytes((u_char *)&st->st_dpd_seqno, sizeof(st->st_dpd_seqno));
- st->st_dpd_seqno &= 0x7fff;
- st->st_dpd_seqno++;
- }
- seqno = htonl(st->st_dpd_seqno);
-
- if (send_isakmp_notification(st, R_U_THERE, &seqno, sizeof(seqno)) != STF_IGNORE)
- {
- loglog(RC_LOG_SERIOUS, "DPD: Could not send R_U_THERE");
- return;
- }
- DBG(DBG_CONTROL,
- DBG_log("sent DPD notification R_U_THERE with seqno = %u", st->st_dpd_seqno)
- )
- st->st_dpd_expectseqno = st->st_dpd_seqno++;
- st->st_last_dpd = tm;
- /* Only schedule a new timeout if there isn't one currently,
- * or if it would be sooner than the current timeout. */
- if (st->st_dpd_event == NULL
- || st->st_dpd_event->ev_time > tm + timeout)
- {
- delete_dpd_event(st);
- event_schedule(EVENT_DPD_TIMEOUT, timeout, st);
- }
+ /* Only schedule a new timeout if there isn't one currently,
+ * or if it would be sooner than the current timeout. */
+ if (st->st_dpd_event == NULL
+ || st->st_dpd_event->ev_time > tm + timeout)
+ {
+ delete_dpd_event(st);
+ event_schedule(EVENT_DPD_TIMEOUT, timeout, st);
+ }
}
/*
@@ -5444,139 +5318,139 @@ stf_status
dpd_inI_outR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
{
time_t tm = now();
- u_int32_t seqno;
-
- if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS, "DPD: Received R_U_THERE for unestablished ISAKMP SA");
- return STF_IGNORE;
- }
- if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid SPI length (%d)", n->isan_spisize);
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
- {
+ u_int32_t seqno;
+
+ if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: Received R_U_THERE for unestablished ISAKMP SA");
+ return STF_IGNORE;
+ }
+ if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid SPI length (%d)", n->isan_spisize);
+ return STF_FAIL + PAYLOAD_MALFORMED;
+ }
+
+ if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
+ {
#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
+ /* Ignore it, cisco sends odd icookies */
#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid icookie (broken Cisco?)");
- return STF_FAIL + INVALID_COOKIE;
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid icookie (broken Cisco?)");
+ return STF_FAIL + INVALID_COOKIE;
#endif
- }
- pbs->cur += COOKIE_SIZE;
-
- if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid rcookie (broken Cisco?)");
- return STF_FAIL + INVALID_COOKIE;
- }
- pbs->cur += COOKIE_SIZE;
-
- if (pbs_left(pbs) != sizeof(seqno))
- {
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid data length (%d)"
- , (int) pbs_left(pbs));
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- seqno = ntohl(*(u_int32_t *)pbs->cur);
- DBG(DBG_CONTROL,
- DBG_log("received DPD notification R_U_THERE with seqno = %u", seqno)
- )
-
- if (st->st_dpd_peerseqno && seqno <= st->st_dpd_peerseqno) {
- loglog(RC_LOG_SERIOUS, "DPD: Received old or duplicate R_U_THERE");
- return STF_IGNORE;
- }
-
- st->st_dpd_peerseqno = seqno;
- delete_dpd_event(st);
-
- if (send_isakmp_notification(st, R_U_THERE_ACK, pbs->cur, pbs_left(pbs)) != STF_IGNORE)
- {
- loglog(RC_LOG_SERIOUS, "DPD Info: could not send R_U_THERE_ACK");
- return STF_IGNORE;
- }
- DBG(DBG_CONTROL,
- DBG_log("sent DPD notification R_U_THERE_ACK with seqno = %u", seqno)
- )
-
- st->st_last_dpd = tm;
- return STF_IGNORE;
+ }
+ pbs->cur += COOKIE_SIZE;
+
+ if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid rcookie (broken Cisco?)");
+ return STF_FAIL + INVALID_COOKIE;
+ }
+ pbs->cur += COOKIE_SIZE;
+
+ if (pbs_left(pbs) != sizeof(seqno))
+ {
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE has invalid data length (%d)"
+ , (int) pbs_left(pbs));
+ return STF_FAIL + PAYLOAD_MALFORMED;
+ }
+
+ seqno = ntohl(*(u_int32_t *)pbs->cur);
+ DBG(DBG_CONTROL,
+ DBG_log("received DPD notification R_U_THERE with seqno = %u", seqno)
+ )
+
+ if (st->st_dpd_peerseqno && seqno <= st->st_dpd_peerseqno) {
+ loglog(RC_LOG_SERIOUS, "DPD: Received old or duplicate R_U_THERE");
+ return STF_IGNORE;
+ }
+
+ st->st_dpd_peerseqno = seqno;
+ delete_dpd_event(st);
+
+ if (send_isakmp_notification(st, R_U_THERE_ACK, pbs->cur, pbs_left(pbs)) != STF_IGNORE)
+ {
+ loglog(RC_LOG_SERIOUS, "DPD Info: could not send R_U_THERE_ACK");
+ return STF_IGNORE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("sent DPD notification R_U_THERE_ACK with seqno = %u", seqno)
+ )
+
+ st->st_last_dpd = tm;
+ return STF_IGNORE;
}
/*
* DPD out Responder
*/
-stf_status
-dpd_inR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
+stf_status dpd_inR(struct state *st, struct isakmp_notification *const n,
+ pb_stream *pbs)
{
- u_int32_t seqno;
+ u_int32_t seqno;
- if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: Received R_U_THERE_ACK for unestablished ISAKMP SA");
- return STF_FAIL;
- }
+ if (st == NULL || !IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "DPD: Received R_U_THERE_ACK for unestablished ISAKMP SA");
+ return STF_FAIL;
+ }
if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: R_U_THERE_ACK has invalid SPI length (%d)"
- , n->isan_spisize);
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
- {
+ {
+ loglog(RC_LOG_SERIOUS
+ , "DPD: R_U_THERE_ACK has invalid SPI length (%d)"
+ , n->isan_spisize);
+ return STF_FAIL + PAYLOAD_MALFORMED;
+ }
+
+ if (memcmp(pbs->cur, st->st_icookie, COOKIE_SIZE) != 0)
+ {
#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
+ /* Ignore it, cisco sends odd icookies */
#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid icookie");
- return STF_FAIL + INVALID_COOKIE;
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid icookie");
+ return STF_FAIL + INVALID_COOKIE;
#endif
- }
- pbs->cur += COOKIE_SIZE;
+ }
+ pbs->cur += COOKIE_SIZE;
- if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
- {
+ if (memcmp(pbs->cur, st->st_rcookie, COOKIE_SIZE) != 0)
+ {
#ifdef APPLY_CRISCO
- /* Ignore it, cisco sends odd icookies */
+ /* Ignore it, cisco sends odd icookies */
#else
- loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid rcookie");
- return STF_FAIL + INVALID_COOKIE;
+ loglog(RC_LOG_SERIOUS, "DPD: R_U_THERE_ACK has invalid rcookie");
+ return STF_FAIL + INVALID_COOKIE;
#endif
- }
- pbs->cur += COOKIE_SIZE;
-
- if (pbs_left(pbs) != sizeof(seqno))
- {
- loglog(RC_LOG_SERIOUS
- , " DPD: R_U_THERE_ACK has invalid data length (%d)"
- , (int) pbs_left(pbs));
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- seqno = ntohl(*(u_int32_t *)pbs->cur);
- DBG(DBG_CONTROL,
- DBG_log("received DPD notification R_U_THERE_ACK with seqno = %u"
- , seqno)
- )
-
- if (!st->st_dpd_expectseqno && seqno != st->st_dpd_expectseqno)
- {
- loglog(RC_LOG_SERIOUS
- , "DPD: R_U_THERE_ACK has unexpected sequence number");
- return STF_FAIL + PAYLOAD_MALFORMED;
- }
-
- st->st_dpd_expectseqno = 0;
- delete_dpd_event(st);
- return STF_IGNORE;
+ }
+ pbs->cur += COOKIE_SIZE;
+
+ if (pbs_left(pbs) != sizeof(seqno))
+ {
+ loglog(RC_LOG_SERIOUS
+ , " DPD: R_U_THERE_ACK has invalid data length (%d)"
+ , (int) pbs_left(pbs));
+ return STF_FAIL + PAYLOAD_MALFORMED;
+ }
+
+ seqno = ntohl(*(u_int32_t *)pbs->cur);
+ DBG(DBG_CONTROL,
+ DBG_log("received DPD notification R_U_THERE_ACK with seqno = %u"
+ , seqno)
+ )
+
+ if (!st->st_dpd_expectseqno && seqno != st->st_dpd_expectseqno)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "DPD: R_U_THERE_ACK has unexpected sequence number");
+ return STF_FAIL + PAYLOAD_MALFORMED;
+ }
+
+ st->st_dpd_expectseqno = 0;
+ delete_dpd_event(st);
+ return STF_IGNORE;
}
/*
@@ -5589,67 +5463,67 @@ dpd_inR(struct state *st, struct isakmp_notification *const n, pb_stream *pbs)
void
dpd_timeout(struct state *st)
{
- struct state *newest_phase1_st;
- struct connection *c = st->st_connection;
- int action = st->st_connection->dpd_action;
- char cname[BUF_LEN];
-
- passert(action == DPD_ACTION_HOLD
- || action == DPD_ACTION_CLEAR
- || DPD_ACTION_RESTART);
-
- /* is there a newer phase1_state? */
- newest_phase1_st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
- if (newest_phase1_st != NULL && newest_phase1_st != st)
- {
- plog("DPD: Phase1 state #%ld has been superseded by #%ld"
- " - timeout ignored"
- , st->st_serialno, newest_phase1_st->st_serialno);
- return;
- }
-
- loglog(RC_LOG_SERIOUS, "DPD: No response from peer - declaring peer dead");
-
- /* delete the state, which is probably in phase 2 */
- set_cur_connection(c);
- plog("DPD: Terminating all SAs using this connection");
- delete_states_by_connection(c, TRUE);
- reset_cur_connection();
-
- switch (action)
- {
- case DPD_ACTION_HOLD:
- /* dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
- * leak traffic. Also, being in %trap means new packets will
- * force an initiation of the conn again.
- */
- loglog(RC_LOG_SERIOUS, "DPD: Putting connection \"%s\" into %%trap", c->name);
- if (c->kind == CK_INSTANCE)
- delete_connection(c, TRUE);
- break;
- case DPD_ACTION_CLEAR:
- /* dpdaction=clear - Wipe the SA & eroute - everything */
- loglog(RC_LOG_SERIOUS, "DPD: Clearing connection \"%s\"", c->name);
- unroute_connection(c);
- if (c->kind == CK_INSTANCE)
- delete_connection(c, TRUE);
- break;
- case DPD_ACTION_RESTART:
- /* dpdaction=restart - Restart connection,
- * except if roadwarrior connection
- */
- loglog(RC_LOG_SERIOUS, "DPD: Restarting connection \"%s\"", c->name);
- unroute_connection(c);
-
- /* caching the connection name before deletion */
- strncpy(cname, c->name, BUF_LEN);
-
- if (c->kind == CK_INSTANCE)
- delete_connection(c, TRUE);
- initiate_connection(cname, NULL_FD);
- break;
- default:
- loglog(RC_LOG_SERIOUS, "DPD: unknown action");
- }
+ struct state *newest_phase1_st;
+ struct connection *c = st->st_connection;
+ int action = st->st_connection->dpd_action;
+ char cname[BUF_LEN];
+
+ passert(action == DPD_ACTION_HOLD
+ || action == DPD_ACTION_CLEAR
+ || DPD_ACTION_RESTART);
+
+ /* is there a newer phase1_state? */
+ newest_phase1_st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
+ if (newest_phase1_st != NULL && newest_phase1_st != st)
+ {
+ plog("DPD: Phase1 state #%ld has been superseded by #%ld"
+ " - timeout ignored"
+ , st->st_serialno, newest_phase1_st->st_serialno);
+ return;
+ }
+
+ loglog(RC_LOG_SERIOUS, "DPD: No response from peer - declaring peer dead");
+
+ /* delete the state, which is probably in phase 2 */
+ set_cur_connection(c);
+ plog("DPD: Terminating all SAs using this connection");
+ delete_states_by_connection(c, TRUE);
+ reset_cur_connection();
+
+ switch (action)
+ {
+ case DPD_ACTION_HOLD:
+ /* dpdaction=hold - Wipe the SA's but %trap the eroute so we don't
+ * leak traffic. Also, being in %trap means new packets will
+ * force an initiation of the conn again.
+ */
+ loglog(RC_LOG_SERIOUS, "DPD: Putting connection \"%s\" into %%trap", c->name);
+ if (c->kind == CK_INSTANCE)
+ delete_connection(c, TRUE);
+ break;
+ case DPD_ACTION_CLEAR:
+ /* dpdaction=clear - Wipe the SA & eroute - everything */
+ loglog(RC_LOG_SERIOUS, "DPD: Clearing connection \"%s\"", c->name);
+ unroute_connection(c);
+ if (c->kind == CK_INSTANCE)
+ delete_connection(c, TRUE);
+ break;
+ case DPD_ACTION_RESTART:
+ /* dpdaction=restart - Restart connection,
+ * except if roadwarrior connection
+ */
+ loglog(RC_LOG_SERIOUS, "DPD: Restarting connection \"%s\"", c->name);
+ unroute_connection(c);
+
+ /* caching the connection name before deletion */
+ strncpy(cname, c->name, BUF_LEN);
+
+ if (c->kind == CK_INSTANCE)
+ delete_connection(c, TRUE);
+ initiate_connection(cname, NULL_FD);
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "DPD: unknown action");
+ }
}
diff --git a/src/pluto/ipsec_doi.h b/src/pluto/ipsec_doi.h
index 60b5e4e31..2e242e903 100644
--- a/src/pluto/ipsec_doi.h
+++ b/src/pluto/ipsec_doi.h
@@ -10,55 +10,53 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ipsec_doi.h 3252 2007-10-06 21:24:50Z andreas $
*/
extern void echo_hdr(struct msg_digest *md, bool enc, u_int8_t np);
extern void ipsecdoi_initiate(int whack_sock, struct connection *c
- , lset_t policy, unsigned long try, so_serial_t replacing);
+ , lset_t policy, unsigned long try, so_serial_t replacing);
extern void ipsecdoi_replace(struct state *st, unsigned long try);
extern void init_phase2_iv(struct state *st, const msgid_t *msgid);
extern stf_status quick_outI1(int whack_sock
- , struct state *isakmp_sa
- , struct connection *c
- , lset_t policy
- , unsigned long try
- , so_serial_t replacing);
+ , struct state *isakmp_sa
+ , struct connection *c
+ , lset_t policy
+ , unsigned long try
+ , so_serial_t replacing);
extern state_transition_fn
- main_inI1_outR1,
- main_inR1_outI2,
- main_inI2_outR2,
- main_inR2_outI3,
- main_inI3_outR3,
- main_inR3,
- quick_inI1_outR1,
- quick_inR1_outI2,
- quick_inI2;
+ main_inI1_outR1,
+ main_inR1_outI2,
+ main_inI2_outR2,
+ main_inR2_outI3,
+ main_inI3_outR3,
+ main_inR3,
+ quick_inI1_outR1,
+ quick_inR1_outI2,
+ quick_inI2;
extern void send_delete(struct state *st);
extern void accept_delete(struct state *st, struct msg_digest *md
- , struct payload_digest *p);
+ , struct payload_digest *p);
extern void close_message(pb_stream *pbs);
extern bool encrypt_message(pb_stream *pbs, struct state *st);
extern void send_notification_from_state(struct state *st,
- enum state_kind state, u_int16_t type);
+ enum state_kind state, u_int16_t type);
extern void send_notification_from_md(struct msg_digest *md, u_int16_t type);
extern const char *init_pluto_vendorid(void);
extern void dpd_outI(struct state *st);
extern stf_status dpd_inI_outR(struct state *st
- , struct isakmp_notification *const n, pb_stream *n_pbs);
+ , struct isakmp_notification *const n, pb_stream *n_pbs);
extern stf_status dpd_inR(struct state *st
- , struct isakmp_notification *const n, pb_stream *n_pbs);
+ , struct isakmp_notification *const n, pb_stream *n_pbs);
extern void dpd_timeout(struct state *st);
/* START_HASH_PAYLOAD
@@ -70,14 +68,14 @@ extern void dpd_timeout(struct state *st);
* - it references variables local to the caller (r_hashval, r_hash_start, st)
*/
#define START_HASH_PAYLOAD(rbody, np) { \
- pb_stream hash_pbs; \
- if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
- return STF_INTERNAL_ERROR; \
- r_hashval = hash_pbs.cur; /* remember where to plant value */ \
- if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
- return STF_INTERNAL_ERROR; \
- close_output_pbs(&hash_pbs); \
- r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
+ pb_stream hash_pbs; \
+ if (!out_generic(np, &isakmp_hash_desc, &(rbody), &hash_pbs)) \
+ return STF_INTERNAL_ERROR; \
+ r_hashval = hash_pbs.cur; /* remember where to plant value */ \
+ if (!out_zero(st->st_oakley.hasher->hash_digest_size, &hash_pbs, "HASH")) \
+ return STF_INTERNAL_ERROR; \
+ close_output_pbs(&hash_pbs); \
+ r_hash_start = (rbody).cur; /* hash from after HASH payload */ \
}
/* CHECK_QUICK_HASH
@@ -88,17 +86,17 @@ extern void dpd_timeout(struct state *st);
* expression to reference them (hash_val, hash_pbs)
*/
#define CHECK_QUICK_HASH(md, do_hash, hash_name, msg_name) { \
- pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
- u_char hash_val[MAX_DIGEST_LEN]; \
- size_t hash_len = do_hash; \
- if (pbs_left(hash_pbs) != hash_len \
- || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
- { \
- DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \
- loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \
- /* XXX Could send notification back */ \
- return STF_FAIL + INVALID_HASH_INFORMATION; \
- } \
- }
+ pb_stream *const hash_pbs = &md->chain[ISAKMP_NEXT_HASH]->pbs; \
+ u_char hash_val[MAX_DIGEST_LEN]; \
+ size_t hash_len = do_hash; \
+ if (pbs_left(hash_pbs) != hash_len \
+ || memcmp(hash_pbs->cur, hash_val, hash_len) != 0) \
+ { \
+ DBG_cond_dump(DBG_CRYPT, "received " hash_name ":", hash_pbs->cur, pbs_left(hash_pbs)); \
+ loglog(RC_LOG_SERIOUS, "received " hash_name " does not match computed value in " msg_name); \
+ /* XXX Could send notification back */ \
+ return STF_FAIL + INVALID_HASH_INFORMATION; \
+ } \
+ }
diff --git a/src/pluto/kameipsec.h b/src/pluto/kameipsec.h
index 5f08c7d38..5e9d8ce99 100644
--- a/src/pluto/kameipsec.h
+++ b/src/pluto/kameipsec.h
@@ -3,45 +3,45 @@
/* The definitions, required to talk to KAME racoon IKE. */
-#define IPSEC_PORT_ANY 0
-#define IPSEC_ULPROTO_ANY 255
-#define IPSEC_PROTO_ANY 255
+#define IPSEC_PORT_ANY 0
+#define IPSEC_ULPROTO_ANY 255
+#define IPSEC_PROTO_ANY 255
enum {
- IPSEC_MODE_ANY = 0, /* We do not support this for SA */
- IPSEC_MODE_TRANSPORT = 1,
- IPSEC_MODE_TUNNEL = 2
+ IPSEC_MODE_ANY = 0, /* We do not support this for SA */
+ IPSEC_MODE_TRANSPORT = 1,
+ IPSEC_MODE_TUNNEL = 2
};
enum {
- IPSEC_DIR_ANY = 0,
- IPSEC_DIR_INBOUND = 1,
- IPSEC_DIR_OUTBOUND = 2,
- IPSEC_DIR_FWD = 3, /* It is our own */
- IPSEC_DIR_MAX = 4,
- IPSEC_DIR_INVALID = 5
+ IPSEC_DIR_ANY = 0,
+ IPSEC_DIR_INBOUND = 1,
+ IPSEC_DIR_OUTBOUND = 2,
+ IPSEC_DIR_FWD = 3, /* It is our own */
+ IPSEC_DIR_MAX = 4,
+ IPSEC_DIR_INVALID = 5
};
enum {
- IPSEC_POLICY_DISCARD = 0,
- IPSEC_POLICY_NONE = 1,
- IPSEC_POLICY_IPSEC = 2,
- IPSEC_POLICY_ENTRUST = 3,
- IPSEC_POLICY_BYPASS = 4
+ IPSEC_POLICY_DISCARD = 0,
+ IPSEC_POLICY_NONE = 1,
+ IPSEC_POLICY_IPSEC = 2,
+ IPSEC_POLICY_ENTRUST = 3,
+ IPSEC_POLICY_BYPASS = 4
};
enum {
- IPSEC_LEVEL_DEFAULT = 0,
- IPSEC_LEVEL_USE = 1,
- IPSEC_LEVEL_REQUIRE = 2,
- IPSEC_LEVEL_UNIQUE = 3
+ IPSEC_LEVEL_DEFAULT = 0,
+ IPSEC_LEVEL_USE = 1,
+ IPSEC_LEVEL_REQUIRE = 2,
+ IPSEC_LEVEL_UNIQUE = 3
};
-#define IPSEC_MANUAL_REQID_MAX 0x3fff
+#define IPSEC_MANUAL_REQID_MAX 0x3fff
#define IPSEC_REPLAYWSIZE 32
#define IP_IPSEC_POLICY 16
#define IPV6_IPSEC_POLICY 34
-#endif /* __IPSEC_H */
+#endif /* __IPSEC_H */
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index d42ac3372..f698de2c8 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel.c 3846 2008-04-18 17:01:45Z andreas $
*/
#include <stddef.h>
@@ -31,12 +29,14 @@
#include <arpa/inet.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <library.h>
+#include <crypto/rngs/rng.h>
#ifdef KLIPS
#include <signal.h>
-#include <sys/time.h> /* for select(2) */
-#include <sys/types.h> /* for select(2) */
+#include <sys/time.h> /* for select(2) */
+#include <sys/types.h> /* for select(2) */
#include <pfkeyv2.h>
#include <pfkey.h>
#include "kameipsec.h"
@@ -44,7 +44,6 @@
#include "constants.h"
#include "defs.h"
-#include "rnd.h"
#include "id.h"
#include "connections.h"
#include "state.h"
@@ -56,7 +55,7 @@
#include "log.h"
#include "ca.h"
#include "server.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "keys.h"
#include "nat_traversal.h"
#include "alg_info.h"
@@ -69,7 +68,7 @@ bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
* logic loses track and swats them? 64 is the best KLIPS can do.
* And 32 is the best XFRM can do...
*/
-#define REPLAY_WINDOW 64
+#define REPLAY_WINDOW 64
#define REPLAY_WINDOW_XFRM 32
/* test if the routes required for two different connections agree
@@ -77,11 +76,11 @@ bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
* testing that the interfaces and nexthops match.
*/
#define routes_agree(c, d) ((c)->interface == (d)->interface \
- && sameaddr(&(c)->spd.this.host_nexthop, &(d)->spd.this.host_nexthop))
+ && sameaddr(&(c)->spd.this.host_nexthop, &(d)->spd.this.host_nexthop))
#ifndef KLIPS
-bool no_klips = TRUE; /* don't actually use KLIPS */
+bool no_klips = TRUE; /* don't actually use KLIPS */
#else /* !KLIPS */
@@ -96,50 +95,49 @@ bool no_klips = TRUE; /* don't actually use KLIPS */
* which %holds are news and which others should expire.
*/
-#define SHUNT_SCAN_INTERVAL (60 * 2) /* time between scans of eroutes */
+#define SHUNT_SCAN_INTERVAL (60 * 2) /* time between scans of eroutes */
/* SHUNT_PATIENCE only has resolution down to a multiple of the sample rate,
* SHUNT_SCAN_INTERVAL.
* By making SHUNT_PATIENCE an odd multiple of half of SHUNT_SCAN_INTERVAL,
* we minimize the effects of jitter.
*/
-#define SHUNT_PATIENCE (SHUNT_SCAN_INTERVAL * 15 / 2) /* inactivity timeout */
+#define SHUNT_PATIENCE (SHUNT_SCAN_INTERVAL * 15 / 2) /* inactivity timeout */
struct bare_shunt {
- policy_prio_t policy_prio;
- ip_subnet ours;
- ip_subnet his;
- ip_said said;
- int transport_proto;
- unsigned long count;
- time_t last_activity;
- char *why;
- struct bare_shunt *next;
+ policy_prio_t policy_prio;
+ ip_subnet ours;
+ ip_subnet his;
+ ip_said said;
+ int transport_proto;
+ unsigned long count;
+ time_t last_activity;
+ char *why;
+ struct bare_shunt *next;
};
static struct bare_shunt *bare_shunts = NULL;
#ifdef DEBUG
-static void
-DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
+static void DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
{
- DBG(DBG_KLIPS,
- {
- int ourport = ntohs(portof(&(bs)->ours.addr));
- int hisport = ntohs(portof(&(bs)->his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
- char prio[POLICY_PRIO_BUF];
-
- subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
- subnettot(&(bs)->his, 0, hist, sizeof(hist));
- satot(&(bs)->said, 0, sat, sizeof(sat));
- fmt_policy_prio(bs->policy_prio, prio);
- DBG_log("%s bare shunt %p %s:%d -> %s:%d => %s:%d %s %s"
- , op, (const void *)(bs), ourst, ourport, hist, hisport
- , sat, (bs)->transport_proto, prio, (bs)->why);
- });
+ DBG(DBG_KLIPS,
+ {
+ int ourport = ntohs(portof(&(bs)->ours.addr));
+ int hisport = ntohs(portof(&(bs)->his.addr));
+ char ourst[SUBNETTOT_BUF];
+ char hist[SUBNETTOT_BUF];
+ char sat[SATOT_BUF];
+ char prio[POLICY_PRIO_BUF];
+
+ subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
+ subnettot(&(bs)->his, 0, hist, sizeof(hist));
+ satot(&(bs)->said, 0, sat, sizeof(sat));
+ fmt_policy_prio(bs->policy_prio, prio);
+ DBG_log("%s bare shunt %p %s:%d -> %s:%d => %s:%d %s %s"
+ , op, (const void *)(bs), ourst, ourport, hist, hisport
+ , sat, (bs)->transport_proto, prio, (bs)->why);
+ });
}
#else /* !DEBUG */
#define DBG_bare_shunt(op, bs) {}
@@ -152,112 +150,108 @@ DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
struct eroute_info *orphaned_holds = NULL;
/* forward declaration */
-static bool shunt_eroute(struct connection *c
- , struct spd_route *sr
- , enum routing_t rt_kind
- , unsigned int op, const char *opname);
-static void set_text_said(char *text_said
- , const ip_address *dst
- , ipsec_spi_t spi
- , int proto);
+static bool shunt_eroute(struct connection *c, struct spd_route *sr,
+ enum routing_t rt_kind, unsigned int op,
+ const char *opname);
+
+static void set_text_said(char *text_said, const ip_address *dst,
+ ipsec_spi_t spi, int proto);
-bool no_klips = FALSE; /* don't actually use KLIPS */
+bool no_klips = FALSE; /* don't actually use KLIPS */
static const struct pfkey_proto_info null_proto_info[2] = {
+ {
+ proto: IPPROTO_ESP,
+ encapsulation: ENCAPSULATION_MODE_TRANSPORT,
+ reqid: 0
+ },
+ {
+ proto: 0,
+ encapsulation: 0,
+ reqid: 0
+ }
+};
+
+void record_and_initiate_opportunistic(const ip_subnet *ours,
+ const ip_subnet *his,
+ int transport_proto, const char *why)
+{
+ passert(samesubnettype(ours, his));
+
+ /* Add to bare shunt list.
+ * We need to do this because the shunt was installed by KLIPS
+ * which can't do this itself.
+ */
{
- proto: IPPROTO_ESP,
- encapsulation: ENCAPSULATION_MODE_TRANSPORT,
- reqid: 0
- },
+ struct bare_shunt *bs = malloc_thing(struct bare_shunt);
+
+ bs->why = clone_str(why);
+ bs->ours = *ours;
+ bs->his = *his;
+ bs->transport_proto = transport_proto;
+ bs->policy_prio = BOTTOM_PRIO;
+
+ bs->said.proto = SA_INT;
+ bs->said.spi = htonl(SPI_HOLD);
+ bs->said.dst = *aftoinfo(subnettypeof(ours))->any;
+
+ bs->count = 0;
+ bs->last_activity = now();
+
+ bs->next = bare_shunts;
+ bare_shunts = bs;
+ DBG_bare_shunt("add", bs);
+ }
+
+ /* actually initiate opportunism */
{
- proto: 0,
- encapsulation: 0,
- reqid: 0
+ ip_address src, dst;
+
+ networkof(ours, &src);
+ networkof(his, &dst);
+ initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
}
-};
-void
-record_and_initiate_opportunistic(const ip_subnet *ours
- , const ip_subnet *his
- , int transport_proto
- , const char *why)
-{
- passert(samesubnettype(ours, his));
-
- /* Add to bare shunt list.
- * We need to do this because the shunt was installed by KLIPS
- * which can't do this itself.
- */
- {
- struct bare_shunt *bs = alloc_thing(struct bare_shunt, "bare shunt");
-
- bs->why = clone_str(why, "story for bare shunt");
- bs->ours = *ours;
- bs->his = *his;
- bs->transport_proto = transport_proto;
- bs->policy_prio = BOTTOM_PRIO;
-
- bs->said.proto = SA_INT;
- bs->said.spi = htonl(SPI_HOLD);
- bs->said.dst = *aftoinfo(subnettypeof(ours))->any;
-
- bs->count = 0;
- bs->last_activity = now();
-
- bs->next = bare_shunts;
- bare_shunts = bs;
- DBG_bare_shunt("add", bs);
- }
-
- /* actually initiate opportunism */
- {
- ip_address src, dst;
-
- networkof(ours, &src);
- networkof(his, &dst);
- initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
- }
-
- /* if present, remove from orphaned_holds list.
- * NOTE: we do this last in case ours or his is a pointer into a member.
- */
- {
- struct eroute_info **pp, *p;
-
- for (pp = &orphaned_holds; (p = *pp) != NULL; pp = &p->next)
- {
- if (samesubnet(ours, &p->ours)
- && samesubnet(his, &p->his)
- && transport_proto == p->transport_proto
- && portof(&ours->addr) == portof(&p->ours.addr)
- && portof(&his->addr) == portof(&p->his.addr))
- {
- *pp = p->next;
- pfree(p);
- break;
- }
+ /* if present, remove from orphaned_holds list.
+ * NOTE: we do this last in case ours or his is a pointer into a member.
+ */
+ {
+ struct eroute_info **pp, *p;
+
+ for (pp = &orphaned_holds; (p = *pp) != NULL; pp = &p->next)
+ {
+ if (samesubnet(ours, &p->ours)
+ && samesubnet(his, &p->his)
+ && transport_proto == p->transport_proto
+ && portof(&ours->addr) == portof(&p->ours.addr)
+ && portof(&his->addr) == portof(&p->his.addr))
+ {
+ *pp = p->next;
+ free(p);
+ break;
+ }
+ }
}
- }
}
#endif /* KLIPS */
static unsigned get_proto_reqid(unsigned base, int proto)
{
- switch (proto)
- {
- default:
- case IPPROTO_COMP:
- base++;
- /* fall through */
- case IPPROTO_ESP:
- base++;
- /* fall through */
- case IPPROTO_AH:
- break;
- }
-
- return base;
+ switch (proto)
+ {
+ default:
+ case IPPROTO_COMP:
+ base++;
+ /* fall through */
+ case IPPROTO_ESP:
+ base++;
+ /* fall through */
+ case IPPROTO_AH:
+ break;
+ }
+
+ return base;
}
/* Generate Unique SPI numbers.
@@ -281,33 +275,39 @@ static unsigned get_proto_reqid(unsigned base, int proto)
* check if the number was previously used (assuming that no
* SPI lives longer than 4G of its successors).
*/
-ipsec_spi_t
-get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
+ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
+ bool tunnel)
{
- static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
- char text_said[SATOT_BUF];
+ static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
+ char text_said[SATOT_BUF];
+ rng_t *rng;
- set_text_said(text_said, &sr->this.host_addr, 0, proto);
+ set_text_said(text_said, &sr->this.host_addr, 0, proto);
- if (kernel_ops->get_spi)
- return kernel_ops->get_spi(&sr->that.host_addr
- , &sr->this.host_addr, proto, tunnel
- , get_proto_reqid(sr->reqid, proto)
- , IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
- , text_said);
-
- spi++;
- while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
- get_rnd_bytes((u_char *)&spi, sizeof(spi));
+ if (kernel_ops->get_spi)
+ {
+ return kernel_ops->get_spi(&sr->that.host_addr
+ , &sr->this.host_addr, proto, tunnel
+ , get_proto_reqid(sr->reqid, proto)
+ , IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
+ , text_said);
+ }
- DBG(DBG_CONTROL,
+ spi++;
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
{
- ipsec_spi_t spi_net = htonl(spi);
+ rng->get_bytes(rng, sizeof(spi), (u_char *)&spi);
+ }
+ rng->destroy(rng);
+ DBG(DBG_CONTROL,
+ {
+ ipsec_spi_t spi_net = htonl(spi);
- DBG_dump("generate SPI:", (u_char *)&spi_net, sizeof(spi_net));
- });
+ DBG_dump("generate SPI:", (u_char *)&spi_net, sizeof(spi_net));
+ });
- return htonl(spi);
+ return htonl(spi);
}
/* Generate Unique CPI numbers.
@@ -318,38 +318,40 @@ get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr, bool tunnel)
* If we can't find one easily, return 0 (a bad SPI,
* no matter what order) indicating failure.
*/
-ipsec_spi_t
-get_my_cpi(struct spd_route *sr, bool tunnel)
+ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel)
{
- static cpi_t
- first_busy_cpi = 0,
- latest_cpi;
- char text_said[SATOT_BUF];
+ static cpi_t first_busy_cpi = 0, latest_cpi;
+ char text_said[SATOT_BUF];
+ rng_t *rng;
- set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
+ set_text_said(text_said, &sr->this.host_addr, 0, IPPROTO_COMP);
- if (kernel_ops->get_spi)
- return kernel_ops->get_spi(&sr->that.host_addr
- , &sr->this.host_addr, IPPROTO_COMP, tunnel
- , get_proto_reqid(sr->reqid, IPPROTO_COMP)
- , IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
- , text_said);
+ if (kernel_ops->get_spi)
+ {
+ return kernel_ops->get_spi(&sr->that.host_addr
+ , &sr->this.host_addr, IPPROTO_COMP, tunnel
+ , get_proto_reqid(sr->reqid, IPPROTO_COMP)
+ , IPCOMP_FIRST_NEGOTIATED, IPCOMP_LAST_NEGOTIATED
+ , text_said);
+ }
- while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
- {
- get_rnd_bytes((u_char *)&first_busy_cpi, sizeof(first_busy_cpi));
- latest_cpi = first_busy_cpi;
- }
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ while (!(IPCOMP_FIRST_NEGOTIATED <= first_busy_cpi && first_busy_cpi < IPCOMP_LAST_NEGOTIATED))
+ {
+ rng->get_bytes(rng, sizeof(first_busy_cpi), (u_char *)&first_busy_cpi);
+ latest_cpi = first_busy_cpi;
+ }
+ rng->destroy(rng);
- latest_cpi++;
+ latest_cpi++;
- if (latest_cpi == first_busy_cpi)
- find_my_cpi_gap(&latest_cpi, &first_busy_cpi);
+ if (latest_cpi == first_busy_cpi)
+ find_my_cpi_gap(&latest_cpi, &first_busy_cpi);
- if (latest_cpi > IPCOMP_LAST_NEGOTIATED)
- latest_cpi = IPCOMP_FIRST_NEGOTIATED;
+ if (latest_cpi > IPCOMP_LAST_NEGOTIATED)
+ latest_cpi = IPCOMP_FIRST_NEGOTIATED;
- return htonl((ipsec_spi_t)latest_cpi);
+ return htonl((ipsec_spi_t)latest_cpi);
}
/* invoke the updown script to do the routing and firewall commands required
@@ -386,872 +388,864 @@ get_my_cpi(struct spd_route *sr, bool tunnel)
*/
#ifndef DEFAULT_UPDOWN
-# define DEFAULT_UPDOWN "ipsec _updown"
+# define DEFAULT_UPDOWN "ipsec _updown"
#endif
-static bool
-do_command(struct connection *c, struct spd_route *sr, const char *verb)
+static bool do_command(struct connection *c, struct spd_route *sr,
+ const char *verb)
{
- char cmd[1536]; /* arbitrary limit on shell command length */
- const char *verb_suffix;
+ char cmd[1536]; /* arbitrary limit on shell command length */
+ const char *verb_suffix;
- /* figure out which verb suffix applies */
- {
- const char *hs, *cs;
-
- switch (addrtypeof(&sr->this.host_addr))
+ /* figure out which verb suffix applies */
{
- case AF_INET:
- hs = "-host";
- cs = "-client";
- break;
- case AF_INET6:
- hs = "-host-v6";
- cs = "-client-v6";
- break;
- default:
- loglog(RC_LOG_SERIOUS, "unknown address family");
- return FALSE;
- }
- verb_suffix = subnetisaddr(&sr->this.client, &sr->this.host_addr)
- ? hs : cs;
- }
-
- /* form the command string */
- {
- char
- nexthop_str[sizeof("PLUTO_NEXT_HOP='' ") +ADDRTOT_BUF] = "",
- srcip_str[sizeof("PLUTO_MY_SOURCEIP='' ")+ADDRTOT_BUF] = "",
- me_str[ADDRTOT_BUF],
- myid_str[BUF_LEN],
- myclient_str[SUBNETTOT_BUF],
- myclientnet_str[ADDRTOT_BUF],
- myclientmask_str[ADDRTOT_BUF],
- peer_str[ADDRTOT_BUF],
- peerid_str[BUF_LEN],
- peerclient_str[SUBNETTOT_BUF],
- peerclientnet_str[ADDRTOT_BUF],
- peerclientmask_str[ADDRTOT_BUF],
- peerca_str[BUF_LEN],
- secure_myid_str[BUF_LEN] = "",
- secure_peerid_str[BUF_LEN] = "",
- secure_peerca_str[BUF_LEN] = "";
- ip_address ta;
- pubkey_list_t *p;
-
- if (addrbytesptr(&sr->this.host_nexthop, NULL)
- && !isanyaddr(&sr->this.host_nexthop))
- {
- char *n;
-
- strcpy(nexthop_str, "PLUTO_NEXT_HOP='");
- n = nexthop_str + strlen(nexthop_str);
-
- addrtot(&sr->this.host_nexthop, 0
- ,n , sizeof(nexthop_str)-strlen(nexthop_str));
- strncat(nexthop_str, "' ", sizeof(nexthop_str));
- }
-
- if (addrbytesptr(&sr->this.host_srcip, NULL)
- && !isanyaddr(&sr->this.host_srcip))
- {
- char *n;
-
- strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
- n = srcip_str + strlen(srcip_str);
-
- addrtot(&sr->this.host_srcip, 0
- ,n , sizeof(srcip_str)-strlen(srcip_str));
- strncat(srcip_str, "' ", sizeof(srcip_str));
- }
-
- addrtot(&sr->this.host_addr, 0, me_str, sizeof(me_str));
- idtoa(&sr->this.id, myid_str, sizeof(myid_str));
- escape_metachar(myid_str, secure_myid_str, sizeof(secure_myid_str));
- subnettot(&sr->this.client, 0, myclient_str, sizeof(myclientnet_str));
- networkof(&sr->this.client, &ta);
- addrtot(&ta, 0, myclientnet_str, sizeof(myclientnet_str));
- maskof(&sr->this.client, &ta);
- addrtot(&ta, 0, myclientmask_str, sizeof(myclientmask_str));
-
- addrtot(&sr->that.host_addr, 0, peer_str, sizeof(peer_str));
- idtoa(&sr->that.id, peerid_str, sizeof(peerid_str));
- escape_metachar(peerid_str, secure_peerid_str, sizeof(secure_peerid_str));
- subnettot(&sr->that.client, 0, peerclient_str, sizeof(peerclientnet_str));
- networkof(&sr->that.client, &ta);
- addrtot(&ta, 0, peerclientnet_str, sizeof(peerclientnet_str));
- maskof(&sr->that.client, &ta);
- addrtot(&ta, 0, peerclientmask_str, sizeof(peerclientmask_str));
-
- for (p = pubkeys; p != NULL; p = p->next)
- {
- pubkey_t *key = p->key;
- int pathlen;
-
- if (key->alg == PUBKEY_ALG_RSA && same_id(&sr->that.id, &key->id)
- && trusted_ca(key->issuer, sr->that.ca, &pathlen))
- {
- dntoa_or_null(peerca_str, BUF_LEN, key->issuer, "");
- escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str));
- break;
- }
- }
-
- if (-1 == snprintf(cmd, sizeof(cmd)
- , "2>&1 " /* capture stderr along with stdout */
- "PLUTO_VERSION='1.1' " /* change VERSION when interface spec changes */
- "PLUTO_VERB='%s%s' "
- "PLUTO_CONNECTION='%s' "
- "%s" /* optional PLUTO_NEXT_HOP */
- "PLUTO_INTERFACE='%s' "
- "%s" /* optional PLUTO_HOST_ACCESS */
- "PLUTO_REQID='%u' "
- "PLUTO_ME='%s' "
- "PLUTO_MY_ID='%s' "
- "PLUTO_MY_CLIENT='%s' "
- "PLUTO_MY_CLIENT_NET='%s' "
- "PLUTO_MY_CLIENT_MASK='%s' "
- "PLUTO_MY_PORT='%u' "
- "PLUTO_MY_PROTOCOL='%u' "
- "PLUTO_PEER='%s' "
- "PLUTO_PEER_ID='%s' "
- "PLUTO_PEER_CLIENT='%s' "
- "PLUTO_PEER_CLIENT_NET='%s' "
- "PLUTO_PEER_CLIENT_MASK='%s' "
- "PLUTO_PEER_PORT='%u' "
- "PLUTO_PEER_PROTOCOL='%u' "
- "PLUTO_PEER_CA='%s' "
- "%s" /* optional PLUTO_MY_SRCIP */
- "%s" /* actual script */
- , verb, verb_suffix
- , c->name
- , nexthop_str
- , c->interface->vname
- , sr->this.hostaccess? "PLUTO_HOST_ACCESS='1' " : ""
- , sr->reqid + 1 /* ESP requid */
- , me_str
- , secure_myid_str
- , myclient_str
- , myclientnet_str
- , myclientmask_str
- , sr->this.port
- , sr->this.protocol
- , peer_str
- , secure_peerid_str
- , peerclient_str
- , peerclientnet_str
- , peerclientmask_str
- , sr->that.port
- , sr->that.protocol
- , secure_peerca_str
- , srcip_str
- , sr->this.updown == NULL? DEFAULT_UPDOWN : sr->this.updown))
- {
- loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb, verb_suffix);
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL, DBG_log("executing %s%s: %s"
- , verb, verb_suffix, cmd));
+ const char *hs, *cs;
-#ifdef KLIPS
- if (!no_klips)
- {
- /* invoke the script, catching stderr and stdout
- * It may be of concern that some file descriptors will
- * be inherited. For the ones under our control, we
- * have done fcntl(fd, F_SETFD, FD_CLOEXEC) to prevent this.
- * Any used by library routines (perhaps the resolver or syslog)
- * will remain.
- */
- FILE *f = popen(cmd, "r");
-
- if (f == NULL)
- {
- loglog(RC_LOG_SERIOUS, "unable to popen %s%s command", verb, verb_suffix);
- return FALSE;
+ switch (addrtypeof(&sr->this.host_addr))
+ {
+ case AF_INET:
+ hs = "-host";
+ cs = "-client";
+ break;
+ case AF_INET6:
+ hs = "-host-v6";
+ cs = "-client-v6";
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "unknown address family");
+ return FALSE;
+ }
+ verb_suffix = subnetisaddr(&sr->this.client, &sr->this.host_addr)
+ ? hs : cs;
}
- /* log any output */
- for (;;)
+ /* form the command string */
{
- /* if response doesn't fit in this buffer, it will be folded */
- char resp[256];
+ char
+ nexthop_str[sizeof("PLUTO_NEXT_HOP='' ") +ADDRTOT_BUF] = "",
+ srcip_str[sizeof("PLUTO_MY_SOURCEIP='' ")+ADDRTOT_BUF] = "",
+ me_str[ADDRTOT_BUF],
+ myid_str[BUF_LEN],
+ myclient_str[SUBNETTOT_BUF],
+ myclientnet_str[ADDRTOT_BUF],
+ myclientmask_str[ADDRTOT_BUF],
+ peer_str[ADDRTOT_BUF],
+ peerid_str[BUF_LEN],
+ peerclient_str[SUBNETTOT_BUF],
+ peerclientnet_str[ADDRTOT_BUF],
+ peerclientmask_str[ADDRTOT_BUF],
+ peerca_str[BUF_LEN],
+ secure_myid_str[BUF_LEN] = "",
+ secure_peerid_str[BUF_LEN] = "",
+ secure_peerca_str[BUF_LEN] = "";
+ ip_address ta;
+ pubkey_list_t *p;
+
+ if (addrbytesptr(&sr->this.host_nexthop, NULL)
+ && !isanyaddr(&sr->this.host_nexthop))
+ {
+ char *n;
+
+ strcpy(nexthop_str, "PLUTO_NEXT_HOP='");
+ n = nexthop_str + strlen(nexthop_str);
+
+ addrtot(&sr->this.host_nexthop, 0
+ ,n , sizeof(nexthop_str)-strlen(nexthop_str));
+ strncat(nexthop_str, "' ", sizeof(nexthop_str));
+ }
- if (fgets(resp, sizeof(resp), f) == NULL)
- {
- if (ferror(f))
+ if (addrbytesptr(&sr->this.host_srcip, NULL)
+ && !isanyaddr(&sr->this.host_srcip))
{
- log_errno((e, "fgets failed on output of %s%s command"
- , verb, verb_suffix));
- return FALSE;
+ char *n;
+
+ strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
+ n = srcip_str + strlen(srcip_str);
+
+ addrtot(&sr->this.host_srcip, 0
+ ,n , sizeof(srcip_str)-strlen(srcip_str));
+ strncat(srcip_str, "' ", sizeof(srcip_str));
}
- else
+
+ addrtot(&sr->this.host_addr, 0, me_str, sizeof(me_str));
+ idtoa(&sr->this.id, myid_str, sizeof(myid_str));
+ escape_metachar(myid_str, secure_myid_str, sizeof(secure_myid_str));
+ subnettot(&sr->this.client, 0, myclient_str, sizeof(myclientnet_str));
+ networkof(&sr->this.client, &ta);
+ addrtot(&ta, 0, myclientnet_str, sizeof(myclientnet_str));
+ maskof(&sr->this.client, &ta);
+ addrtot(&ta, 0, myclientmask_str, sizeof(myclientmask_str));
+
+ addrtot(&sr->that.host_addr, 0, peer_str, sizeof(peer_str));
+ idtoa(&sr->that.id, peerid_str, sizeof(peerid_str));
+ escape_metachar(peerid_str, secure_peerid_str, sizeof(secure_peerid_str));
+ subnettot(&sr->that.client, 0, peerclient_str, sizeof(peerclientnet_str));
+ networkof(&sr->that.client, &ta);
+ addrtot(&ta, 0, peerclientnet_str, sizeof(peerclientnet_str));
+ maskof(&sr->that.client, &ta);
+ addrtot(&ta, 0, peerclientmask_str, sizeof(peerclientmask_str));
+
+ for (p = pubkeys; p != NULL; p = p->next)
{
- passert(feof(f));
- break;
+ pubkey_t *key = p->key;
+ key_type_t type = key->public_key->get_type(key->public_key);
+ int pathlen;
+
+ if (type == KEY_RSA && same_id(&sr->that.id, &key->id) &&
+ trusted_ca(key->issuer, sr->that.ca, &pathlen))
+ {
+ dntoa_or_null(peerca_str, BUF_LEN, key->issuer, "");
+ escape_metachar(peerca_str, secure_peerca_str, sizeof(secure_peerca_str));
+ break;
+ }
}
- }
- else
- {
- char *e = resp + strlen(resp);
- if (e > resp && e[-1] == '\n')
- e[-1] = '\0'; /* trim trailing '\n' */
- plog("%s%s output: %s", verb, verb_suffix, resp);
- }
+ if (-1 == snprintf(cmd, sizeof(cmd)
+ , "2>&1 " /* capture stderr along with stdout */
+ "PLUTO_VERSION='1.1' " /* change VERSION when interface spec changes */
+ "PLUTO_VERB='%s%s' "
+ "PLUTO_CONNECTION='%s' "
+ "%s" /* optional PLUTO_NEXT_HOP */
+ "PLUTO_INTERFACE='%s' "
+ "%s" /* optional PLUTO_HOST_ACCESS */
+ "PLUTO_REQID='%u' "
+ "PLUTO_ME='%s' "
+ "PLUTO_MY_ID='%s' "
+ "PLUTO_MY_CLIENT='%s' "
+ "PLUTO_MY_CLIENT_NET='%s' "
+ "PLUTO_MY_CLIENT_MASK='%s' "
+ "PLUTO_MY_PORT='%u' "
+ "PLUTO_MY_PROTOCOL='%u' "
+ "PLUTO_PEER='%s' "
+ "PLUTO_PEER_ID='%s' "
+ "PLUTO_PEER_CLIENT='%s' "
+ "PLUTO_PEER_CLIENT_NET='%s' "
+ "PLUTO_PEER_CLIENT_MASK='%s' "
+ "PLUTO_PEER_PORT='%u' "
+ "PLUTO_PEER_PROTOCOL='%u' "
+ "PLUTO_PEER_CA='%s' "
+ "%s" /* optional PLUTO_MY_SRCIP */
+ "%s" /* actual script */
+ , verb, verb_suffix
+ , c->name
+ , nexthop_str
+ , c->interface->vname
+ , sr->this.hostaccess? "PLUTO_HOST_ACCESS='1' " : ""
+ , sr->reqid + 1 /* ESP requid */
+ , me_str
+ , secure_myid_str
+ , myclient_str
+ , myclientnet_str
+ , myclientmask_str
+ , sr->this.port
+ , sr->this.protocol
+ , peer_str
+ , secure_peerid_str
+ , peerclient_str
+ , peerclientnet_str
+ , peerclientmask_str
+ , sr->that.port
+ , sr->that.protocol
+ , secure_peerca_str
+ , srcip_str
+ , sr->this.updown == NULL? DEFAULT_UPDOWN : sr->this.updown))
+ {
+ loglog(RC_LOG_SERIOUS, "%s%s command too long!", verb, verb_suffix);
+ return FALSE;
+ }
}
- /* report on and react to return code */
+ DBG(DBG_CONTROL, DBG_log("executing %s%s: %s"
+ , verb, verb_suffix, cmd));
+
+#ifdef KLIPS
+ if (!no_klips)
{
- int r = pclose(f);
+ /* invoke the script, catching stderr and stdout
+ * It may be of concern that some file descriptors will
+ * be inherited. For the ones under our control, we
+ * have done fcntl(fd, F_SETFD, FD_CLOEXEC) to prevent this.
+ * Any used by library routines (perhaps the resolver or syslog)
+ * will remain.
+ */
+ FILE *f = popen(cmd, "r");
- if (r == -1)
- {
- log_errno((e, "pclose failed for %s%s command"
- , verb, verb_suffix));
- return FALSE;
- }
- else if (WIFEXITED(r))
- {
- if (WEXITSTATUS(r) != 0)
+ if (f == NULL)
{
- loglog(RC_LOG_SERIOUS, "%s%s command exited with status %d"
- , verb, verb_suffix, WEXITSTATUS(r));
- return FALSE;
+ loglog(RC_LOG_SERIOUS, "unable to popen %s%s command", verb, verb_suffix);
+ return FALSE;
+ }
+
+ /* log any output */
+ for (;;)
+ {
+ /* if response doesn't fit in this buffer, it will be folded */
+ char resp[256];
+
+ if (fgets(resp, sizeof(resp), f) == NULL)
+ {
+ if (ferror(f))
+ {
+ log_errno((e, "fgets failed on output of %s%s command"
+ , verb, verb_suffix));
+ return FALSE;
+ }
+ else
+ {
+ passert(feof(f));
+ break;
+ }
+ }
+ else
+ {
+ char *e = resp + strlen(resp);
+
+ if (e > resp && e[-1] == '\n')
+ e[-1] = '\0'; /* trim trailing '\n' */
+ plog("%s%s output: %s", verb, verb_suffix, resp);
+ }
+ }
+
+ /* report on and react to return code */
+ {
+ int r = pclose(f);
+
+ if (r == -1)
+ {
+ log_errno((e, "pclose failed for %s%s command"
+ , verb, verb_suffix));
+ return FALSE;
+ }
+ else if (WIFEXITED(r))
+ {
+ if (WEXITSTATUS(r) != 0)
+ {
+ loglog(RC_LOG_SERIOUS, "%s%s command exited with status %d"
+ , verb, verb_suffix, WEXITSTATUS(r));
+ return FALSE;
+ }
+ }
+ else if (WIFSIGNALED(r))
+ {
+ loglog(RC_LOG_SERIOUS, "%s%s command exited with signal %d"
+ , verb, verb_suffix, WTERMSIG(r));
+ return FALSE;
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "%s%s command exited with unknown status %d"
+ , verb, verb_suffix, r);
+ return FALSE;
+ }
}
- }
- else if (WIFSIGNALED(r))
- {
- loglog(RC_LOG_SERIOUS, "%s%s command exited with signal %d"
- , verb, verb_suffix, WTERMSIG(r));
- return FALSE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "%s%s command exited with unknown status %d"
- , verb, verb_suffix, r);
- return FALSE;
- }
}
- }
#endif /* KLIPS */
- return TRUE;
+ return TRUE;
}
/* Check that we can route (and eroute). Diagnose if we cannot. */
enum routability {
- route_impossible = 0,
- route_easy = 1,
- route_nearconflict = 2,
- route_farconflict = 3
+ route_impossible = 0,
+ route_easy = 1,
+ route_nearconflict = 2,
+ route_farconflict = 3
};
-static enum routability
-could_route(struct connection *c)
+static enum routability could_route(struct connection *c)
{
- struct spd_route *esr, *rosr;
- struct connection *ero /* who, if anyone, owns our eroute? */
- , *ro = route_owner(c, &rosr, &ero, &esr); /* who owns our route? */
-
- /* it makes no sense to route a connection that is ISAKMP-only */
- if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
- {
- loglog(RC_ROUTE, "cannot route an ISAKMP-only connection");
- return route_impossible;
- }
-
- /* if this is a Road Warrior template, we cannot route.
- * Opportunistic template is OK.
- */
- if (c->kind == CK_TEMPLATE && !(c->policy & POLICY_OPPO))
- {
- loglog(RC_ROUTE, "cannot route Road Warrior template");
- return route_impossible;
- }
-
- /* if we don't know nexthop, we cannot route */
- if (isanyaddr(&c->spd.this.host_nexthop))
- {
- loglog(RC_ROUTE, "cannot route connection without knowing our nexthop");
- return route_impossible;
- }
-
- /* if routing would affect IKE messages, reject */
- if (!no_klips
- && c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT
- && c->spd.this.host_port != IKE_UDP_PORT
- && addrinsubnet(&c->spd.that.host_addr, &c->spd.that.client))
- {
- loglog(RC_LOG_SERIOUS, "cannot install route: peer is within its client");
- return route_impossible;
- }
-
- /* If there is already a route for peer's client subnet
- * and it disagrees about interface or nexthop, we cannot steal it.
- * Note: if this connection is already routed (perhaps for another
- * state object), the route will agree.
- * This is as it should be -- it will arise during rekeying.
- */
- if (ro != NULL && !routes_agree(ro, c))
- {
- loglog(RC_LOG_SERIOUS, "cannot route -- route already in use for \"%s\""
- , ro->name);
- return route_impossible; /* another connection already
- using the eroute */
- }
+ struct spd_route *esr, *rosr;
+ struct connection *ero /* who, if anyone, owns our eroute? */
+ , *ro = route_owner(c, &rosr, &ero, &esr); /* who owns our route? */
-#ifdef KLIPS
- /* if there is an eroute for another connection, there is a problem */
- if (ero != NULL && ero != c)
- {
- struct connection *ero2, *ero_top;
- struct connection *inside, *outside;
-
- /*
- * note, wavesec (PERMANENT) goes *outside* and
- * OE goes *inside* (TEMPLATE)
+ /* it makes no sense to route a connection that is ISAKMP-only */
+ if (!NEVER_NEGOTIATE(c->policy) && !HAS_IPSEC_POLICY(c->policy))
+ {
+ loglog(RC_ROUTE, "cannot route an ISAKMP-only connection");
+ return route_impossible;
+ }
+
+ /* if this is a Road Warrior template, we cannot route.
+ * Opportunistic template is OK.
*/
- inside = NULL;
- outside= NULL;
- if (ero->kind == CK_PERMANENT
- && c->kind == CK_TEMPLATE)
+ if (c->kind == CK_TEMPLATE && !(c->policy & POLICY_OPPO))
{
- outside = ero;
- inside = c;
+ loglog(RC_ROUTE, "cannot route Road Warrior template");
+ return route_impossible;
}
- else if (c->kind == CK_PERMANENT
- && ero->kind == CK_TEMPLATE)
+
+ /* if we don't know nexthop, we cannot route */
+ if (isanyaddr(&c->spd.this.host_nexthop))
{
- outside = c;
- inside = ero;
+ loglog(RC_ROUTE, "cannot route connection without knowing our nexthop");
+ return route_impossible;
}
- /* okay, check again, with correct order */
- if (outside && outside->kind == CK_PERMANENT
- && inside && inside->kind == CK_TEMPLATE)
+ /* if routing would affect IKE messages, reject */
+ if (!no_klips
+ && c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT
+ && c->spd.this.host_port != IKE_UDP_PORT
+ && addrinsubnet(&c->spd.that.host_addr, &c->spd.that.client))
{
- char inst[CONN_INST_BUF];
+ loglog(RC_LOG_SERIOUS, "cannot install route: peer is within its client");
+ return route_impossible;
+ }
- /* this is a co-terminal attempt of the "near" kind. */
- /* when chaining, we chain from inside to outside */
+ /* If there is already a route for peer's client subnet
+ * and it disagrees about interface or nexthop, we cannot steal it.
+ * Note: if this connection is already routed (perhaps for another
+ * state object), the route will agree.
+ * This is as it should be -- it will arise during rekeying.
+ */
+ if (ro != NULL && !routes_agree(ro, c))
+ {
+ loglog(RC_LOG_SERIOUS, "cannot route -- route already in use for \"%s\""
+ , ro->name);
+ return route_impossible; /* another connection already
+ using the eroute */
+ }
- /* XXX permit multiple deep connections? */
- passert(inside->policy_next == NULL);
+#ifdef KLIPS
+ /* if there is an eroute for another connection, there is a problem */
+ if (ero != NULL && ero != c)
+ {
+ struct connection *ero2, *ero_top;
+ struct connection *inside, *outside;
- inside->policy_next = outside;
+ /*
+ * note, wavesec (PERMANENT) goes *outside* and
+ * OE goes *inside* (TEMPLATE)
+ */
+ inside = NULL;
+ outside= NULL;
+ if (ero->kind == CK_PERMANENT
+ && c->kind == CK_TEMPLATE)
+ {
+ outside = ero;
+ inside = c;
+ }
+ else if (c->kind == CK_PERMANENT
+ && ero->kind == CK_TEMPLATE)
+ {
+ outside = c;
+ inside = ero;
+ }
- /* since we are going to steal the eroute from the secondary
- * policy, we need to make sure that it no longer thinks that
- * it owns the eroute.
- */
- outside->spd.eroute_owner = SOS_NOBODY;
- outside->spd.routing = RT_UNROUTED_KEYED;
+ /* okay, check again, with correct order */
+ if (outside && outside->kind == CK_PERMANENT
+ && inside && inside->kind == CK_TEMPLATE)
+ {
+ char inst[CONN_INST_BUF];
- /* set the priority of the new eroute owner to be higher
- * than that of the current eroute owner
- */
- inside->prio = outside->prio + 1;
+ /* this is a co-terminal attempt of the "near" kind. */
+ /* when chaining, we chain from inside to outside */
- fmt_conn_instance(inside, inst);
+ /* XXX permit multiple deep connections? */
+ passert(inside->policy_next == NULL);
- loglog(RC_LOG_SERIOUS
- , "conflict on eroute (%s), switching eroute to %s and linking %s"
- , inst, inside->name, outside->name);
+ inside->policy_next = outside;
- return route_nearconflict;
- }
+ /* since we are going to steal the eroute from the secondary
+ * policy, we need to make sure that it no longer thinks that
+ * it owns the eroute.
+ */
+ outside->spd.eroute_owner = SOS_NOBODY;
+ outside->spd.routing = RT_UNROUTED_KEYED;
- /* look along the chain of policies for one with the same name */
- ero_top = ero;
+ /* set the priority of the new eroute owner to be higher
+ * than that of the current eroute owner
+ */
+ inside->prio = outside->prio + 1;
- for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
- {
- if (ero2->kind == CK_TEMPLATE
- && streq(ero2->name, c->name))
- break;
- }
+ fmt_conn_instance(inside, inst);
- /* If we fell of the end of the list, then we found no TEMPLATE
- * so there must be a conflict that we can't resolve.
- * As the names are not equal, then we aren't replacing/rekeying.
- */
- if (ero2 == NULL)
- {
- char inst[CONN_INST_BUF];
+ loglog(RC_LOG_SERIOUS
+ , "conflict on eroute (%s), switching eroute to %s and linking %s"
+ , inst, inside->name, outside->name);
+
+ return route_nearconflict;
+ }
+
+ /* look along the chain of policies for one with the same name */
+ ero_top = ero;
+
+ for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
+ {
+ if (ero2->kind == CK_TEMPLATE
+ && streq(ero2->name, c->name))
+ break;
+ }
+
+ /* If we fell of the end of the list, then we found no TEMPLATE
+ * so there must be a conflict that we can't resolve.
+ * As the names are not equal, then we aren't replacing/rekeying.
+ */
+ if (ero2 == NULL)
+ {
+ char inst[CONN_INST_BUF];
- fmt_conn_instance(ero, inst);
+ fmt_conn_instance(ero, inst);
- loglog(RC_LOG_SERIOUS
- , "cannot install eroute -- it is in use for \"%s\"%s #%lu"
- , ero->name, inst, esr->eroute_owner);
- return FALSE; /* another connection already using the eroute */
+ loglog(RC_LOG_SERIOUS
+ , "cannot install eroute -- it is in use for \"%s\"%s #%lu"
+ , ero->name, inst, esr->eroute_owner);
+ return FALSE; /* another connection already using the eroute */
+ }
}
- }
#endif /* KLIPS */
- return route_easy;
+ return route_easy;
}
-bool
-trap_connection(struct connection *c)
+bool trap_connection(struct connection *c)
{
- switch (could_route(c))
- {
- case route_impossible:
- return FALSE;
-
- case route_nearconflict:
- case route_easy:
- /* RT_ROUTED_TUNNEL is treated specially: we don't override
- * because we don't want to lose track of the IPSEC_SAs etc.
- */
- if (c->spd.routing < RT_ROUTED_TUNNEL)
+ switch (could_route(c))
{
- return route_and_eroute(c, &c->spd, NULL);
+ case route_impossible:
+ return FALSE;
+
+ case route_nearconflict:
+ case route_easy:
+ /* RT_ROUTED_TUNNEL is treated specially: we don't override
+ * because we don't want to lose track of the IPSEC_SAs etc.
+ */
+ if (c->spd.routing < RT_ROUTED_TUNNEL)
+ {
+ return route_and_eroute(c, &c->spd, NULL);
+ }
+ return TRUE;
+
+ case route_farconflict:
+ return FALSE;
}
- return TRUE;
- case route_farconflict:
return FALSE;
- }
-
- return FALSE;
}
-/* delete any eroute for a connection and unroute it if route isn't shared */
-void
-unroute_connection(struct connection *c)
+/**
+ * Delete any eroute for a connection and unroute it if route isn't shared
+ */
+void unroute_connection(struct connection *c)
{
- struct spd_route *sr;
- enum routing_t cr;
-
- for (sr = &c->spd; sr; sr = sr->next)
- {
- cr = sr->routing;
+ struct spd_route *sr;
+ enum routing_t cr;
- if (erouted(cr))
+ for (sr = &c->spd; sr; sr = sr->next)
{
- /* cannot handle a live one */
- passert(sr->routing != RT_ROUTED_TUNNEL);
+ cr = sr->routing;
+
+ if (erouted(cr))
+ {
+ /* cannot handle a live one */
+ passert(sr->routing != RT_ROUTED_TUNNEL);
#ifdef KLIPS
- shunt_eroute(c, sr, RT_UNROUTED, ERO_DELETE, "delete");
+ shunt_eroute(c, sr, RT_UNROUTED, ERO_DELETE, "delete");
#endif
- }
+ }
- sr->routing = RT_UNROUTED; /* do now so route_owner won't find us */
+ sr->routing = RT_UNROUTED; /* do now so route_owner won't find us */
- /* only unroute if no other connection shares it */
- if (routed(cr) && route_owner(c, NULL, NULL, NULL) == NULL)
- (void) do_command(c, sr, "unroute");
- }
+ /* only unroute if no other connection shares it */
+ if (routed(cr) && route_owner(c, NULL, NULL, NULL) == NULL)
+ (void) do_command(c, sr, "unroute");
+ }
}
#ifdef KLIPS
-static void
-set_text_said(char *text_said, const ip_address *dst, ipsec_spi_t spi, int proto)
+static void set_text_said(char *text_said, const ip_address *dst,
+ ipsec_spi_t spi, int proto)
{
- ip_said said;
+ ip_said said;
- initsaid(dst, spi, proto, &said);
- satot(&said, 0, text_said, SATOT_BUF);
+ initsaid(dst, spi, proto, &said);
+ satot(&said, 0, text_said, SATOT_BUF);
}
/* find an entry in the bare_shunt table.
* Trick: return a pointer to the pointer to the entry;
* this allows the entry to be deleted.
*/
-static struct bare_shunt **
-bare_shunt_ptr(const ip_subnet *ours, const ip_subnet *his, int transport_proto)
+static struct bare_shunt** bare_shunt_ptr(const ip_subnet *ours,
+ const ip_subnet *his,
+ int transport_proto)
{
- struct bare_shunt *p, **pp;
-
- for (pp = &bare_shunts; (p = *pp) != NULL; pp = &p->next)
- {
- if (samesubnet(ours, &p->ours)
- && samesubnet(his, &p->his)
- && transport_proto == p->transport_proto
- && portof(&ours->addr) == portof(&p->ours.addr)
- && portof(&his->addr) == portof(&p->his.addr))
- return pp;
- }
- return NULL;
+ struct bare_shunt *p, **pp;
+
+ for (pp = &bare_shunts; (p = *pp) != NULL; pp = &p->next)
+ {
+ if (samesubnet(ours, &p->ours)
+ && samesubnet(his, &p->his)
+ && transport_proto == p->transport_proto
+ && portof(&ours->addr) == portof(&p->ours.addr)
+ && portof(&his->addr) == portof(&p->his.addr))
+ return pp;
+ }
+ return NULL;
}
/* free a bare_shunt entry, given a pointer to the pointer */
-static void
-free_bare_shunt(struct bare_shunt **pp)
+static void free_bare_shunt(struct bare_shunt **pp)
{
- if (pp == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("delete bare shunt: null pointer")
- )
- }
- else
- {
- struct bare_shunt *p = *pp;
-
- *pp = p->next;
- DBG_bare_shunt("delete", p);
- pfree(p->why);
- pfree(p);
- }
+ if (pp == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("delete bare shunt: null pointer")
+ )
+ }
+ else
+ {
+ struct bare_shunt *p = *pp;
+
+ *pp = p->next;
+ DBG_bare_shunt("delete", p);
+ free(p->why);
+ free(p);
+ }
}
void
show_shunt_status(void)
{
- struct bare_shunt *bs;
-
- for (bs = bare_shunts; bs != NULL; bs = bs->next)
- {
- /* Print interesting fields. Ignore count and last_active. */
-
- int ourport = ntohs(portof(&bs->ours.addr));
- int hisport = ntohs(portof(&bs->his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
- char prio[POLICY_PRIO_BUF];
-
- subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
- subnettot(&(bs)->his, 0, hist, sizeof(hist));
- satot(&(bs)->said, 0, sat, sizeof(sat));
- fmt_policy_prio(bs->policy_prio, prio);
-
- whack_log(RC_COMMENT, "%s:%d -> %s:%d => %s:%d %s %s"
- , ourst, ourport, hist, hisport, sat, bs->transport_proto
- , prio, bs->why);
- }
- if (bare_shunts != NULL)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
+ struct bare_shunt *bs;
+
+ for (bs = bare_shunts; bs != NULL; bs = bs->next)
+ {
+ /* Print interesting fields. Ignore count and last_active. */
+
+ int ourport = ntohs(portof(&bs->ours.addr));
+ int hisport = ntohs(portof(&bs->his.addr));
+ char ourst[SUBNETTOT_BUF];
+ char hist[SUBNETTOT_BUF];
+ char sat[SATOT_BUF];
+ char prio[POLICY_PRIO_BUF];
+
+ subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
+ subnettot(&(bs)->his, 0, hist, sizeof(hist));
+ satot(&(bs)->said, 0, sat, sizeof(sat));
+ fmt_policy_prio(bs->policy_prio, prio);
+
+ whack_log(RC_COMMENT, "%s:%d -> %s:%d => %s:%d %s %s"
+ , ourst, ourport, hist, hisport, sat, bs->transport_proto
+ , prio, bs->why);
+ }
+ if (bare_shunts != NULL)
+ whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
/* Setup an IPsec route entry.
* op is one of the ERO_* operators.
*/
-static bool
-raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int proto
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info
- , time_t use_lifetime
- , unsigned int op
- , const char *opname USED_BY_DEBUG)
+static bool raw_eroute(const ip_address *this_host,
+ const ip_subnet *this_client,
+ const ip_address *that_host,
+ const ip_subnet *that_client,
+ ipsec_spi_t spi,
+ unsigned int proto,
+ unsigned int satype,
+ unsigned int transport_proto,
+ const struct pfkey_proto_info *proto_info,
+ time_t use_lifetime,
+ unsigned int op,
+ const char *opname USED_BY_DEBUG)
{
- char text_said[SATOT_BUF];
+ char text_said[SATOT_BUF];
- set_text_said(text_said, that_host, spi, proto);
+ set_text_said(text_said, that_host, spi, proto);
- DBG(DBG_CONTROL | DBG_KLIPS,
- {
- int sport = ntohs(portof(&this_client->addr));
- int dport = ntohs(portof(&that_client->addr));
- char mybuf[SUBNETTOT_BUF];
- char peerbuf[SUBNETTOT_BUF];
-
- subnettot(this_client, 0, mybuf, sizeof(mybuf));
- subnettot(that_client, 0, peerbuf, sizeof(peerbuf));
- DBG_log("%s eroute %s:%d -> %s:%d => %s:%d"
- , opname, mybuf, sport, peerbuf, dport
- , text_said, transport_proto);
- });
-
- return kernel_ops->raw_eroute(this_host, this_client
- , that_host, that_client, spi, satype, transport_proto, proto_info
- , use_lifetime, op, text_said);
+ DBG(DBG_CONTROL | DBG_KLIPS,
+ {
+ int sport = ntohs(portof(&this_client->addr));
+ int dport = ntohs(portof(&that_client->addr));
+ char mybuf[SUBNETTOT_BUF];
+ char peerbuf[SUBNETTOT_BUF];
+
+ subnettot(this_client, 0, mybuf, sizeof(mybuf));
+ subnettot(that_client, 0, peerbuf, sizeof(peerbuf));
+ DBG_log("%s eroute %s:%d -> %s:%d => %s:%d"
+ , opname, mybuf, sport, peerbuf, dport
+ , text_said, transport_proto);
+ });
+
+ return kernel_ops->raw_eroute(this_host, this_client
+ , that_host, that_client, spi, satype, transport_proto, proto_info
+ , use_lifetime, op, text_said);
}
/* test to see if %hold remains */
-bool
-has_bare_hold(const ip_address *src, const ip_address *dst, int transport_proto)
+bool has_bare_hold(const ip_address *src, const ip_address *dst,
+ int transport_proto)
{
- ip_subnet this_client, that_client;
- struct bare_shunt **bspp;
-
- passert(addrtypeof(src) == addrtypeof(dst));
- happy(addrtosubnet(src, &this_client));
- happy(addrtosubnet(dst, &that_client));
- bspp = bare_shunt_ptr(&this_client, &that_client, transport_proto);
- return bspp != NULL
- && (*bspp)->said.proto == SA_INT && (*bspp)->said.spi == htonl(SPI_HOLD);
+ ip_subnet this_client, that_client;
+ struct bare_shunt **bspp;
+
+ passert(addrtypeof(src) == addrtypeof(dst));
+ happy(addrtosubnet(src, &this_client));
+ happy(addrtosubnet(dst, &that_client));
+ bspp = bare_shunt_ptr(&this_client, &that_client, transport_proto);
+ return bspp != NULL
+ && (*bspp)->said.proto == SA_INT && (*bspp)->said.spi == htonl(SPI_HOLD);
}
/* Replace (or delete) a shunt that is in the bare_shunts table.
* Issues the PF_KEY commands and updates the bare_shunts table.
*/
-bool
-replace_bare_shunt(const ip_address *src, const ip_address *dst
- , policy_prio_t policy_prio
- , ipsec_spi_t shunt_spi /* in host order! */
- , bool repl /* if TRUE, replace; if FALSE, delete */
- , unsigned int transport_proto
- , const char *why)
+bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
+ policy_prio_t policy_prio, ipsec_spi_t shunt_spi,
+ bool repl, unsigned int transport_proto, const char *why)
{
- ip_subnet this_client, that_client;
- ip_subnet this_broad_client, that_broad_client;
- const ip_address *null_host = aftoinfo(addrtypeof(src))->any;
-
- passert(addrtypeof(src) == addrtypeof(dst));
- happy(addrtosubnet(src, &this_client));
- happy(addrtosubnet(dst, &that_client));
- this_broad_client = this_client;
- that_broad_client = that_client;
- setportof(0, &this_broad_client.addr);
- setportof(0, &that_broad_client.addr);
-
- if (repl)
- {
- struct bare_shunt **bs_pp = bare_shunt_ptr(&this_broad_client
- , &that_broad_client, 0);
-
- /* is there already a broad host-to-host bare shunt? */
- if (bs_pp == NULL)
- {
- if (raw_eroute(null_host, &this_broad_client, null_host, &that_broad_client
- , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
- , 0, null_proto_info
- , SHUNT_PATIENCE, ERO_ADD, why))
- {
- struct bare_shunt *bs = alloc_thing(struct bare_shunt, "bare shunt");
-
- bs->ours = this_broad_client;
- bs->his = that_broad_client;
- bs->transport_proto = 0;
- bs->said.proto = SA_INT;
- bs->why = clone_str(why, "bare shunt story");
- bs->policy_prio = policy_prio;
- bs->said.spi = htonl(shunt_spi);
- bs->said.dst = *null_host;
- bs->count = 0;
- bs->last_activity = now();
- bs->next = bare_shunts;
- bare_shunts = bs;
- DBG_bare_shunt("add", bs);
- }
+ ip_subnet this_client, that_client;
+ ip_subnet this_broad_client, that_broad_client;
+ const ip_address *null_host = aftoinfo(addrtypeof(src))->any;
+
+ passert(addrtypeof(src) == addrtypeof(dst));
+ happy(addrtosubnet(src, &this_client));
+ happy(addrtosubnet(dst, &that_client));
+ this_broad_client = this_client;
+ that_broad_client = that_client;
+ setportof(0, &this_broad_client.addr);
+ setportof(0, &that_broad_client.addr);
+
+ if (repl)
+ {
+ struct bare_shunt **bs_pp = bare_shunt_ptr(&this_broad_client
+ , &that_broad_client, 0);
+
+ /* is there already a broad host-to-host bare shunt? */
+ if (bs_pp == NULL)
+ {
+ if (raw_eroute(null_host, &this_broad_client, null_host, &that_broad_client
+ , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
+ , 0, null_proto_info
+ , SHUNT_PATIENCE, ERO_ADD, why))
+ {
+ struct bare_shunt *bs = malloc_thing(struct bare_shunt);
+
+ bs->ours = this_broad_client;
+ bs->his = that_broad_client;
+ bs->transport_proto = 0;
+ bs->said.proto = SA_INT;
+ bs->why = clone_str(why);
+ bs->policy_prio = policy_prio;
+ bs->said.spi = htonl(shunt_spi);
+ bs->said.dst = *null_host;
+ bs->count = 0;
+ bs->last_activity = now();
+ bs->next = bare_shunts;
+ bare_shunts = bs;
+ DBG_bare_shunt("add", bs);
+ }
+ }
+ shunt_spi = SPI_HOLD;
}
- shunt_spi = SPI_HOLD;
- }
- if (raw_eroute(null_host, &this_client, null_host, &that_client
- , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
- , transport_proto, null_proto_info
- , SHUNT_PATIENCE, ERO_DELETE, why))
- {
- struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
- , transport_proto);
+ if (raw_eroute(null_host, &this_client, null_host, &that_client
+ , htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
+ , transport_proto, null_proto_info
+ , SHUNT_PATIENCE, ERO_DELETE, why))
+ {
+ struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
+ , transport_proto);
- /* delete bare eroute */
- free_bare_shunt(bs_pp);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ /* delete bare eroute */
+ free_bare_shunt(bs_pp);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
-static bool
-eroute_connection(struct spd_route *sr
-, ipsec_spi_t spi, unsigned int proto, unsigned int satype
-, const struct pfkey_proto_info *proto_info
-, unsigned int op, const char *opname)
+static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
+ unsigned int proto, unsigned int satype,
+ const struct pfkey_proto_info *proto_info,
+ unsigned int op, const char *opname)
{
- const ip_address *peer = &sr->that.host_addr;
- char buf2[256];
+ const ip_address *peer = &sr->that.host_addr;
+ char buf2[256];
- snprintf(buf2, sizeof(buf2)
- , "eroute_connection %s", opname);
+ snprintf(buf2, sizeof(buf2)
+ , "eroute_connection %s", opname);
- if (proto == SA_INT)
- peer = aftoinfo(addrtypeof(peer))->any;
+ if (proto == SA_INT)
+ peer = aftoinfo(addrtypeof(peer))->any;
- return raw_eroute(&sr->this.host_addr, &sr->this.client
- , peer
- , &sr->that.client
- , spi, proto, satype
- , sr->this.protocol, proto_info, 0, op, buf2);
+ return raw_eroute(&sr->this.host_addr, &sr->this.client
+ , peer
+ , &sr->that.client
+ , spi, proto, satype
+ , sr->this.protocol, proto_info, 0, op, buf2);
}
/* assign a bare hold to a connection */
-bool
-assign_hold(struct connection *c USED_BY_DEBUG
- , struct spd_route *sr
- , int transport_proto
- , const ip_address *src, const ip_address *dst)
+bool assign_hold(struct connection *c USED_BY_DEBUG, struct spd_route *sr,
+ int transport_proto,
+ const ip_address *src,
+ const ip_address *dst)
{
- /* either the automatically installed %hold eroute is broad enough
- * or we try to add a broader one and delete the automatic one.
- * Beware: this %hold might be already handled, but still squeak
- * through because of a race.
- */
- enum routing_t ro = sr->routing /* routing, old */
- , rn = ro; /* routing, new */
-
- passert(LHAS(LELEM(CK_PERMANENT) | LELEM(CK_INSTANCE), c->kind));
- /* figure out what routing should become */
- switch (ro)
- {
- case RT_UNROUTED:
- rn = RT_UNROUTED_HOLD;
- break;
- case RT_ROUTED_PROSPECTIVE:
- rn = RT_ROUTED_HOLD;
- break;
- default:
- /* no change: this %hold is old news and should just be deleted */
- break;
- }
-
- /* we need a broad %hold, not the narrow one.
- * First we ensure that there is a broad %hold.
- * There may already be one (race condition): no need to create one.
- * There may already be a %trap: replace it.
- * There may not be any broad eroute: add %hold.
- * Once the broad %hold is in place, delete the narrow one.
- */
- if (rn != ro)
- {
- if (erouted(ro)
- ? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info
- , ERO_REPLACE, "replace %trap with broad %hold")
- : !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info
- , ERO_ADD, "add broad %hold"))
- {
- return FALSE;
- }
- }
- if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE
- , transport_proto, "delete narrow %hold"))
- {
- return FALSE;
- }
- sr->routing = rn;
- return TRUE;
+ /* either the automatically installed %hold eroute is broad enough
+ * or we try to add a broader one and delete the automatic one.
+ * Beware: this %hold might be already handled, but still squeak
+ * through because of a race.
+ */
+ enum routing_t ro = sr->routing /* routing, old */
+ , rn = ro; /* routing, new */
+
+ passert(LHAS(LELEM(CK_PERMANENT) | LELEM(CK_INSTANCE), c->kind));
+ /* figure out what routing should become */
+ switch (ro)
+ {
+ case RT_UNROUTED:
+ rn = RT_UNROUTED_HOLD;
+ break;
+ case RT_ROUTED_PROSPECTIVE:
+ rn = RT_ROUTED_HOLD;
+ break;
+ default:
+ /* no change: this %hold is old news and should just be deleted */
+ break;
+ }
+
+ /* we need a broad %hold, not the narrow one.
+ * First we ensure that there is a broad %hold.
+ * There may already be one (race condition): no need to create one.
+ * There may already be a %trap: replace it.
+ * There may not be any broad eroute: add %hold.
+ * Once the broad %hold is in place, delete the narrow one.
+ */
+ if (rn != ro)
+ {
+ if (erouted(ro)
+ ? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
+ , null_proto_info
+ , ERO_REPLACE, "replace %trap with broad %hold")
+ : !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
+ , null_proto_info
+ , ERO_ADD, "add broad %hold"))
+ {
+ return FALSE;
+ }
+ }
+ if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE
+ , transport_proto, "delete narrow %hold"))
+ {
+ return FALSE;
+ }
+ sr->routing = rn;
+ return TRUE;
}
/* install or remove eroute for SA Group */
-static bool
-sag_eroute(struct state *st, struct spd_route *sr
- , unsigned op, const char *opname)
+static bool sag_eroute(struct state *st, struct spd_route *sr,
+ unsigned op, const char *opname)
{
- u_int inner_proto = 0;
- u_int inner_satype = 0;
- ipsec_spi_t inner_spi = 0;
- struct pfkey_proto_info proto_info[4];
- int i;
- bool tunnel;
-
- /* figure out the SPI and protocol (in two forms)
- * for the innermost transformation.
- */
-
- i = sizeof(proto_info) / sizeof(proto_info[0]) - 1;
- proto_info[i].proto = 0;
- tunnel = FALSE;
-
- if (st->st_ah.present)
- {
- inner_spi = st->st_ah.attrs.spi;
- inner_proto = SA_AH;
- inner_satype = SADB_SATYPE_AH;
-
- i--;
- proto_info[i].proto = IPPROTO_AH;
- proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid;
- }
-
- if (st->st_esp.present)
- {
- inner_spi = st->st_esp.attrs.spi;
- inner_proto = SA_ESP;
- inner_satype = SADB_SATYPE_ESP;
-
- i--;
- proto_info[i].proto = IPPROTO_ESP;
- proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid + 1;
- }
-
- if (st->st_ipcomp.present)
- {
- inner_spi = st->st_ipcomp.attrs.spi;
- inner_proto = SA_COMP;
- inner_satype = SADB_X_SATYPE_COMP;
-
- i--;
- proto_info[i].proto = IPPROTO_COMP;
- proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
- tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
- proto_info[i].reqid = sr->reqid + 2;
- }
-
- if (i == sizeof(proto_info) / sizeof(proto_info[0]) - 1)
- {
- impossible(); /* no transform at all! */
- }
-
- if (tunnel)
- {
- int j;
-
- inner_spi = st->st_tunnel_out_spi;
- inner_proto = SA_IPIP;
- inner_satype = SADB_X_SATYPE_IPIP;
-
- proto_info[i].encapsulation = ENCAPSULATION_MODE_TUNNEL;
- for (j = i + 1; proto_info[j].proto; j++)
- {
- proto_info[j].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
- }
-
- return eroute_connection(sr
- , inner_spi, inner_proto, inner_satype, proto_info + i
- , op, opname);
+ u_int inner_proto = 0;
+ u_int inner_satype = 0;
+ ipsec_spi_t inner_spi = 0;
+ struct pfkey_proto_info proto_info[4];
+ int i;
+ bool tunnel;
+
+ /* figure out the SPI and protocol (in two forms)
+ * for the innermost transformation.
+ */
+
+ i = sizeof(proto_info) / sizeof(proto_info[0]) - 1;
+ proto_info[i].proto = 0;
+ tunnel = FALSE;
+
+ if (st->st_ah.present)
+ {
+ inner_spi = st->st_ah.attrs.spi;
+ inner_proto = SA_AH;
+ inner_satype = SADB_SATYPE_AH;
+
+ i--;
+ proto_info[i].proto = IPPROTO_AH;
+ proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
+ tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
+ proto_info[i].reqid = sr->reqid;
+ }
+
+ if (st->st_esp.present)
+ {
+ inner_spi = st->st_esp.attrs.spi;
+ inner_proto = SA_ESP;
+ inner_satype = SADB_SATYPE_ESP;
+
+ i--;
+ proto_info[i].proto = IPPROTO_ESP;
+ proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
+ tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
+ proto_info[i].reqid = sr->reqid + 1;
+ }
+
+ if (st->st_ipcomp.present)
+ {
+ inner_spi = st->st_ipcomp.attrs.spi;
+ inner_proto = SA_COMP;
+ inner_satype = SADB_X_SATYPE_COMP;
+
+ i--;
+ proto_info[i].proto = IPPROTO_COMP;
+ proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
+ tunnel |= proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
+ proto_info[i].reqid = sr->reqid + 2;
+ }
+
+ if (i == sizeof(proto_info) / sizeof(proto_info[0]) - 1)
+ {
+ impossible(); /* no transform at all! */
+ }
+
+ if (tunnel)
+ {
+ int j;
+
+ inner_spi = st->st_tunnel_out_spi;
+ inner_proto = SA_IPIP;
+ inner_satype = SADB_X_SATYPE_IPIP;
+
+ proto_info[i].encapsulation = ENCAPSULATION_MODE_TUNNEL;
+ for (j = i + 1; proto_info[j].proto; j++)
+ {
+ proto_info[j].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ }
+ }
+
+ return eroute_connection(sr
+ , inner_spi, inner_proto, inner_satype, proto_info + i
+ , op, opname);
}
/* compute a (host-order!) SPI to implement the policy in connection c */
ipsec_spi_t
shunt_policy_spi(struct connection *c, bool prospective)
{
- /* note: these are in host order :-( */
- static const ipsec_spi_t shunt_spi[] =
- {
- SPI_TRAP, /* --initiateontraffic */
- SPI_PASS, /* --pass */
- SPI_DROP, /* --drop */
- SPI_REJECT, /* --reject */
- };
-
- static const ipsec_spi_t fail_spi[] =
- {
- 0, /* --none*/
- SPI_PASS, /* --failpass */
- SPI_DROP, /* --faildrop */
- SPI_REJECT, /* --failreject */
- };
-
- return prospective
- ? shunt_spi[(c->policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT]
- : fail_spi[(c->policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT];
+ /* note: these are in host order :-( */
+ static const ipsec_spi_t shunt_spi[] =
+ {
+ SPI_TRAP, /* --initiateontraffic */
+ SPI_PASS, /* --pass */
+ SPI_DROP, /* --drop */
+ SPI_REJECT, /* --reject */
+ };
+
+ static const ipsec_spi_t fail_spi[] =
+ {
+ 0, /* --none*/
+ SPI_PASS, /* --failpass */
+ SPI_DROP, /* --faildrop */
+ SPI_REJECT, /* --failreject */
+ };
+
+ return prospective
+ ? shunt_spi[(c->policy & POLICY_SHUNT_MASK) >> POLICY_SHUNT_SHIFT]
+ : fail_spi[(c->policy & POLICY_FAIL_MASK) >> POLICY_FAIL_SHIFT];
}
/* Add/replace/delete a shunt eroute.
@@ -1261,89 +1255,87 @@ shunt_policy_spi(struct connection *c, bool prospective)
* If negotiation has failed, the choice between %trap/%pass/%drop/%reject
* is specified in the policy of connection c.
*/
-static bool
-shunt_eroute(struct connection *c
-, struct spd_route *sr
-, enum routing_t rt_kind
-, unsigned int op, const char *opname)
+static bool shunt_eroute(struct connection *c, struct spd_route *sr,
+ enum routing_t rt_kind,
+ unsigned int op, const char *opname)
{
- /* We are constructing a special SAID for the eroute.
- * The destination doesn't seem to matter, but the family does.
- * The protocol is SA_INT -- mark this as shunt.
- * The satype has no meaning, but is required for PF_KEY header!
- * The SPI signifies the kind of shunt.
- */
- ipsec_spi_t spi = shunt_policy_spi(c, rt_kind == RT_ROUTED_PROSPECTIVE);
- bool ok;
-
- if (spi == 0)
- {
- /* we're supposed to end up with no eroute: rejig op and opname */
- switch (op)
- {
- case ERO_REPLACE:
- /* replace with nothing == delete */
- op = ERO_DELETE;
- opname = "delete";
- break;
- case ERO_ADD:
- /* add nothing == do nothing */
- return TRUE;
- case ERO_DELETE:
- /* delete remains delete */
- break;
- default:
- bad_case(op);
- }
- }
- if (sr->routing == RT_ROUTED_ECLIPSED && c->kind == CK_TEMPLATE)
- {
- /* We think that we have an eroute, but we don't.
- * Adjust the request and account for eclipses.
+ /* We are constructing a special SAID for the eroute.
+ * The destination doesn't seem to matter, but the family does.
+ * The protocol is SA_INT -- mark this as shunt.
+ * The satype has no meaning, but is required for PF_KEY header!
+ * The SPI signifies the kind of shunt.
*/
- passert(eclipsable(sr));
- switch (op)
- {
- case ERO_REPLACE:
- /* really an add */
- op = ERO_ADD;
- opname = "replace eclipsed";
- eclipse_count--;
- break;
- case ERO_DELETE:
- /* delete unnecessary: we don't actually have an eroute */
- eclipse_count--;
- return TRUE;
- case ERO_ADD:
- default:
- bad_case(op);
+ ipsec_spi_t spi = shunt_policy_spi(c, rt_kind == RT_ROUTED_PROSPECTIVE);
+ bool ok;
+
+ if (spi == 0)
+ {
+ /* we're supposed to end up with no eroute: rejig op and opname */
+ switch (op)
+ {
+ case ERO_REPLACE:
+ /* replace with nothing == delete */
+ op = ERO_DELETE;
+ opname = "delete";
+ break;
+ case ERO_ADD:
+ /* add nothing == do nothing */
+ return TRUE;
+ case ERO_DELETE:
+ /* delete remains delete */
+ break;
+ default:
+ bad_case(op);
+ }
}
- }
- else if (eclipse_count > 0 && op == ERO_DELETE && eclipsable(sr))
- {
- /* maybe we are uneclipsing something */
- struct spd_route *esr;
- struct connection *ue = eclipsed(c, &esr);
-
- if (ue != NULL)
- {
- esr->routing = RT_ROUTED_PROSPECTIVE;
- return shunt_eroute(ue, esr
- , RT_ROUTED_PROSPECTIVE, ERO_REPLACE, "restoring eclipsed");
- }
- }
-
- ok = TRUE;
- if (kernel_ops->inbound_eroute)
- {
- ok = raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , htonl(spi), SA_INT, SADB_X_SATYPE_INT
- , 0, null_proto_info, 0
- , op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), opname);
- }
- return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT
- , null_proto_info, op, opname) && ok;
+ if (sr->routing == RT_ROUTED_ECLIPSED && c->kind == CK_TEMPLATE)
+ {
+ /* We think that we have an eroute, but we don't.
+ * Adjust the request and account for eclipses.
+ */
+ passert(eclipsable(sr));
+ switch (op)
+ {
+ case ERO_REPLACE:
+ /* really an add */
+ op = ERO_ADD;
+ opname = "replace eclipsed";
+ eclipse_count--;
+ break;
+ case ERO_DELETE:
+ /* delete unnecessary: we don't actually have an eroute */
+ eclipse_count--;
+ return TRUE;
+ case ERO_ADD:
+ default:
+ bad_case(op);
+ }
+ }
+ else if (eclipse_count > 0 && op == ERO_DELETE && eclipsable(sr))
+ {
+ /* maybe we are uneclipsing something */
+ struct spd_route *esr;
+ struct connection *ue = eclipsed(c, &esr);
+
+ if (ue != NULL)
+ {
+ esr->routing = RT_ROUTED_PROSPECTIVE;
+ return shunt_eroute(ue, esr
+ , RT_ROUTED_PROSPECTIVE, ERO_REPLACE, "restoring eclipsed");
+ }
+ }
+
+ ok = TRUE;
+ if (kernel_ops->inbound_eroute)
+ {
+ ok = raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
+ , &c->spd.this.host_addr, &c->spd.this.client
+ , htonl(spi), SA_INT, SADB_X_SATYPE_INT
+ , 0, null_proto_info, 0
+ , op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), opname);
+ }
+ return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT
+ , null_proto_info, op, opname) && ok;
}
@@ -1357,28 +1349,27 @@ shunt_eroute(struct connection *c
* The task here is to remove the ":p" part so that the rest can be read
* by another routine.
*/
-static const char *
-read_proto(const char * s, size_t * len, int * transport_proto)
+static const char *read_proto(const char * s, size_t * len, int * transport_proto)
{
- const char * p;
- const char * ugh;
- unsigned long proto;
- size_t l;
-
- l = *len;
- p = memchr(s, ':', l);
- if (p == 0) {
- *transport_proto = 0;
- return 0;
- }
- ugh = ttoul(p+1, l-((p-s)+1), 10, &proto);
- if (ugh != 0)
- return ugh;
- if (proto > 65535)
- return "protocol number is too large, legal range is 0-65535";
- *len = p-s;
- *transport_proto = proto;
- return 0;
+ const char * p;
+ const char * ugh;
+ unsigned long proto;
+ size_t l;
+
+ l = *len;
+ p = memchr(s, ':', l);
+ if (p == 0) {
+ *transport_proto = 0;
+ return 0;
+ }
+ ugh = ttoul(p+1, l-((p-s)+1), 10, &proto);
+ if (ugh != 0)
+ return ugh;
+ if (proto > 65535)
+ return "protocol number is too large, legal range is 0-65535";
+ *len = p-s;
+ *transport_proto = proto;
+ return 0;
}
@@ -1407,937 +1398,931 @@ read_proto(const char * s, size_t * len, int * transport_proto)
* searching for each is sequential. If this becomes a problem, faster
* searches could be implemented (hash or radix tree, for example).
*/
-void
-scan_proc_shunts(void)
+void scan_proc_shunts(void)
{
- static const char procname[] = "/proc/net/ipsec_eroute";
- FILE *f;
- time_t nw = now();
- int lino;
- struct eroute_info *expired = NULL;
-
- event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
-
- DBG(DBG_CONTROL,
- DBG_log("scanning for shunt eroutes")
- )
-
- /* free any leftover entries: they will be refreshed if still current */
- while (orphaned_holds != NULL)
- {
- struct eroute_info *p = orphaned_holds;
-
- orphaned_holds = p->next;
- pfree(orphaned_holds);
- }
-
- /* decode the /proc file. Don't do anything strenuous to it
- * (certainly no PF_KEY stuff) to minimize the chance that it
- * might change underfoot.
- */
-
- f = fopen(procname, "r");
- if (f == NULL)
- return;
-
- /* for each line... */
- for (lino = 1; ; lino++)
- {
- unsigned char buf[1024]; /* should be big enough */
- chunk_t field[10]; /* 10 is loose upper bound */
- chunk_t *ff = NULL; /* fixed fields (excluding optional count) */
- int fi;
- struct eroute_info eri;
- char *cp;
- err_t context = ""
- , ugh = NULL;
-
- cp = fgets(buf, sizeof(buf), f);
- if (cp == NULL)
- break;
-
- /* break out each field
- * Note: if there are too many fields, just stop;
- * it will be diagnosed a little later.
- */
- for (fi = 0; fi < (int)elemsof(field); fi++)
+ static const char procname[] = "/proc/net/ipsec_eroute";
+ FILE *f;
+ time_t nw = now();
+ int lino;
+ struct eroute_info *expired = NULL;
+
+ event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
+
+ DBG(DBG_CONTROL,
+ DBG_log("scanning for shunt eroutes")
+ )
+
+ /* free any leftover entries: they will be refreshed if still current */
+ while (orphaned_holds != NULL)
{
- static const char sep[] = " \t\n"; /* field-separating whitespace */
- size_t w;
+ struct eroute_info *p = orphaned_holds;
- cp += strspn(cp, sep); /* find start of field */
- w = strcspn(cp, sep); /* find width of field */
- setchunk(field[fi], cp, w);
- cp += w;
- if (w == 0)
- break;
+ orphaned_holds = p->next;
+ free(orphaned_holds);
}
- /* This odd do-hickey is to share error reporting code.
- * A break will get to that common code. The setting
- * of "ugh" and "context" parameterize it.
+ /* decode the /proc file. Don't do anything strenuous to it
+ * (certainly no PF_KEY stuff) to minimize the chance that it
+ * might change underfoot.
*/
- do {
- /* Old entries have no packet count; new ones do.
- * check if things are as they should be.
- */
- if (fi == 5)
- ff = &field[0]; /* old form, with no count */
- else if (fi == 6)
- ff = &field[1]; /* new form, with count */
- else
- {
- ugh = "has wrong number of fields";
- break;
- }
-
- if (ff[1].len != 2
- || strncmp(ff[1].ptr, "->", 2) != 0
- || ff[3].len != 2
- || strncmp(ff[3].ptr, "=>", 2) != 0)
- {
- ugh = "is missing -> or =>";
- break;
- }
- /* actually digest fields of interest */
+ f = fopen(procname, "r");
+ if (f == NULL)
+ return;
- /* packet count */
+ /* for each line... */
+ for (lino = 1; ; lino++)
+ {
+ unsigned char buf[1024]; /* should be big enough */
+ chunk_t field[10]; /* 10 is loose upper bound */
+ chunk_t *ff = NULL; /* fixed fields (excluding optional count) */
+ int fi;
+ struct eroute_info eri;
+ char *cp;
+ err_t context = ""
+ , ugh = NULL;
+
+ cp = fgets(buf, sizeof(buf), f);
+ if (cp == NULL)
+ break;
- eri.count = 0;
- if (ff != field)
- {
- context = "count field is malformed: ";
- ugh = ttoul(field[0].ptr, field[0].len, 10, &eri.count);
- if (ugh != NULL)
- break;
- }
+ /* break out each field
+ * Note: if there are too many fields, just stop;
+ * it will be diagnosed a little later.
+ */
+ for (fi = 0; fi < (int)countof(field); fi++)
+ {
+ static const char sep[] = " \t\n"; /* field-separating whitespace */
+ size_t w;
+
+ cp += strspn(cp, sep); /* find start of field */
+ w = strcspn(cp, sep); /* find width of field */
+ field[fi] = chunk_create(cp, w);
+ cp += w;
+ if (w == 0)
+ break;
+ }
- /* our client */
+ /* This odd do-hickey is to share error reporting code.
+ * A break will get to that common code. The setting
+ * of "ugh" and "context" parameterize it.
+ */
+ do {
+ /* Old entries have no packet count; new ones do.
+ * check if things are as they should be.
+ */
+ if (fi == 5)
+ ff = &field[0]; /* old form, with no count */
+ else if (fi == 6)
+ ff = &field[1]; /* new form, with count */
+ else
+ {
+ ugh = "has wrong number of fields";
+ break;
+ }
- context = "source subnet field malformed: ";
- ugh = ttosubnet(ff[0].ptr, ff[0].len, AF_INET, &eri.ours);
- if (ugh != NULL)
- break;
+ if (ff[1].len != 2
+ || strncmp(ff[1].ptr, "->", 2) != 0
+ || ff[3].len != 2
+ || strncmp(ff[3].ptr, "=>", 2) != 0)
+ {
+ ugh = "is missing -> or =>";
+ break;
+ }
- /* his client */
+ /* actually digest fields of interest */
- context = "destination subnet field malformed: ";
- ugh = ttosubnet(ff[2].ptr, ff[2].len, AF_INET, &eri.his);
- if (ugh != NULL)
- break;
+ /* packet count */
- /* SAID */
+ eri.count = 0;
+ if (ff != field)
+ {
+ context = "count field is malformed: ";
+ ugh = ttoul(field[0].ptr, field[0].len, 10, &eri.count);
+ if (ugh != NULL)
+ break;
+ }
- context = "SA ID field malformed: ";
- ugh = read_proto(ff[4].ptr, &ff[4].len, &eri.transport_proto);
- if (ugh != NULL)
- break;
- ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said);
- } while (FALSE);
-
- if (ugh != NULL)
- {
- plog("INTERNAL ERROR: %s line %d %s%s"
- , procname, lino, context, ugh);
- continue; /* ignore rest of line */
- }
-
- /* Now we have decoded eroute, let's consider it.
- * For shunt eroutes:
- *
- * %hold: if not known, add to orphaned_holds list for initiation
- * because ACQUIRE might have been lost.
- *
- * %pass, %drop, %reject: determine if idle; if so, blast it away.
- * Can occur bare (if DNS provided insufficient information)
- * or with a connection (failure context).
- * Could even be installed by ipsec manual.
- *
- * %trap: always welcome.
- *
- * For other eroutes: find state and record count change
- */
- if (eri.said.proto == SA_INT)
- {
- /* shunt eroute */
- switch (ntohl(eri.said.spi))
- {
- case SPI_HOLD:
- if (bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto) == NULL
- && shunt_owner(&eri.ours, &eri.his) == NULL)
+ /* our client */
+
+ context = "source subnet field malformed: ";
+ ugh = ttosubnet(ff[0].ptr, ff[0].len, AF_INET, &eri.ours);
+ if (ugh != NULL)
+ break;
+
+ /* his client */
+
+ context = "destination subnet field malformed: ";
+ ugh = ttosubnet(ff[2].ptr, ff[2].len, AF_INET, &eri.his);
+ if (ugh != NULL)
+ break;
+
+ /* SAID */
+
+ context = "SA ID field malformed: ";
+ ugh = read_proto(ff[4].ptr, &ff[4].len, &eri.transport_proto);
+ if (ugh != NULL)
+ break;
+ ugh = ttosa(ff[4].ptr, ff[4].len, &eri.said);
+ } while (FALSE);
+
+ if (ugh != NULL)
{
- int ourport = ntohs(portof(&eri.ours.addr));
- int hisport = ntohs(portof(&eri.his.addr));
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
- char sat[SATOT_BUF];
-
- subnettot(&eri.ours, 0, ourst, sizeof(ourst));
- subnettot(&eri.his, 0, hist, sizeof(hist));
- satot(&eri.said, 0, sat, sizeof(sat));
-
- DBG(DBG_CONTROL,
- DBG_log("add orphaned shunt %s:%d -> %s:%d => %s:%d"
- , ourst, ourport, hist, hisport, sat, eri.transport_proto)
- )
- eri.next = orphaned_holds;
- orphaned_holds = clone_thing(eri, "orphaned %hold");
+ plog("INTERNAL ERROR: %s line %d %s%s"
+ , procname, lino, context, ugh);
+ continue; /* ignore rest of line */
}
- break;
- case SPI_PASS:
- case SPI_DROP:
- case SPI_REJECT:
- /* nothing sensible to do if we don't have counts */
- if (ff != field)
+ /* Now we have decoded eroute, let's consider it.
+ * For shunt eroutes:
+ *
+ * %hold: if not known, add to orphaned_holds list for initiation
+ * because ACQUIRE might have been lost.
+ *
+ * %pass, %drop, %reject: determine if idle; if so, blast it away.
+ * Can occur bare (if DNS provided insufficient information)
+ * or with a connection (failure context).
+ * Could even be installed by ipsec manual.
+ *
+ * %trap: always welcome.
+ *
+ * For other eroutes: find state and record count change
+ */
+ if (eri.said.proto == SA_INT)
{
- struct bare_shunt **bs_pp
- = bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto);
-
- if (bs_pp != NULL)
- {
- struct bare_shunt *bs = *bs_pp;
-
- if (eri.count != bs->count)
+ /* shunt eroute */
+ switch (ntohl(eri.said.spi))
{
- bs->count = eri.count;
- bs->last_activity = nw;
+ case SPI_HOLD:
+ if (bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto) == NULL
+ && shunt_owner(&eri.ours, &eri.his) == NULL)
+ {
+ int ourport = ntohs(portof(&eri.ours.addr));
+ int hisport = ntohs(portof(&eri.his.addr));
+ char ourst[SUBNETTOT_BUF];
+ char hist[SUBNETTOT_BUF];
+ char sat[SATOT_BUF];
+
+ subnettot(&eri.ours, 0, ourst, sizeof(ourst));
+ subnettot(&eri.his, 0, hist, sizeof(hist));
+ satot(&eri.said, 0, sat, sizeof(sat));
+
+ DBG(DBG_CONTROL,
+ DBG_log("add orphaned shunt %s:%d -> %s:%d => %s:%d"
+ , ourst, ourport, hist, hisport, sat, eri.transport_proto)
+ )
+ eri.next = orphaned_holds;
+ orphaned_holds = clone_thing(eri);
+ }
+ break;
+
+ case SPI_PASS:
+ case SPI_DROP:
+ case SPI_REJECT:
+ /* nothing sensible to do if we don't have counts */
+ if (ff != field)
+ {
+ struct bare_shunt **bs_pp
+ = bare_shunt_ptr(&eri.ours, &eri.his, eri.transport_proto);
+
+ if (bs_pp != NULL)
+ {
+ struct bare_shunt *bs = *bs_pp;
+
+ if (eri.count != bs->count)
+ {
+ bs->count = eri.count;
+ bs->last_activity = nw;
+ }
+ else if (nw - bs->last_activity > SHUNT_PATIENCE)
+ {
+ eri.next = expired;
+ expired = clone_thing(eri);
+ }
+ }
+ }
+ break;
+
+ case SPI_TRAP:
+ break;
+
+ default:
+ bad_case(ntohl(eri.said.spi));
}
- else if (nw - bs->last_activity > SHUNT_PATIENCE)
- {
- eri.next = expired;
- expired = clone_thing(eri, "expired %pass");
- }
- }
}
- break;
-
- case SPI_TRAP:
- break;
+ else
+ {
+ /* regular (non-shunt) eroute */
+ state_eroute_usage(&eri.ours, &eri.his, eri.count, nw);
+ }
+ } /* for each line */
+ fclose(f);
- default:
- bad_case(ntohl(eri.said.spi));
- }
- }
- else
+ /* Now that we've finished processing the /proc file,
+ * it is safe to delete the expired %pass shunts.
+ */
+ while (expired != NULL)
{
- /* regular (non-shunt) eroute */
- state_eroute_usage(&eri.ours, &eri.his, eri.count, nw);
- }
- } /* for each line */
- fclose(f);
-
- /* Now that we've finished processing the /proc file,
- * it is safe to delete the expired %pass shunts.
- */
- while (expired != NULL)
- {
- struct eroute_info *p = expired;
- ip_address src, dst;
-
- networkof(&p->ours, &src);
- networkof(&p->his, &dst);
- (void) replace_bare_shunt(&src, &dst
- , BOTTOM_PRIO /* not used because we are deleting. This value is a filler */
- , SPI_PASS /* not used because we are deleting. This value is a filler */
- , FALSE, p->transport_proto, "delete expired bare shunts");
- expired = p->next;
- pfree(p);
- }
+ struct eroute_info *p = expired;
+ ip_address src, dst;
+
+ networkof(&p->ours, &src);
+ networkof(&p->his, &dst);
+ (void) replace_bare_shunt(&src, &dst
+ , BOTTOM_PRIO /* not used because we are deleting. This value is a filler */
+ , SPI_PASS /* not used because we are deleting. This value is a filler */
+ , FALSE, p->transport_proto, "delete expired bare shunts");
+ expired = p->next;
+ free(p);
+ }
}
-static bool
-del_spi(ipsec_spi_t spi, int proto
-, const ip_address *src, const ip_address *dest)
+static bool del_spi(ipsec_spi_t spi, int proto,
+ const ip_address *src, const ip_address *dest)
{
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
+ char text_said[SATOT_BUF];
+ struct kernel_sa sa;
- set_text_said(text_said, dest, spi, proto);
+ set_text_said(text_said, dest, spi, proto);
- DBG(DBG_KLIPS, DBG_log("delete %s", text_said));
+ DBG(DBG_KLIPS, DBG_log("delete %s", text_said));
- memset(&sa, 0, sizeof(sa));
- sa.spi = spi;
- sa.proto = proto;
- sa.src = src;
- sa.dst = dest;
- sa.text_said = text_said;
+ memset(&sa, 0, sizeof(sa));
+ sa.spi = spi;
+ sa.proto = proto;
+ sa.src = src;
+ sa.dst = dest;
+ sa.text_said = text_said;
- return kernel_ops->del_sa(&sa);
+ return kernel_ops->del_sa(&sa);
}
/* Setup a pair of SAs. Code taken from setsa.c and spigrp.c, in
* ipsec-0.5.
*/
-static bool
-setup_half_ipsec_sa(struct state *st, bool inbound)
+static bool setup_half_ipsec_sa(struct state *st, bool inbound)
{
- /* Build an inbound or outbound SA */
-
- struct connection *c = st->st_connection;
- ip_subnet src, dst;
- ip_subnet src_client, dst_client;
- ipsec_spi_t inner_spi = 0;
- u_int proto = 0;
- u_int satype = SADB_SATYPE_UNSPEC;
- bool replace;
-
- /* SPIs, saved for spigrouping or undoing, if necessary */
- struct kernel_sa
- said[EM_MAXRELSPIS],
- *said_next = said;
-
- char text_said[SATOT_BUF];
- int encapsulation;
-
- replace = inbound && (kernel_ops->get_spi != NULL);
-
- src.maskbits = 0;
- dst.maskbits = 0;
-
- if (inbound)
- {
- src.addr = c->spd.that.host_addr;
- dst.addr = c->spd.this.host_addr;
- src_client = c->spd.that.client;
- dst_client = c->spd.this.client;
- }
- else
- {
- src.addr = c->spd.this.host_addr,
- dst.addr = c->spd.that.host_addr;
- src_client = c->spd.this.client;
- dst_client = c->spd.that.client;
- }
-
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- encapsulation = ENCAPSULATION_MODE_TUNNEL;
- }
-
- memset(said, 0, sizeof(said));
-
- /* If we are tunnelling, set up IP in IP pseudo SA */
-
- if (kernel_ops->inbound_eroute)
- {
- inner_spi = 256;
- proto = SA_IPIP;
- satype = SADB_SATYPE_UNSPEC;
- }
- else if (encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- /* XXX hack alert -- we SHOULD NOT HAVE TO HAVE A DIFFERENT SPI
- * XXX FOR IP-in-IP ENCAPSULATION!
- */
+ /* Build an inbound or outbound SA */
- ipsec_spi_t ipip_spi;
+ struct connection *c = st->st_connection;
+ ip_subnet src, dst;
+ ip_subnet src_client, dst_client;
+ ipsec_spi_t inner_spi = 0;
+ u_int proto = 0;
+ u_int satype = SADB_SATYPE_UNSPEC;
+ bool replace;
- /* Allocate an SPI for the tunnel.
- * Since our peer will never see this,
- * and it comes from its own number space,
- * it is purely a local implementation wart.
- */
+ /* SPIs, saved for spigrouping or undoing, if necessary */
+ struct kernel_sa
+ said[EM_MAXRELSPIS],
+ *said_next = said;
+
+ char text_said[SATOT_BUF];
+ int encapsulation;
+
+ replace = inbound && (kernel_ops->get_spi != NULL);
+
+ src.maskbits = 0;
+ dst.maskbits = 0;
+
+ if (inbound)
+ {
+ src.addr = c->spd.that.host_addr;
+ dst.addr = c->spd.this.host_addr;
+ src_client = c->spd.that.client;
+ dst_client = c->spd.this.client;
+ }
+ else
{
- static ipsec_spi_t last_tunnel_spi = IPSEC_DOI_SPI_OUR_MIN;
+ src.addr = c->spd.this.host_addr,
+ dst.addr = c->spd.that.host_addr;
+ src_client = c->spd.this.client;
+ dst_client = c->spd.that.client;
+ }
- ipip_spi = htonl(++last_tunnel_spi);
- if (inbound)
- st->st_tunnel_in_spi = ipip_spi;
- else
- st->st_tunnel_out_spi = ipip_spi;
+ encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ encapsulation = ENCAPSULATION_MODE_TUNNEL;
}
- set_text_said(text_said
- , &c->spd.that.host_addr, ipip_spi, SA_IPIP);
+ memset(said, 0, sizeof(said));
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ipip_spi;
- said_next->satype = SADB_X_SATYPE_IPIP;
- said_next->text_said = text_said;
+ /* If we are tunnelling, set up IP in IP pseudo SA */
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
+ if (kernel_ops->inbound_eroute)
+ {
+ inner_spi = 256;
+ proto = SA_IPIP;
+ satype = SADB_SATYPE_UNSPEC;
+ }
+ else if (encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ /* XXX hack alert -- we SHOULD NOT HAVE TO HAVE A DIFFERENT SPI
+ * XXX FOR IP-in-IP ENCAPSULATION!
+ */
- said_next++;
+ ipsec_spi_t ipip_spi;
- inner_spi = ipip_spi;
- proto = SA_IPIP;
- satype = SADB_X_SATYPE_IPIP;
- }
+ /* Allocate an SPI for the tunnel.
+ * Since our peer will never see this,
+ * and it comes from its own number space,
+ * it is purely a local implementation wart.
+ */
+ {
+ static ipsec_spi_t last_tunnel_spi = IPSEC_DOI_SPI_OUR_MIN;
- /* set up IPCOMP SA, if any */
+ ipip_spi = htonl(++last_tunnel_spi);
+ if (inbound)
+ st->st_tunnel_in_spi = ipip_spi;
+ else
+ st->st_tunnel_out_spi = ipip_spi;
+ }
- if (st->st_ipcomp.present)
- {
- ipsec_spi_t ipcomp_spi = inbound? st->st_ipcomp.our_spi : st->st_ipcomp.attrs.spi;
- unsigned compalg;
+ set_text_said(text_said
+ , &c->spd.that.host_addr, ipip_spi, SA_IPIP);
- switch (st->st_ipcomp.attrs.transid)
- {
- case IPCOMP_DEFLATE:
- compalg = SADB_X_CALG_DEFLATE;
- break;
+ said_next->src = &src.addr;
+ said_next->dst = &dst.addr;
+ said_next->src_client = &src_client;
+ said_next->dst_client = &dst_client;
+ said_next->spi = ipip_spi;
+ said_next->satype = SADB_X_SATYPE_IPIP;
+ said_next->text_said = text_said;
- default:
- loglog(RC_LOG_SERIOUS, "IPCOMP transform %s not implemented"
- , enum_name(&ipcomp_transformid_names, st->st_ipcomp.attrs.transid));
- goto fail;
- }
+ if (!kernel_ops->add_sa(said_next, replace))
+ goto fail;
- set_text_said(text_said, &dst.addr, ipcomp_spi, SA_COMP);
+ said_next++;
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ipcomp_spi;
- said_next->satype = SADB_X_SATYPE_COMP;
- said_next->compalg = compalg;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid + 2;
- said_next->text_said = text_said;
+ inner_spi = ipip_spi;
+ proto = SA_IPIP;
+ satype = SADB_X_SATYPE_IPIP;
+ }
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
+ /* set up IPCOMP SA, if any */
- said_next++;
+ if (st->st_ipcomp.present)
+ {
+ ipsec_spi_t ipcomp_spi = inbound? st->st_ipcomp.our_spi : st->st_ipcomp.attrs.spi;
+ unsigned compalg;
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
+ switch (st->st_ipcomp.attrs.transid)
+ {
+ case IPCOMP_DEFLATE:
+ compalg = SADB_X_CALG_DEFLATE;
+ break;
+
+ default:
+ loglog(RC_LOG_SERIOUS, "IPCOMP transform %s not implemented"
+ , enum_name(&ipcomp_transformid_names, st->st_ipcomp.attrs.transid));
+ goto fail;
+ }
- /* set up ESP SA, if any */
+ set_text_said(text_said, &dst.addr, ipcomp_spi, SA_COMP);
- if (st->st_esp.present)
- {
- ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
- u_char *esp_dst_keymat = inbound? st->st_esp.our_keymat : st->st_esp.peer_keymat;
- const struct esp_info *ei;
- u_int16_t key_len;
-
- static const struct esp_info esp_info[] = {
- { ESP_NULL, AUTH_ALGORITHM_HMAC_MD5,
- 0, HMAC_MD5_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_MD5HMAC },
- { ESP_NULL, AUTH_ALGORITHM_HMAC_SHA1,
- 0, HMAC_SHA1_KEY_LEN,
- SADB_EALG_NULL, SADB_AALG_SHA1HMAC },
-
- { ESP_DES, AUTH_ALGORITHM_NONE,
- DES_CBC_BLOCK_SIZE, 0,
- SADB_EALG_DESCBC, SADB_AALG_NONE },
- { ESP_DES, AUTH_ALGORITHM_HMAC_MD5,
- DES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,
- SADB_EALG_DESCBC, SADB_AALG_MD5HMAC },
- { ESP_DES, AUTH_ALGORITHM_HMAC_SHA1,
- DES_CBC_BLOCK_SIZE,
- HMAC_SHA1_KEY_LEN, SADB_EALG_DESCBC, SADB_AALG_SHA1HMAC },
-
- { ESP_3DES, AUTH_ALGORITHM_NONE,
- DES_CBC_BLOCK_SIZE * 3, 0,
- SADB_EALG_3DESCBC, SADB_AALG_NONE },
- { ESP_3DES, AUTH_ALGORITHM_HMAC_MD5,
- DES_CBC_BLOCK_SIZE * 3, HMAC_MD5_KEY_LEN,
- SADB_EALG_3DESCBC, SADB_AALG_MD5HMAC },
- { ESP_3DES, AUTH_ALGORITHM_HMAC_SHA1,
- DES_CBC_BLOCK_SIZE * 3, HMAC_SHA1_KEY_LEN,
- SADB_EALG_3DESCBC, SADB_AALG_SHA1HMAC },
- };
+ said_next->src = &src.addr;
+ said_next->dst = &dst.addr;
+ said_next->src_client = &src_client;
+ said_next->dst_client = &dst_client;
+ said_next->spi = ipcomp_spi;
+ said_next->satype = SADB_X_SATYPE_COMP;
+ said_next->compalg = compalg;
+ said_next->encapsulation = encapsulation;
+ said_next->reqid = c->spd.reqid + 2;
+ said_next->text_said = text_said;
- u_int8_t natt_type = 0;
- u_int16_t natt_sport = 0;
- u_int16_t natt_dport = 0;
- ip_address natt_oa;
+ if (!kernel_ops->add_sa(said_next, replace))
+ goto fail;
- if (st->nat_traversal & NAT_T_DETECTED)
- {
- natt_type = (st->nat_traversal & NAT_T_WITH_PORT_FLOATING) ?
- ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;
- natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port;
- natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
- natt_oa = st->nat_oa;
+ said_next++;
+
+ encapsulation = ENCAPSULATION_MODE_TRANSPORT;
}
- for (ei = esp_info; ; ei++)
+ /* set up ESP SA, if any */
+
+ if (st->st_esp.present)
{
- if (ei == &esp_info[elemsof(esp_info)])
- {
- /* Check for additional kernel alg */
-#ifndef NO_KERNEL_ALG
- if ((ei=kernel_alg_esp_info(st->st_esp.attrs.transid,
- st->st_esp.attrs.auth))!=NULL) {
- break;
+ ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
+ u_char *esp_dst_keymat = inbound? st->st_esp.our_keymat : st->st_esp.peer_keymat;
+ const struct esp_info *ei;
+ u_int16_t key_len;
+
+ static const struct esp_info esp_info[] = {
+ { ESP_NULL, AUTH_ALGORITHM_HMAC_MD5,
+ 0, HMAC_MD5_KEY_LEN,
+ SADB_EALG_NULL, SADB_AALG_MD5HMAC },
+ { ESP_NULL, AUTH_ALGORITHM_HMAC_SHA1,
+ 0, HMAC_SHA1_KEY_LEN,
+ SADB_EALG_NULL, SADB_AALG_SHA1HMAC },
+
+ { ESP_DES, AUTH_ALGORITHM_NONE,
+ DES_CBC_BLOCK_SIZE, 0,
+ SADB_EALG_DESCBC, SADB_AALG_NONE },
+ { ESP_DES, AUTH_ALGORITHM_HMAC_MD5,
+ DES_CBC_BLOCK_SIZE, HMAC_MD5_KEY_LEN,
+ SADB_EALG_DESCBC, SADB_AALG_MD5HMAC },
+ { ESP_DES, AUTH_ALGORITHM_HMAC_SHA1,
+ DES_CBC_BLOCK_SIZE,
+ HMAC_SHA1_KEY_LEN, SADB_EALG_DESCBC, SADB_AALG_SHA1HMAC },
+
+ { ESP_3DES, AUTH_ALGORITHM_NONE,
+ DES_CBC_BLOCK_SIZE * 3, 0,
+ SADB_EALG_3DESCBC, SADB_AALG_NONE },
+ { ESP_3DES, AUTH_ALGORITHM_HMAC_MD5,
+ DES_CBC_BLOCK_SIZE * 3, HMAC_MD5_KEY_LEN,
+ SADB_EALG_3DESCBC, SADB_AALG_MD5HMAC },
+ { ESP_3DES, AUTH_ALGORITHM_HMAC_SHA1,
+ DES_CBC_BLOCK_SIZE * 3, HMAC_SHA1_KEY_LEN,
+ SADB_EALG_3DESCBC, SADB_AALG_SHA1HMAC },
+ };
+
+ u_int8_t natt_type = 0;
+ u_int16_t natt_sport = 0;
+ u_int16_t natt_dport = 0;
+ ip_address natt_oa;
+
+ if (st->nat_traversal & NAT_T_DETECTED)
+ {
+ natt_type = (st->nat_traversal & NAT_T_WITH_PORT_FLOATING) ?
+ ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;
+ natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port;
+ natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
+ natt_oa = st->nat_oa;
}
-#endif
- /* note: enum_show may use a static buffer, so two
- * calls in one printf would be a mistake.
- * enum_name does the same job, without a static buffer,
- * assuming the name will be found.
- */
- loglog(RC_LOG_SERIOUS, "ESP transform %s / auth %s not implemented yet"
- , enum_name(&esp_transformid_names, st->st_esp.attrs.transid)
- , enum_name(&auth_alg_names, st->st_esp.attrs.auth));
- goto fail;
- }
-
- if (st->st_esp.attrs.transid == ei->transid
- && st->st_esp.attrs.auth == ei->auth)
- break;
- }
+ for (ei = esp_info; ; ei++)
+ {
+ if (ei == &esp_info[countof(esp_info)])
+ {
+ /* Check for additional kernel alg */
+#ifndef NO_KERNEL_ALG
+ if ((ei=kernel_alg_esp_info(st->st_esp.attrs.transid,
+ st->st_esp.attrs.auth))!=NULL) {
+ break;
+ }
+#endif
- key_len = st->st_esp.attrs.key_len/8;
- if (key_len)
- {
- /* XXX: must change to check valid _range_ key_len */
- if (key_len > ei->enckeylen)
- {
- loglog(RC_LOG_SERIOUS, "ESP transform %s passed key_len=%d > %d",
- enum_name(&esp_transformid_names, st->st_esp.attrs.transid),
- (int)key_len, (int)ei->enckeylen);
- goto fail;
- }
- }
- else
- {
- key_len = ei->enckeylen;
- }
- /* Grrrrr.... f*cking 7 bits jurassic algos */
+ /* note: enum_show may use a static buffer, so two
+ * calls in one printf would be a mistake.
+ * enum_name does the same job, without a static buffer,
+ * assuming the name will be found.
+ */
+ loglog(RC_LOG_SERIOUS, "ESP transform %s / auth %s not implemented yet"
+ , enum_name(&esp_transformid_names, st->st_esp.attrs.transid)
+ , enum_name(&auth_alg_names, st->st_esp.attrs.auth));
+ goto fail;
+ }
- /* 168 bits in kernel, need 192 bits for keymat_len */
- if (ei->transid == ESP_3DES && key_len == 21)
- key_len = 24;
+ if (st->st_esp.attrs.transid == ei->transid
+ && st->st_esp.attrs.auth == ei->auth)
+ break;
+ }
- /* 56 bits in kernel, need 64 bits for keymat_len */
- if (ei->transid == ESP_DES && key_len == 7)
- key_len = 8;
+ key_len = st->st_esp.attrs.key_len/8;
+ if (key_len)
+ {
+ /* XXX: must change to check valid _range_ key_len */
+ if (key_len > ei->enckeylen)
+ {
+ loglog(RC_LOG_SERIOUS, "ESP transform %s passed key_len=%d > %d",
+ enum_name(&esp_transformid_names, st->st_esp.attrs.transid),
+ (int)key_len, (int)ei->enckeylen);
+ goto fail;
+ }
+ }
+ else
+ {
+ key_len = ei->enckeylen;
+ }
+ /* Grrrrr.... f*cking 7 bits jurassic algos */
+
+ /* 168 bits in kernel, need 192 bits for keymat_len */
+ if (ei->transid == ESP_3DES && key_len == 21)
+ key_len = 24;
+
+ /* 56 bits in kernel, need 64 bits for keymat_len */
+ if (ei->transid == ESP_DES && key_len == 7)
+ key_len = 8;
+
+ /* divide up keying material */
+ /* passert(st->st_esp.keymat_len == ei->enckeylen + ei->authkeylen); */
+ DBG(DBG_KLIPS|DBG_CONTROL|DBG_PARSING,
+ if(st->st_esp.keymat_len != key_len + ei->authkeylen)
+ DBG_log("keymat_len=%d key_len=%d authkeylen=%d",
+ st->st_esp.keymat_len, (int)key_len, (int)ei->authkeylen);
+ )
+ passert(st->st_esp.keymat_len == key_len + ei->authkeylen);
+
+ set_text_said(text_said, &dst.addr, esp_spi, SA_ESP);
+
+ said_next->src = &src.addr;
+ said_next->dst = &dst.addr;
+ said_next->src_client = &src_client;
+ said_next->dst_client = &dst_client;
+ said_next->spi = esp_spi;
+ said_next->satype = SADB_SATYPE_ESP;
+ said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
+ said_next->authalg = ei->authalg;
+ said_next->authkeylen = ei->authkeylen;
+ /* said_next->authkey = esp_dst_keymat + ei->enckeylen; */
+ said_next->authkey = esp_dst_keymat + key_len;
+ said_next->encalg = ei->encryptalg;
+ /* said_next->enckeylen = ei->enckeylen; */
+ said_next->enckeylen = key_len;
+ said_next->enckey = esp_dst_keymat;
+ said_next->encapsulation = encapsulation;
+ said_next->reqid = c->spd.reqid + 1;
+ said_next->natt_sport = natt_sport;
+ said_next->natt_dport = natt_dport;
+ said_next->transid = st->st_esp.attrs.transid;
+ said_next->natt_type = natt_type;
+ said_next->natt_oa = &natt_oa;
+ said_next->text_said = text_said;
+
+ if (!kernel_ops->add_sa(said_next, replace))
+ goto fail;
+
+ said_next++;
+
+ encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ }
- /* divide up keying material */
- /* passert(st->st_esp.keymat_len == ei->enckeylen + ei->authkeylen); */
- DBG(DBG_KLIPS|DBG_CONTROL|DBG_PARSING,
- if(st->st_esp.keymat_len != key_len + ei->authkeylen)
- DBG_log("keymat_len=%d key_len=%d authkeylen=%d",
- st->st_esp.keymat_len, (int)key_len, (int)ei->authkeylen);
- )
- passert(st->st_esp.keymat_len == key_len + ei->authkeylen);
-
- set_text_said(text_said, &dst.addr, esp_spi, SA_ESP);
-
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = esp_spi;
- said_next->satype = SADB_SATYPE_ESP;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
- said_next->authalg = ei->authalg;
- said_next->authkeylen = ei->authkeylen;
- /* said_next->authkey = esp_dst_keymat + ei->enckeylen; */
- said_next->authkey = esp_dst_keymat + key_len;
- said_next->encalg = ei->encryptalg;
- /* said_next->enckeylen = ei->enckeylen; */
- said_next->enckeylen = key_len;
- said_next->enckey = esp_dst_keymat;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid + 1;
- said_next->natt_sport = natt_sport;
- said_next->natt_dport = natt_dport;
- said_next->transid = st->st_esp.attrs.transid;
- said_next->natt_type = natt_type;
- said_next->natt_oa = &natt_oa;
- said_next->text_said = text_said;
-
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
-
- said_next++;
+ /* set up AH SA, if any */
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
+ if (st->st_ah.present)
+ {
+ ipsec_spi_t ah_spi = inbound? st->st_ah.our_spi : st->st_ah.attrs.spi;
+ u_char *ah_dst_keymat = inbound? st->st_ah.our_keymat : st->st_ah.peer_keymat;
- /* set up AH SA, if any */
+ unsigned char authalg;
- if (st->st_ah.present)
- {
- ipsec_spi_t ah_spi = inbound? st->st_ah.our_spi : st->st_ah.attrs.spi;
- u_char *ah_dst_keymat = inbound? st->st_ah.our_keymat : st->st_ah.peer_keymat;
+ switch (st->st_ah.attrs.auth)
+ {
+ case AUTH_ALGORITHM_HMAC_MD5:
+ authalg = SADB_AALG_MD5HMAC;
+ break;
- unsigned char authalg;
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ authalg = SADB_AALG_SHA1HMAC;
+ break;
- switch (st->st_ah.attrs.auth)
- {
- case AUTH_ALGORITHM_HMAC_MD5:
- authalg = SADB_AALG_MD5HMAC;
- break;
+ default:
+ loglog(RC_LOG_SERIOUS, "%s not implemented yet"
+ , enum_show(&auth_alg_names, st->st_ah.attrs.auth));
+ goto fail;
+ }
- case AUTH_ALGORITHM_HMAC_SHA1:
- authalg = SADB_AALG_SHA1HMAC;
- break;
+ set_text_said(text_said, &dst.addr, ah_spi, SA_AH);
- default:
- loglog(RC_LOG_SERIOUS, "%s not implemented yet"
- , enum_show(&auth_alg_names, st->st_ah.attrs.auth));
- goto fail;
- }
+ said_next->src = &src.addr;
+ said_next->dst = &dst.addr;
+ said_next->src_client = &src_client;
+ said_next->dst_client = &dst_client;
+ said_next->spi = ah_spi;
+ said_next->satype = SADB_SATYPE_AH;
+ said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
+ said_next->authalg = authalg;
+ said_next->authkeylen = st->st_ah.keymat_len;
+ said_next->authkey = ah_dst_keymat;
+ said_next->encapsulation = encapsulation;
+ said_next->reqid = c->spd.reqid;
+ said_next->text_said = text_said;
- set_text_said(text_said, &dst.addr, ah_spi, SA_AH);
+ if (!kernel_ops->add_sa(said_next, replace))
+ goto fail;
- said_next->src = &src.addr;
- said_next->dst = &dst.addr;
- said_next->src_client = &src_client;
- said_next->dst_client = &dst_client;
- said_next->spi = ah_spi;
- said_next->satype = SADB_SATYPE_AH;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
- said_next->authalg = authalg;
- said_next->authkeylen = st->st_ah.keymat_len;
- said_next->authkey = ah_dst_keymat;
- said_next->encapsulation = encapsulation;
- said_next->reqid = c->spd.reqid;
- said_next->text_said = text_said;
+ said_next++;
- if (!kernel_ops->add_sa(said_next, replace))
- goto fail;
+ encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ }
- said_next++;
+ if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ encapsulation = ENCAPSULATION_MODE_TUNNEL;
+ }
- encapsulation = ENCAPSULATION_MODE_TRANSPORT;
- }
-
- if (st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- encapsulation = ENCAPSULATION_MODE_TUNNEL;
- }
-
- if (kernel_ops->inbound_eroute ? c->spd.eroute_owner == SOS_NOBODY
- : encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- /* If inbound, and policy does not specifie DISABLEARRIVALCHECK,
- * tell KLIPS to enforce the IP addresses appropriate for this tunnel.
- * Note reversed ends.
- * Not much to be done on failure.
- */
- if (inbound && (c->policy & POLICY_DISABLEARRIVALCHECK) == 0)
+ if (kernel_ops->inbound_eroute ? c->spd.eroute_owner == SOS_NOBODY
+ : encapsulation == ENCAPSULATION_MODE_TUNNEL)
{
- struct pfkey_proto_info proto_info[4];
- int i = 0;
-
- if (st->st_ipcomp.present)
- {
- proto_info[i].proto = IPPROTO_COMP;
- proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid + 2;
- i++;
- }
-
- if (st->st_esp.present)
- {
- proto_info[i].proto = IPPROTO_ESP;
- proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid + 1;
- i++;
- }
-
- if (st->st_ah.present)
- {
- proto_info[i].proto = IPPROTO_AH;
- proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
- proto_info[i].reqid = c->spd.reqid;
- i++;
- }
-
- proto_info[i].proto = 0;
-
- if (kernel_ops->inbound_eroute
- && encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- proto_info[0].encapsulation = ENCAPSULATION_MODE_TUNNEL;
- for (i = 1; proto_info[i].proto; i++)
+ /* If inbound, and policy does not specifie DISABLEARRIVALCHECK,
+ * tell KLIPS to enforce the IP addresses appropriate for this tunnel.
+ * Note reversed ends.
+ * Not much to be done on failure.
+ */
+ if (inbound && (c->policy & POLICY_DISABLEARRIVALCHECK) == 0)
{
- proto_info[i].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ struct pfkey_proto_info proto_info[4];
+ int i = 0;
+
+ if (st->st_ipcomp.present)
+ {
+ proto_info[i].proto = IPPROTO_COMP;
+ proto_info[i].encapsulation = st->st_ipcomp.attrs.encapsulation;
+ proto_info[i].reqid = c->spd.reqid + 2;
+ i++;
+ }
+
+ if (st->st_esp.present)
+ {
+ proto_info[i].proto = IPPROTO_ESP;
+ proto_info[i].encapsulation = st->st_esp.attrs.encapsulation;
+ proto_info[i].reqid = c->spd.reqid + 1;
+ i++;
+ }
+
+ if (st->st_ah.present)
+ {
+ proto_info[i].proto = IPPROTO_AH;
+ proto_info[i].encapsulation = st->st_ah.attrs.encapsulation;
+ proto_info[i].reqid = c->spd.reqid;
+ i++;
+ }
+
+ proto_info[i].proto = 0;
+
+ if (kernel_ops->inbound_eroute
+ && encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ proto_info[0].encapsulation = ENCAPSULATION_MODE_TUNNEL;
+ for (i = 1; proto_info[i].proto; i++)
+ {
+ proto_info[i].encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ }
+ }
+
+ /* MCR - should be passed a spd_eroute structure here */
+ (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
+ , &c->spd.this.host_addr, &c->spd.this.client
+ , inner_spi, proto, satype, c->spd.this.protocol
+ , proto_info, 0
+ , ERO_ADD_INBOUND, "add inbound");
}
- }
-
- /* MCR - should be passed a spd_eroute structure here */
- (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , inner_spi, proto, satype, c->spd.this.protocol
- , proto_info, 0
- , ERO_ADD_INBOUND, "add inbound");
- }
- }
-
- /* If there are multiple SPIs, group them. */
-
- if (kernel_ops->grp_sa && said_next > &said[1])
- {
- struct kernel_sa *s;
+ }
+
+ /* If there are multiple SPIs, group them. */
- /* group SAs, two at a time, inner to outer (backwards in said[])
- * The grouping is by pairs. So if said[] contains ah esp ipip,
- * the grouping would be ipip:esp, esp:ah.
- */
- for (s = said; s < said_next-1; s++)
- {
- char
- text_said0[SATOT_BUF],
- text_said1[SATOT_BUF];
-
- /* group s[1] and s[0], in that order */
-
- set_text_said(text_said0, s[0].dst, s[0].spi, s[0].proto);
- set_text_said(text_said1, s[1].dst, s[1].spi, s[1].proto);
-
- DBG(DBG_KLIPS, DBG_log("grouping %s and %s", text_said1, text_said0));
-
- s[0].text_said = text_said0;
- s[1].text_said = text_said1;
-
- if (!kernel_ops->grp_sa(s + 1, s))
- goto fail;
- }
- /* could update said, but it will not be used */
- }
-
- return TRUE;
+ if (kernel_ops->grp_sa && said_next > &said[1])
+ {
+ struct kernel_sa *s;
+
+ /* group SAs, two at a time, inner to outer (backwards in said[])
+ * The grouping is by pairs. So if said[] contains ah esp ipip,
+ * the grouping would be ipip:esp, esp:ah.
+ */
+ for (s = said; s < said_next-1; s++)
+ {
+ char
+ text_said0[SATOT_BUF],
+ text_said1[SATOT_BUF];
+
+ /* group s[1] and s[0], in that order */
+
+ set_text_said(text_said0, s[0].dst, s[0].spi, s[0].proto);
+ set_text_said(text_said1, s[1].dst, s[1].spi, s[1].proto);
+
+ DBG(DBG_KLIPS, DBG_log("grouping %s and %s", text_said1, text_said0));
+
+ s[0].text_said = text_said0;
+ s[1].text_said = text_said1;
+
+ if (!kernel_ops->grp_sa(s + 1, s))
+ goto fail;
+ }
+ /* could update said, but it will not be used */
+ }
+
+ return TRUE;
fail:
- {
- /* undo the done SPIs */
- while (said_next-- != said)
- (void) del_spi(said_next->spi, said_next->proto
- , &src.addr, said_next->dst);
- return FALSE;
- }
+ {
+ /* undo the done SPIs */
+ while (said_next-- != said)
+ (void) del_spi(said_next->spi, said_next->proto
+ , &src.addr, said_next->dst);
+ return FALSE;
+ }
}
/* teardown_ipsec_sa is a canibalized version of setup_ipsec_sa */
-static bool
-teardown_half_ipsec_sa(struct state *st, bool inbound)
+static bool teardown_half_ipsec_sa(struct state *st, bool inbound)
{
- /* We need to delete AH, ESP, and IP in IP SPIs.
- * But if there is more than one, they have been grouped
- * so deleting any one will do. So we just delete the
- * first one found. It may or may not be the only one.
- */
- struct connection *c = st->st_connection;
- struct {
- unsigned proto;
- struct ipsec_proto_info *info;
- } protos[4];
- int i;
- bool result;
-
- i = 0;
- if (kernel_ops->inbound_eroute && inbound
- && c->spd.eroute_owner == SOS_NOBODY)
- {
- (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
- , &c->spd.this.host_addr, &c->spd.this.client
- , 256, IPSEC_PROTO_ANY, SADB_SATYPE_UNSPEC, c->spd.this.protocol
- , null_proto_info, 0
- , ERO_DEL_INBOUND, "delete inbound");
- }
-
- if (!kernel_ops->grp_sa)
- {
- if (st->st_ah.present)
+ /* We need to delete AH, ESP, and IP in IP SPIs.
+ * But if there is more than one, they have been grouped
+ * so deleting any one will do. So we just delete the
+ * first one found. It may or may not be the only one.
+ */
+ struct connection *c = st->st_connection;
+ struct {
+ unsigned proto;
+ struct ipsec_proto_info *info;
+ } protos[4];
+ int i;
+ bool result;
+
+ i = 0;
+ if (kernel_ops->inbound_eroute && inbound
+ && c->spd.eroute_owner == SOS_NOBODY)
{
- protos[i].info = &st->st_ah;
- protos[i].proto = SA_AH;
- i++;
+ (void) raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
+ , &c->spd.this.host_addr, &c->spd.this.client
+ , 256, IPSEC_PROTO_ANY, SADB_SATYPE_UNSPEC, c->spd.this.protocol
+ , null_proto_info, 0
+ , ERO_DEL_INBOUND, "delete inbound");
}
- if (st->st_esp.present)
+ if (!kernel_ops->grp_sa)
{
- protos[i].info = &st->st_esp;
- protos[i].proto = SA_ESP;
- i++;
- }
+ if (st->st_ah.present)
+ {
+ protos[i].info = &st->st_ah;
+ protos[i].proto = SA_AH;
+ i++;
+ }
- if (st->st_ipcomp.present)
- {
- protos[i].info = &st->st_ipcomp;
- protos[i].proto = SA_COMP;
- i++;
- }
- }
- else if (st->st_ah.present)
- {
- protos[i].info = &st->st_ah;
- protos[i].proto = SA_AH;
- i++;
- }
- else if (st->st_esp.present)
- {
- protos[i].info = &st->st_esp;
- protos[i].proto = SA_ESP;
- i++;
- }
- else
- {
- impossible(); /* neither AH nor ESP in outbound SA bundle! */
- }
- protos[i].proto = 0;
-
- result = TRUE;
- for (i = 0; protos[i].proto; i++)
- {
- unsigned proto = protos[i].proto;
- ipsec_spi_t spi;
- const ip_address *src, *dst;
+ if (st->st_esp.present)
+ {
+ protos[i].info = &st->st_esp;
+ protos[i].proto = SA_ESP;
+ i++;
+ }
- if (inbound)
+ if (st->st_ipcomp.present)
+ {
+ protos[i].info = &st->st_ipcomp;
+ protos[i].proto = SA_COMP;
+ i++;
+ }
+ }
+ else if (st->st_ah.present)
+ {
+ protos[i].info = &st->st_ah;
+ protos[i].proto = SA_AH;
+ i++;
+ }
+ else if (st->st_esp.present)
{
- spi = protos[i].info->our_spi;
- src = &c->spd.that.host_addr;
- dst = &c->spd.this.host_addr;
+ protos[i].info = &st->st_esp;
+ protos[i].proto = SA_ESP;
+ i++;
}
else
{
- spi = protos[i].info->attrs.spi;
- src = &c->spd.this.host_addr;
- dst = &c->spd.that.host_addr;
+ impossible(); /* neither AH nor ESP in outbound SA bundle! */
}
+ protos[i].proto = 0;
+
+ result = TRUE;
+ for (i = 0; protos[i].proto; i++)
+ {
+ unsigned proto = protos[i].proto;
+ ipsec_spi_t spi;
+ const ip_address *src, *dst;
+
+ if (inbound)
+ {
+ spi = protos[i].info->our_spi;
+ src = &c->spd.that.host_addr;
+ dst = &c->spd.this.host_addr;
+ }
+ else
+ {
+ spi = protos[i].info->attrs.spi;
+ src = &c->spd.this.host_addr;
+ dst = &c->spd.that.host_addr;
+ }
- result &= del_spi(spi, proto, src, dst);
- }
- return result;
+ result &= del_spi(spi, proto, src, dst);
+ }
+ return result;
}
/*
* get information about a given sa
*/
-bool
-get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
+bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
{
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
- struct connection *c = st->st_connection;
+ char text_said[SATOT_BUF];
+ struct kernel_sa sa;
+ struct connection *c = st->st_connection;
- *use_time = UNDEFINED_TIME;
+ *use_time = UNDEFINED_TIME;
- if (kernel_ops->get_sa == NULL || !st->st_esp.present)
- return FALSE;
+ if (kernel_ops->get_sa == NULL || !st->st_esp.present)
+ return FALSE;
- memset(&sa, 0, sizeof(sa));
- sa.proto = SA_ESP;
-
- if (inbound)
- {
- sa.src = &c->spd.that.host_addr;
- sa.dst = &c->spd.this.host_addr;
- sa.spi = st->st_esp.our_spi;
- }
- else
- {
- sa.src = &c->spd.this.host_addr;
- sa.dst = &c->spd.that.host_addr;
- sa.spi = st->st_esp.attrs.spi;
- }
- set_text_said(text_said, sa.dst, sa.spi, sa.proto);
-
- sa.text_said = text_said;
-
- DBG(DBG_KLIPS,
- DBG_log("get %s", text_said)
- )
- if (!kernel_ops->get_sa(&sa, bytes))
- return FALSE;
- DBG(DBG_KLIPS,
- DBG_log(" current: %d bytes", *bytes)
- )
-
- if (st->st_serialno == c->spd.eroute_owner)
- {
- DBG(DBG_KLIPS,
- DBG_log("get %sbound policy with reqid %u"
- , inbound? "in":"out", (u_int)c->spd.reqid + 1)
- )
- sa.transport_proto = c->spd.this.protocol;
- sa.encapsulation = st->st_esp.attrs.encapsulation;
+ memset(&sa, 0, sizeof(sa));
+ sa.proto = SA_ESP;
if (inbound)
{
- sa.src_client = &c->spd.that.client;
- sa.dst_client = &c->spd.this.client;
+ sa.src = &c->spd.that.host_addr;
+ sa.dst = &c->spd.this.host_addr;
+ sa.spi = st->st_esp.our_spi;
}
else
{
- sa.src_client = &c->spd.this.client;
- sa.dst_client = &c->spd.that.client;
+ sa.src = &c->spd.this.host_addr;
+ sa.dst = &c->spd.that.host_addr;
+ sa.spi = st->st_esp.attrs.spi;
}
- if (!kernel_ops->get_policy(&sa, inbound, use_time))
- return FALSE;
+ set_text_said(text_said, sa.dst, sa.spi, sa.proto);
+
+ sa.text_said = text_said;
+
+ DBG(DBG_KLIPS,
+ DBG_log("get %s", text_said)
+ )
+ if (!kernel_ops->get_sa(&sa, bytes))
+ return FALSE;
DBG(DBG_KLIPS,
- DBG_log(" use_time: %s", timetoa(use_time, FALSE))
+ DBG_log(" current: %d bytes", *bytes)
)
- }
- return TRUE;
+
+ if (st->st_serialno == c->spd.eroute_owner)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("get %sbound policy with reqid %u"
+ , inbound? "in":"out", (u_int)c->spd.reqid + 1)
+ )
+ sa.transport_proto = c->spd.this.protocol;
+ sa.encapsulation = st->st_esp.attrs.encapsulation;
+
+ if (inbound)
+ {
+ sa.src_client = &c->spd.that.client;
+ sa.dst_client = &c->spd.this.client;
+ }
+ else
+ {
+ sa.src_client = &c->spd.this.client;
+ sa.dst_client = &c->spd.that.client;
+ }
+ if (!kernel_ops->get_policy(&sa, inbound, use_time))
+ return FALSE;
+ DBG(DBG_KLIPS,
+ DBG_log(" use_time: %T", use_time, FALSE)
+ )
+ }
+ return TRUE;
}
const struct kernel_ops *kernel_ops;
#endif /* KLIPS */
-void
-init_kernel(void)
+void init_kernel(void)
{
#ifdef KLIPS
- if (no_klips)
- {
- kernel_ops = &noklips_kernel_ops;
- return;
- }
+ if (no_klips)
+ {
+ kernel_ops = &noklips_kernel_ops;
+ return;
+ }
- init_pfkey();
+ init_pfkey();
- kernel_ops = &klips_kernel_ops;
+ kernel_ops = &klips_kernel_ops;
#if defined(linux) && defined(KERNEL26_SUPPORT)
- {
- bool linux_ipsec = 0;
- struct stat buf;
-
- linux_ipsec = (stat("/proc/net/pfkey", &buf) == 0);
- if (linux_ipsec)
- {
- plog("Using Linux 2.6 IPsec interface code");
- kernel_ops = &linux_kernel_ops;
- }
- else
- {
- plog("Using KLIPS IPsec interface code");
- }
- }
+ {
+ bool linux_ipsec = 0;
+ struct stat buf;
+
+ linux_ipsec = (stat("/proc/net/pfkey", &buf) == 0);
+ if (linux_ipsec)
+ {
+ plog("Using Linux 2.6 IPsec interface code");
+ kernel_ops = &linux_kernel_ops;
+ }
+ else
+ {
+ plog("Using KLIPS IPsec interface code");
+ }
+ }
#endif
- if (kernel_ops->init)
- {
- kernel_ops->init();
- }
+ if (kernel_ops->init)
+ {
+ kernel_ops->init();
+ }
- /* register SA types that we can negotiate */
- can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
- kernel_ops->pfkey_register();
+ /* register SA types that we can negotiate */
+ can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
+ kernel_ops->pfkey_register();
- if (!kernel_ops->policy_lifetime)
- {
- event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
- }
+ if (!kernel_ops->policy_lifetime)
+ {
+ event_schedule(EVENT_SHUNT_SCAN, SHUNT_SCAN_INTERVAL, NULL);
+ }
#endif
}
@@ -2345,60 +2330,59 @@ init_kernel(void)
* The Responder will subsequently use install_ipsec_sa for the outbound.
* The Initiator uses install_ipsec_sa to install both at once.
*/
-bool
-install_inbound_ipsec_sa(struct state *st)
+bool install_inbound_ipsec_sa(struct state *st)
{
- struct connection *const c = st->st_connection;
-
- /* If our peer has a fixed-address client, check if we already
- * have a route for that client that conflicts. We will take this
- * as proof that that route and the connections using it are
- * obsolete and should be eliminated. Interestingly, this is
- * the only case in which we can tell that a connection is obsolete.
- */
- passert(c->kind == CK_PERMANENT || c->kind == CK_INSTANCE);
- if (c->spd.that.has_client)
- {
- for (;;)
- {
- struct spd_route *esr;
- struct connection *o = route_owner(c, &esr, NULL, NULL);
-
- if (o == NULL)
- break; /* nobody has a route */
-
- /* note: we ignore the client addresses at this end */
- if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr)
- && o->interface == c->interface)
- break; /* existing route is compatible */
-
- if (o->kind == CK_TEMPLATE && streq(o->name, c->name))
- break; /* ??? is this good enough?? */
-
- loglog(RC_LOG_SERIOUS, "route to peer's client conflicts with \"%s\" %s; releasing old connection to free the route"
- , o->name, ip_str(&o->spd.that.host_addr));
- release_connection(o, FALSE);
- }
- }
-
- DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa() checking if we can route"));
- /* check that we will be able to route and eroute */
- switch (could_route(c))
- {
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
- }
+ struct connection *const c = st->st_connection;
+
+ /* If our peer has a fixed-address client, check if we already
+ * have a route for that client that conflicts. We will take this
+ * as proof that that route and the connections using it are
+ * obsolete and should be eliminated. Interestingly, this is
+ * the only case in which we can tell that a connection is obsolete.
+ */
+ passert(c->kind == CK_PERMANENT || c->kind == CK_INSTANCE);
+ if (c->spd.that.has_client)
+ {
+ for (;;)
+ {
+ struct spd_route *esr;
+ struct connection *o = route_owner(c, &esr, NULL, NULL);
+
+ if (o == NULL)
+ break; /* nobody has a route */
+
+ /* note: we ignore the client addresses at this end */
+ if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr)
+ && o->interface == c->interface)
+ break; /* existing route is compatible */
+
+ if (o->kind == CK_TEMPLATE && streq(o->name, c->name))
+ break; /* ??? is this good enough?? */
+
+ loglog(RC_LOG_SERIOUS, "route to peer's client conflicts with \"%s\" %s; releasing old connection to free the route"
+ , o->name, ip_str(&o->spd.that.host_addr));
+ release_connection(o, FALSE);
+ }
+ }
+
+ DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa() checking if we can route"));
+ /* check that we will be able to route and eroute */
+ switch (could_route(c))
+ {
+ case route_easy:
+ case route_nearconflict:
+ break;
+
+ default:
+ return FALSE;
+ }
#ifdef KLIPS
- /* (attempt to) actually set up the SAs */
- return setup_half_ipsec_sa(st, TRUE);
+ /* (attempt to) actually set up the SAs */
+ return setup_half_ipsec_sa(st, TRUE);
#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa()"));
- return TRUE;
+ DBG(DBG_CONTROL, DBG_log("install_inbound_ipsec_sa()"));
+ return TRUE;
#endif /* !KLIPS */
}
@@ -2407,481 +2391,479 @@ install_inbound_ipsec_sa(struct state *st)
* Any SA Group must have already been created.
* On failure, steps will be unwound.
*/
-bool
-route_and_eroute(struct connection *c USED_BY_KLIPS
- , struct spd_route *sr USED_BY_KLIPS
- , struct state *st USED_BY_KLIPS)
+bool route_and_eroute(struct connection *c USED_BY_KLIPS,
+ struct spd_route *sr USED_BY_KLIPS,
+ struct state *st USED_BY_KLIPS)
{
#ifdef KLIPS
- struct spd_route *esr;
- struct spd_route *rosr;
- struct connection *ero /* who, if anyone, owns our eroute? */
- , *ro = route_owner(c, &rosr, &ero, &esr);
- bool eroute_installed = FALSE
- , firewall_notified = FALSE
- , route_installed = FALSE;
-
- struct connection *ero_top;
- struct bare_shunt **bspp;
-
- DBG(DBG_CONTROLMORE,
- DBG_log("route_and_eroute with c: %s (next: %s) ero:%s esr:{%p} ro:%s rosr:{%p} and state: %lu"
- , c->name
- , (c->policy_next ? c->policy_next->name : "none")
- , ero ? ero->name : "null"
- , esr
- , ro ? ro->name : "null"
- , rosr
- , st ? st->st_serialno : 0));
-
- /* look along the chain of policies for one with the same name */
- ero_top = ero;
+ struct spd_route *esr;
+ struct spd_route *rosr;
+ struct connection *ero /* who, if anyone, owns our eroute? */
+ , *ro = route_owner(c, &rosr, &ero, &esr);
+ bool eroute_installed = FALSE
+ , firewall_notified = FALSE
+ , route_installed = FALSE;
+
+ struct connection *ero_top;
+ struct bare_shunt **bspp;
+
+ DBG(DBG_CONTROLMORE,
+ DBG_log("route_and_eroute with c: %s (next: %s) ero:%s esr:{%p} ro:%s rosr:{%p} and state: %lu"
+ , c->name
+ , (c->policy_next ? c->policy_next->name : "none")
+ , ero ? ero->name : "null"
+ , esr
+ , ro ? ro->name : "null"
+ , rosr
+ , st ? st->st_serialno : 0));
+
+ /* look along the chain of policies for one with the same name */
+ ero_top = ero;
#if 0
- /* XXX - mcr this made sense before, and likely will make sense
- * again, so I'l leaving this to remind me what is up */
- if (ero!= NULL && ero->routing == RT_UNROUTED_KEYED)
- ero = NULL;
-
- for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
- if ((ero2->kind == CK_TEMPLATE || ero2->kind==CK_SECONDARY)
- && streq(ero2->name, c->name))
- break;
+ /* XXX - mcr this made sense before, and likely will make sense
+ * again, so I'l leaving this to remind me what is up */
+ if (ero!= NULL && ero->routing == RT_UNROUTED_KEYED)
+ ero = NULL;
+
+ for (ero2 = ero; ero2 != NULL; ero2 = ero->policy_next)
+ if ((ero2->kind == CK_TEMPLATE || ero2->kind==CK_SECONDARY)
+ && streq(ero2->name, c->name))
+ break;
#endif
- bspp = (ero == NULL)
- ? bare_shunt_ptr(&sr->this.client, &sr->that.client, sr->this.protocol)
- : NULL;
+ bspp = (ero == NULL)
+ ? bare_shunt_ptr(&sr->this.client, &sr->that.client, sr->this.protocol)
+ : NULL;
- /* install the eroute */
+ /* install the eroute */
- passert(bspp == NULL || ero == NULL); /* only one non-NULL */
+ passert(bspp == NULL || ero == NULL); /* only one non-NULL */
- if (bspp != NULL || ero != NULL)
- {
- /* We're replacing an eroute */
+ if (bspp != NULL || ero != NULL)
+ {
+ /* We're replacing an eroute */
- /* if no state provided, then install a shunt for later */
- if (st == NULL)
- eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
- , ERO_REPLACE, "replace");
- else
- eroute_installed = sag_eroute(st, sr, ERO_REPLACE, "replace");
+ /* if no state provided, then install a shunt for later */
+ if (st == NULL)
+ eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
+ , ERO_REPLACE, "replace");
+ else
+ eroute_installed = sag_eroute(st, sr, ERO_REPLACE, "replace");
#if 0
- /* XXX - MCR. I previously felt that this was a bogus check */
- if (ero != NULL && ero != c && esr != sr)
- {
- /* By elimination, we must be eclipsing ero. Check. */
- passert(ero->kind == CK_TEMPLATE && streq(ero->name, c->name));
- passert(LHAS(LELEM(RT_ROUTED_PROSPECTIVE) | LELEM(RT_ROUTED_ECLIPSED)
- , esr->routing));
- passert(samesubnet(&esr->this.client, &sr->this.client)
- && samesubnet(&esr->that.client, &sr->that.client));
- }
+ /* XXX - MCR. I previously felt that this was a bogus check */
+ if (ero != NULL && ero != c && esr != sr)
+ {
+ /* By elimination, we must be eclipsing ero. Check. */
+ passert(ero->kind == CK_TEMPLATE && streq(ero->name, c->name));
+ passert(LHAS(LELEM(RT_ROUTED_PROSPECTIVE) | LELEM(RT_ROUTED_ECLIPSED)
+ , esr->routing));
+ passert(samesubnet(&esr->this.client, &sr->this.client)
+ && samesubnet(&esr->that.client, &sr->that.client));
+ }
#endif
- /* remember to free bspp iff we make it out of here alive */
- }
- else
- {
- /* we're adding an eroute */
-
- /* if no state provided, then install a shunt for later */
- if (st == NULL)
- eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
- , ERO_ADD, "add");
- else
- eroute_installed = sag_eroute(st, sr, ERO_ADD, "add");
- }
-
- /* notify the firewall of a new tunnel */
-
- if (eroute_installed)
- {
- /* do we have to notify the firewall? Yes, if we are installing
- * a tunnel eroute and the firewall wasn't notified
- * for a previous tunnel with the same clients. Any Previous
- * tunnel would have to be for our connection, so the actual
- * test is simple.
- */
- firewall_notified = st == NULL /* not a tunnel eroute */
- || sr->eroute_owner != SOS_NOBODY /* already notified */
- || do_command(c, sr, "up"); /* go ahead and notify */
- }
-
- /* install the route */
-
- DBG(DBG_CONTROL,
- DBG_log("route_and_eroute: firewall_notified: %s"
- , firewall_notified ? "true" : "false"));
- if (!firewall_notified)
- {
- /* we're in trouble -- don't do routing */
- }
- else if (ro == NULL)
- {
- /* a new route: no deletion required, but preparation is */
- (void) do_command(c, sr, "prepare"); /* just in case; ignore failure */
- route_installed = do_command(c, sr, "route");
- }
- else if (routed(sr->routing)
- || routes_agree(ro, c))
- {
- route_installed = TRUE; /* nothing to be done */
- }
- else
- {
- /* Some other connection must own the route
- * and the route must disagree. But since could_route
- * must have allowed our stealing it, we'll do so.
- *
- * A feature of LINUX allows us to install the new route
- * before deleting the old if the nexthops differ.
- * This reduces the "window of vulnerability" when packets
- * might flow in the clear.
- */
- if (sameaddr(&sr->this.host_nexthop, &esr->this.host_nexthop))
- {
- (void) do_command(ro, sr, "unroute");
- route_installed = do_command(c, sr, "route");
+ /* remember to free bspp iff we make it out of here alive */
}
else
{
- route_installed = do_command(c, sr, "route");
- (void) do_command(ro, sr, "unroute");
+ /* we're adding an eroute */
+
+ /* if no state provided, then install a shunt for later */
+ if (st == NULL)
+ eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
+ , ERO_ADD, "add");
+ else
+ eroute_installed = sag_eroute(st, sr, ERO_ADD, "add");
}
- /* record unrouting */
- if (route_installed)
- {
- do {
- passert(!erouted(rosr->routing));
- rosr->routing = RT_UNROUTED;
+ /* notify the firewall of a new tunnel */
- /* no need to keep old value */
- ro = route_owner(c, &rosr, NULL, NULL);
- } while (ro != NULL);
+ if (eroute_installed)
+ {
+ /* do we have to notify the firewall? Yes, if we are installing
+ * a tunnel eroute and the firewall wasn't notified
+ * for a previous tunnel with the same clients. Any Previous
+ * tunnel would have to be for our connection, so the actual
+ * test is simple.
+ */
+ firewall_notified = st == NULL /* not a tunnel eroute */
+ || sr->eroute_owner != SOS_NOBODY /* already notified */
+ || do_command(c, sr, "up"); /* go ahead and notify */
}
- }
- /* all done -- clean up */
- if (route_installed)
- {
- /* Success! */
+ /* install the route */
- if (bspp != NULL)
+ DBG(DBG_CONTROL,
+ DBG_log("route_and_eroute: firewall_notified: %s"
+ , firewall_notified ? "true" : "false"));
+ if (!firewall_notified)
{
- free_bare_shunt(bspp);
+ /* we're in trouble -- don't do routing */
}
- else if (ero != NULL && ero != c)
+ else if (ro == NULL)
{
- /* check if ero is an ancestor of c. */
- struct connection *ero2;
-
- for (ero2 = c; ero2 != NULL && ero2 != c; ero2 = ero2->policy_next)
- ;
-
- if (ero2 == NULL)
- {
- /* By elimination, we must be eclipsing ero. Checked above. */
- if (ero->spd.routing != RT_ROUTED_ECLIPSED)
- {
- ero->spd.routing = RT_ROUTED_ECLIPSED;
- eclipse_count++;
- }
- }
+ /* a new route: no deletion required, but preparation is */
+ (void) do_command(c, sr, "prepare"); /* just in case; ignore failure */
+ route_installed = do_command(c, sr, "route");
}
-
- if (st == NULL)
+ else if (routed(sr->routing)
+ || routes_agree(ro, c))
{
- passert(sr->eroute_owner == SOS_NOBODY);
- sr->routing = RT_ROUTED_PROSPECTIVE;
+ route_installed = TRUE; /* nothing to be done */
}
else
{
- char cib[CONN_INST_BUF];
- sr->routing = RT_ROUTED_TUNNEL;
+ /* Some other connection must own the route
+ * and the route must disagree. But since could_route
+ * must have allowed our stealing it, we'll do so.
+ *
+ * A feature of LINUX allows us to install the new route
+ * before deleting the old if the nexthops differ.
+ * This reduces the "window of vulnerability" when packets
+ * might flow in the clear.
+ */
+ if (sameaddr(&sr->this.host_nexthop, &esr->this.host_nexthop))
+ {
+ (void) do_command(ro, sr, "unroute");
+ route_installed = do_command(c, sr, "route");
+ }
+ else
+ {
+ route_installed = do_command(c, sr, "route");
+ (void) do_command(ro, sr, "unroute");
+ }
- DBG(DBG_CONTROL,
- DBG_log("route_and_eroute: instance \"%s\"%s, setting eroute_owner {spd=%p,sr=%p} to #%ld (was #%ld) (newest_ipsec_sa=#%ld)"
- , st->st_connection->name
- , (fmt_conn_instance(st->st_connection, cib), cib)
- , &st->st_connection->spd, sr
- , st->st_serialno
- , sr->eroute_owner
- , st->st_connection->newest_ipsec_sa));
- sr->eroute_owner = st->st_serialno;
- }
+ /* record unrouting */
+ if (route_installed)
+ {
+ do {
+ passert(!erouted(rosr->routing));
+ rosr->routing = RT_UNROUTED;
- return TRUE;
- }
- else
- {
- /* Failure! Unwind our work. */
- if (firewall_notified && sr->eroute_owner == SOS_NOBODY)
- (void) do_command(c, sr, "down");
+ /* no need to keep old value */
+ ro = route_owner(c, &rosr, NULL, NULL);
+ } while (ro != NULL);
+ }
+ }
- if (eroute_installed)
+ /* all done -- clean up */
+ if (route_installed)
{
- /* Restore original eroute, if we can.
- * Since there is nothing much to be done if the restoration
- * fails, ignore success or failure.
- */
- if (bspp != NULL)
- {
- /* Restore old bare_shunt.
- * I don't think that this case is very likely.
- * Normally a bare shunt would have been assigned
- * to a connection before we've gotten this far.
- */
- struct bare_shunt *bs = *bspp;
-
- (void) raw_eroute(&bs->said.dst /* should be useless */
- , &bs->ours
- , &bs->said.dst /* should be useless */
- , &bs->his
- , bs->said.spi /* network order */
- , SA_INT
- , SADB_X_SATYPE_INT
- , 0
- , null_proto_info
- , SHUNT_PATIENCE
- , ERO_REPLACE, "restore");
- }
- else if (ero != NULL)
- {
- /* restore ero's former glory */
- if (esr->eroute_owner == SOS_NOBODY)
+ /* Success! */
+
+ if (bspp != NULL)
{
- /* note: normal or eclipse case */
- (void) shunt_eroute(ero, esr
- , esr->routing, ERO_REPLACE, "restore");
+ free_bare_shunt(bspp);
}
- else
+ else if (ero != NULL && ero != c)
{
- /* Try to find state that owned eroute.
- * Don't do anything if it cannot be found.
- * This case isn't likely since we don't run
- * the updown script when replacing a SA group
- * with its successor (for the same conn).
- */
- struct state *ost = state_with_serialno(esr->eroute_owner);
-
- if (ost != NULL)
- (void) sag_eroute(ost, esr, ERO_REPLACE, "restore");
+ /* check if ero is an ancestor of c. */
+ struct connection *ero2;
+
+ for (ero2 = c; ero2 != NULL && ero2 != c; ero2 = ero2->policy_next)
+ ;
+
+ if (ero2 == NULL)
+ {
+ /* By elimination, we must be eclipsing ero. Checked above. */
+ if (ero->spd.routing != RT_ROUTED_ECLIPSED)
+ {
+ ero->spd.routing = RT_ROUTED_ECLIPSED;
+ eclipse_count++;
+ }
+ }
}
- }
- else
- {
- /* there was no previous eroute: delete whatever we installed */
+
if (st == NULL)
- (void) shunt_eroute(c, sr
- , sr->routing, ERO_DELETE, "delete");
+ {
+ passert(sr->eroute_owner == SOS_NOBODY);
+ sr->routing = RT_ROUTED_PROSPECTIVE;
+ }
else
- (void) sag_eroute(st, sr
- , ERO_DELETE, "delete");
- }
+ {
+ char cib[CONN_INST_BUF];
+ sr->routing = RT_ROUTED_TUNNEL;
+
+ DBG(DBG_CONTROL,
+ DBG_log("route_and_eroute: instance \"%s\"%s, setting eroute_owner {spd=%p,sr=%p} to #%ld (was #%ld) (newest_ipsec_sa=#%ld)"
+ , st->st_connection->name
+ , (fmt_conn_instance(st->st_connection, cib), cib)
+ , &st->st_connection->spd, sr
+ , st->st_serialno
+ , sr->eroute_owner
+ , st->st_connection->newest_ipsec_sa));
+ sr->eroute_owner = st->st_serialno;
+ }
+
+ return TRUE;
}
+ else
+ {
+ /* Failure! Unwind our work. */
+ if (firewall_notified && sr->eroute_owner == SOS_NOBODY)
+ (void) do_command(c, sr, "down");
- return FALSE;
- }
+ if (eroute_installed)
+ {
+ /* Restore original eroute, if we can.
+ * Since there is nothing much to be done if the restoration
+ * fails, ignore success or failure.
+ */
+ if (bspp != NULL)
+ {
+ /* Restore old bare_shunt.
+ * I don't think that this case is very likely.
+ * Normally a bare shunt would have been assigned
+ * to a connection before we've gotten this far.
+ */
+ struct bare_shunt *bs = *bspp;
+
+ (void) raw_eroute(&bs->said.dst /* should be useless */
+ , &bs->ours
+ , &bs->said.dst /* should be useless */
+ , &bs->his
+ , bs->said.spi /* network order */
+ , SA_INT
+ , SADB_X_SATYPE_INT
+ , 0
+ , null_proto_info
+ , SHUNT_PATIENCE
+ , ERO_REPLACE, "restore");
+ }
+ else if (ero != NULL)
+ {
+ /* restore ero's former glory */
+ if (esr->eroute_owner == SOS_NOBODY)
+ {
+ /* note: normal or eclipse case */
+ (void) shunt_eroute(ero, esr
+ , esr->routing, ERO_REPLACE, "restore");
+ }
+ else
+ {
+ /* Try to find state that owned eroute.
+ * Don't do anything if it cannot be found.
+ * This case isn't likely since we don't run
+ * the updown script when replacing a SA group
+ * with its successor (for the same conn).
+ */
+ struct state *ost = state_with_serialno(esr->eroute_owner);
+
+ if (ost != NULL)
+ (void) sag_eroute(ost, esr, ERO_REPLACE, "restore");
+ }
+ }
+ else
+ {
+ /* there was no previous eroute: delete whatever we installed */
+ if (st == NULL)
+ (void) shunt_eroute(c, sr
+ , sr->routing, ERO_DELETE, "delete");
+ else
+ (void) sag_eroute(st, sr
+ , ERO_DELETE, "delete");
+ }
+ }
+
+ return FALSE;
+ }
#else /* !KLIPS */
- return TRUE;
+ return TRUE;
#endif /* !KLIPS */
}
-bool
-install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
+bool install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
{
#ifdef KLIPS
- struct spd_route *sr;
-
- DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() for #%ld: %s"
- , st->st_serialno
- , inbound_also?
- "inbound and outbound" : "outbound only"));
-
- switch (could_route(st->st_connection))
- {
- case route_easy:
- case route_nearconflict:
- break;
+ struct spd_route *sr;
- default:
- return FALSE;
- }
+ DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() for #%ld: %s"
+ , st->st_serialno
+ , inbound_also?
+ "inbound and outbound" : "outbound only"));
- /* (attempt to) actually set up the SA group */
- if ((inbound_also && !setup_half_ipsec_sa(st, TRUE))
- || !setup_half_ipsec_sa(st, FALSE))
- return FALSE;
+ switch (could_route(st->st_connection))
+ {
+ case route_easy:
+ case route_nearconflict:
+ break;
- for (sr = &st->st_connection->spd; sr != NULL; sr = sr->next)
- {
- DBG(DBG_CONTROL, DBG_log("sr for #%ld: %s"
- , st->st_serialno
- , enum_name(&routing_story, sr->routing)));
+ default:
+ return FALSE;
+ }
- /*
- * if the eroute owner is not us, then make it us.
- * See test co-terminal-02, pluto-rekey-01, pluto-unit-02/oppo-twice
- */
- pexpect(sr->eroute_owner == SOS_NOBODY
- || sr->routing >= RT_ROUTED_TUNNEL);
+ /* (attempt to) actually set up the SA group */
+ if ((inbound_also && !setup_half_ipsec_sa(st, TRUE))
+ || !setup_half_ipsec_sa(st, FALSE))
+ return FALSE;
- if (sr->eroute_owner != st->st_serialno
- && sr->routing != RT_UNROUTED_KEYED)
+ for (sr = &st->st_connection->spd; sr != NULL; sr = sr->next)
{
- if (!route_and_eroute(st->st_connection, sr, st))
- {
- delete_ipsec_sa(st, FALSE);
- /* XXX go and unroute any SRs that were successfully
- * routed already.
+ DBG(DBG_CONTROL, DBG_log("sr for #%ld: %s"
+ , st->st_serialno
+ , enum_name(&routing_story, sr->routing)));
+
+ /*
+ * if the eroute owner is not us, then make it us.
+ * See test co-terminal-02, pluto-rekey-01, pluto-unit-02/oppo-twice
*/
- return FALSE;
- }
+ pexpect(sr->eroute_owner == SOS_NOBODY
+ || sr->routing >= RT_ROUTED_TUNNEL);
+
+ if (sr->eroute_owner != st->st_serialno
+ && sr->routing != RT_UNROUTED_KEYED)
+ {
+ if (!route_and_eroute(st->st_connection, sr, st))
+ {
+ delete_ipsec_sa(st, FALSE);
+ /* XXX go and unroute any SRs that were successfully
+ * routed already.
+ */
+ return FALSE;
+ }
+ }
}
- }
#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() %s"
- , inbound_also? "inbound and oubound" : "outbound only"));
+ DBG(DBG_CONTROL, DBG_log("install_ipsec_sa() %s"
+ , inbound_also? "inbound and oubound" : "outbound only"));
- switch (could_route(st->st_connection))
- {
- case route_easy:
- case route_nearconflict:
- break;
+ switch (could_route(st->st_connection))
+ {
+ case route_easy:
+ case route_nearconflict:
+ break;
- default:
- return FALSE;
- }
+ default:
+ return FALSE;
+ }
#endif /* !KLIPS */
- return TRUE;
+ return TRUE;
}
/* delete an IPSEC SA.
* we may not succeed, but we bull ahead anyway because
* we cannot do anything better by recognizing failure
*/
-void
-delete_ipsec_sa(struct state *st USED_BY_KLIPS, bool inbound_only USED_BY_KLIPS)
+void delete_ipsec_sa(struct state *st USED_BY_KLIPS,
+ bool inbound_only USED_BY_KLIPS)
{
#ifdef KLIPS
- if (!inbound_only)
- {
- /* If the state is the eroute owner, we must adjust
- * the routing for the connection.
- */
- struct connection *c = st->st_connection;
- struct spd_route *sr;
-
- passert(st->st_connection);
-
- for (sr = &c->spd; sr; sr = sr->next)
+ if (!inbound_only)
{
- if (sr->eroute_owner == st->st_serialno
- && sr->routing == RT_ROUTED_TUNNEL)
- {
- sr->eroute_owner = SOS_NOBODY;
-
- /* Routing should become RT_ROUTED_FAILURE,
- * but if POLICY_FAIL_NONE, then we just go
- * right back to RT_ROUTED_PROSPECTIVE as if no
- * failure happened.
+ /* If the state is the eroute owner, we must adjust
+ * the routing for the connection.
*/
- sr->routing = (c->policy & POLICY_FAIL_MASK) == POLICY_FAIL_NONE
- ? RT_ROUTED_PROSPECTIVE : RT_ROUTED_FAILURE;
+ struct connection *c = st->st_connection;
+ struct spd_route *sr;
- (void) do_command(c, sr, "down");
- if ((c->policy & POLICY_DONT_REKEY)
- && c->kind == CK_INSTANCE)
- {
- /* in this special case, even if the connection
- * is still alive (due to an ISAKMP SA),
- * we get rid of routing.
- * Even though there is still an eroute, the c->routing
- * setting will convince unroute_connection to delete it.
- * unroute_connection would be upset if c->routing == RT_ROUTED_TUNNEL
- */
- unroute_connection(c);
- }
- else
+ passert(st->st_connection);
+
+ for (sr = &c->spd; sr; sr = sr->next)
{
- (void) shunt_eroute(c, sr, sr->routing, ERO_REPLACE, "replace with shunt");
+ if (sr->eroute_owner == st->st_serialno
+ && sr->routing == RT_ROUTED_TUNNEL)
+ {
+ sr->eroute_owner = SOS_NOBODY;
+
+ /* Routing should become RT_ROUTED_FAILURE,
+ * but if POLICY_FAIL_NONE, then we just go
+ * right back to RT_ROUTED_PROSPECTIVE as if no
+ * failure happened.
+ */
+ sr->routing = (c->policy & POLICY_FAIL_MASK) == POLICY_FAIL_NONE
+ ? RT_ROUTED_PROSPECTIVE : RT_ROUTED_FAILURE;
+
+ (void) do_command(c, sr, "down");
+ if ((c->policy & POLICY_DONT_REKEY)
+ && c->kind == CK_INSTANCE)
+ {
+ /* in this special case, even if the connection
+ * is still alive (due to an ISAKMP SA),
+ * we get rid of routing.
+ * Even though there is still an eroute, the c->routing
+ * setting will convince unroute_connection to delete it.
+ * unroute_connection would be upset if c->routing == RT_ROUTED_TUNNEL
+ */
+ unroute_connection(c);
+ }
+ else
+ {
+ (void) shunt_eroute(c, sr, sr->routing, ERO_REPLACE, "replace with shunt");
+ }
+ }
}
- }
+ (void) teardown_half_ipsec_sa(st, FALSE);
}
- (void) teardown_half_ipsec_sa(st, FALSE);
- }
- (void) teardown_half_ipsec_sa(st, TRUE);
+ (void) teardown_half_ipsec_sa(st, TRUE);
#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("if I knew how, I'd eroute() and teardown_ipsec_sa()"));
+ DBG(DBG_CONTROL, DBG_log("if I knew how, I'd eroute() and teardown_ipsec_sa()"));
#endif /* !KLIPS */
}
#ifdef KLIPS
static bool update_nat_t_ipsec_esp_sa (struct state *st, bool inbound)
{
- struct connection *c = st->st_connection;
- char text_said[SATOT_BUF];
- struct kernel_sa sa;
- ip_address
- src = inbound? c->spd.that.host_addr : c->spd.this.host_addr,
- dst = inbound? c->spd.this.host_addr : c->spd.that.host_addr;
-
- ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
-
- u_int16_t
- natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port,
- natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
-
- set_text_said(text_said, &dst, esp_spi, SA_ESP);
-
- memset(&sa, 0, sizeof(sa));
- sa.spi = esp_spi;
- sa.src = &src;
- sa.dst = &dst;
- sa.text_said = text_said;
- sa.authalg = alg_info_esp_aa2sadb(st->st_esp.attrs.auth);
- sa.natt_sport = natt_sport;
- sa.natt_dport = natt_dport;
- sa.transid = st->st_esp.attrs.transid;
-
- return kernel_ops->add_sa(&sa, TRUE);
+ struct connection *c = st->st_connection;
+ char text_said[SATOT_BUF];
+ struct kernel_sa sa;
+ ip_address
+ src = inbound? c->spd.that.host_addr : c->spd.this.host_addr,
+ dst = inbound? c->spd.this.host_addr : c->spd.that.host_addr;
+
+ ipsec_spi_t esp_spi = inbound? st->st_esp.our_spi : st->st_esp.attrs.spi;
+
+ u_int16_t
+ natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port,
+ natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
+
+ set_text_said(text_said, &dst, esp_spi, SA_ESP);
+
+ memset(&sa, 0, sizeof(sa));
+ sa.spi = esp_spi;
+ sa.src = &src;
+ sa.dst = &dst;
+ sa.text_said = text_said;
+ sa.authalg = alg_info_esp_aa2sadb(st->st_esp.attrs.auth);
+ sa.natt_sport = natt_sport;
+ sa.natt_dport = natt_dport;
+ sa.transid = st->st_esp.attrs.transid;
+
+ return kernel_ops->add_sa(&sa, TRUE);
}
#endif
bool update_ipsec_sa (struct state *st USED_BY_KLIPS)
{
#ifdef KLIPS
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- if (st->st_esp.present && (
- (!update_nat_t_ipsec_esp_sa (st, TRUE)) ||
- (!update_nat_t_ipsec_esp_sa (st, FALSE))))
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
{
- return FALSE;
+ if (st->st_esp.present && (
+ (!update_nat_t_ipsec_esp_sa (st, TRUE)) ||
+ (!update_nat_t_ipsec_esp_sa (st, FALSE))))
+ {
+ return FALSE;
+ }
}
- }
- else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
- {
- if (st->st_esp.present && !update_nat_t_ipsec_esp_sa (st, FALSE))
+ else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
{
- return FALSE;
+ if (st->st_esp.present && !update_nat_t_ipsec_esp_sa (st, FALSE))
+ {
+ return FALSE;
+ }
}
- }
- else
- {
- DBG_log("assert failed at %s:%d st_state=%d", __FILE__, __LINE__, st->st_state);
- return FALSE;
- }
- return TRUE;
+ else
+ {
+ DBG_log("assert failed at %s:%d st_state=%d", __FILE__, __LINE__, st->st_state);
+ return FALSE;
+ }
+ return TRUE;
#else /* !KLIPS */
- DBG(DBG_CONTROL, DBG_log("if I knew how, I'd update_ipsec_sa()"));
- return TRUE;
+ DBG(DBG_CONTROL, DBG_log("if I knew how, I'd update_ipsec_sa()"));
+ return TRUE;
#endif /* !KLIPS */
}
@@ -2890,106 +2872,105 @@ bool update_ipsec_sa (struct state *st USED_BY_KLIPS)
* If FALSE, DPD is not necessary. We also return TRUE for errors, as they
* could mean that the SA is broken and needs to be replace anyway.
*/
-bool
-was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
+bool was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
{
- static const char procname[] = "/proc/net/ipsec_spi";
- FILE *f;
- char buf[1024];
- u_int bytes;
- int ret = TRUE;
-
- passert(st != NULL);
-
- f = fopen(procname, "r");
- if (f == NULL)
- {
- /* Can't open the file, perhaps were are on 26sec? */
- time_t use_time;
-
- if (get_sa_info(st, TRUE, &bytes, &use_time)
- && use_time != UNDEFINED_TIME)
- {
- *idle_time = time(NULL) - use_time;
- ret = *idle_time >= idle_max;
- }
- }
- else
- {
- while (f != NULL)
- {
- char *line;
- char text_said[SATOT_BUF];
- u_int8_t proto = 0;
- ip_address dst;
- ip_said said;
- ipsec_spi_t spi = 0;
- static const char idle[] = "idle=";
-
- dst = st->st_connection->spd.this.host_addr; /* inbound SA */
- if (st->st_ah.present)
- {
- proto = SA_AH;
- spi = st->st_ah.our_spi;
- }
- if (st->st_esp.present)
- {
- proto = SA_ESP;
- spi = st->st_esp.our_spi;
- }
-
- if (proto == 0 && spi == 0)
- {
- ret = TRUE;
- break;
- }
-
- initsaid(&dst, spi, proto, &said);
- satot(&said, 'x', text_said, SATOT_BUF);
+ static const char procname[] = "/proc/net/ipsec_spi";
+ FILE *f;
+ char buf[1024];
+ u_int bytes;
+ int ret = TRUE;
- line = fgets(buf, sizeof(buf), f);
- if (line == NULL)
- {
- /* Reached end of list */
- ret = TRUE;
- break;
- }
+ passert(st != NULL);
- if (strncmp(line, text_said, strlen(text_said)) == 0)
- {
- /* we found a match, now try to find idle= */
- char *p = strstr(line, idle);
+ f = fopen(procname, "r");
+ if (f == NULL)
+ {
+ /* Can't open the file, perhaps were are on 26sec? */
+ time_t use_time;
- if (p == NULL)
+ if (get_sa_info(st, TRUE, &bytes, &use_time)
+ && use_time != UNDEFINED_TIME)
{
- /* SAs which haven't been used yet don't have it */
- ret = TRUE; /* it didn't have traffic */
- break;
+ *idle_time = time(NULL) - use_time;
+ ret = *idle_time >= idle_max;
}
- p += sizeof(idle)-1;
- if (*p == '\0')
- {
- ret = TRUE; /* be paranoid */
- break;
- }
- if (sscanf(p, "%d", (int *) idle_time) <= 0)
- {
- ret = TRUE;
- break;
- }
- if (*idle_time >= idle_max)
- {
- ret = TRUE;
- break;
- }
- else
+ }
+ else
+ {
+ while (f != NULL)
{
- ret = FALSE;
- break;
+ char *line;
+ char text_said[SATOT_BUF];
+ u_int8_t proto = 0;
+ ip_address dst;
+ ip_said said;
+ ipsec_spi_t spi = 0;
+ static const char idle[] = "idle=";
+
+ dst = st->st_connection->spd.this.host_addr; /* inbound SA */
+ if (st->st_ah.present)
+ {
+ proto = SA_AH;
+ spi = st->st_ah.our_spi;
+ }
+ if (st->st_esp.present)
+ {
+ proto = SA_ESP;
+ spi = st->st_esp.our_spi;
+ }
+
+ if (proto == 0 && spi == 0)
+ {
+ ret = TRUE;
+ break;
+ }
+
+ initsaid(&dst, spi, proto, &said);
+ satot(&said, 'x', text_said, SATOT_BUF);
+
+ line = fgets(buf, sizeof(buf), f);
+ if (line == NULL)
+ {
+ /* Reached end of list */
+ ret = TRUE;
+ break;
+ }
+
+ if (strneq(line, text_said, strlen(text_said)))
+ {
+ /* we found a match, now try to find idle= */
+ char *p = strstr(line, idle);
+
+ if (p == NULL)
+ {
+ /* SAs which haven't been used yet don't have it */
+ ret = TRUE; /* it didn't have traffic */
+ break;
+ }
+ p += sizeof(idle)-1;
+ if (*p == '\0')
+ {
+ ret = TRUE; /* be paranoid */
+ break;
+ }
+ if (sscanf(p, "%d", (int *) idle_time) <= 0)
+ {
+ ret = TRUE;
+ break;
+ }
+ if (*idle_time >= idle_max)
+ {
+ ret = TRUE;
+ break;
+ }
+ else
+ {
+ ret = FALSE;
+ break;
+ }
+ }
}
- }
+ fclose(f);
}
- fclose(f);
- }
- return ret;
+ return ret;
}
diff --git a/src/pluto/kernel.h b/src/pluto/kernel.h
index fdc2bf0a8..06850abfd 100644
--- a/src/pluto/kernel.h
+++ b/src/pluto/kernel.h
@@ -10,13 +10,11 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include "connections.h"
-extern bool no_klips; /* don't actually use KLIPS */
+extern bool no_klips; /* don't actually use KLIPS */
extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
#ifdef KLIPS
@@ -28,96 +26,96 @@ extern bool can_do_IPcomp; /* can system actually perform IPCOMP? */
* limited to appropriate source and destination addresses.
*/
-#define ERO_MASK 0xFF
-#define ERO_FLAG_SHIFT 8
+#define ERO_MASK 0xFF
+#define ERO_FLAG_SHIFT 8
-#define ERO_DELETE SADB_X_DELFLOW
-#define ERO_ADD SADB_X_ADDFLOW
-#define ERO_REPLACE (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
-#define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
-#define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
+#define ERO_DELETE SADB_X_DELFLOW
+#define ERO_ADD SADB_X_ADDFLOW
+#define ERO_REPLACE (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
+#define ERO_ADD_INBOUND (SADB_X_ADDFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
+#define ERO_DEL_INBOUND (SADB_X_DELFLOW | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
struct pfkey_proto_info {
- int proto;
- int encapsulation;
- unsigned reqid;
+ int proto;
+ int encapsulation;
+ unsigned reqid;
};
struct sadb_msg;
struct kernel_sa {
- const ip_address *src;
- const ip_address *dst;
+ const ip_address *src;
+ const ip_address *dst;
- const ip_subnet *src_client;
- const ip_subnet *dst_client;
+ const ip_subnet *src_client;
+ const ip_subnet *dst_client;
- ipsec_spi_t spi;
- unsigned proto;
- unsigned satype;
- unsigned transport_proto;
- unsigned replay_window;
- unsigned reqid;
+ ipsec_spi_t spi;
+ unsigned proto;
+ unsigned satype;
+ unsigned transport_proto;
+ unsigned replay_window;
+ unsigned reqid;
- unsigned authalg;
- unsigned authkeylen;
- char *authkey;
+ unsigned authalg;
+ unsigned authkeylen;
+ char *authkey;
- unsigned encalg;
- unsigned enckeylen;
- char *enckey;
+ unsigned encalg;
+ unsigned enckeylen;
+ char *enckey;
- unsigned compalg;
+ unsigned compalg;
- int encapsulation;
+ int encapsulation;
- u_int16_t natt_sport, natt_dport;
- u_int8_t transid, natt_type;
- ip_address *natt_oa;
+ u_int16_t natt_sport, natt_dport;
+ u_int8_t transid, natt_type;
+ ip_address *natt_oa;
- const char *text_said;
+ const char *text_said;
};
struct kernel_ops {
- enum {
- KERNEL_TYPE_NONE,
- KERNEL_TYPE_KLIPS,
- KERNEL_TYPE_LINUX,
- } type;
- bool inbound_eroute;
- bool policy_lifetime;
- int *async_fdp;
-
- void (*init)(void);
- void (*pfkey_register)(void);
- void (*pfkey_register_response)(const struct sadb_msg *msg);
- void (*process_queue)(void);
- void (*process_msg)(void);
- bool (*raw_eroute)(const ip_address *this_host,
- const ip_subnet *this_client,
- const ip_address *that_host,
- const ip_subnet *that_client,
- ipsec_spi_t spi,
- unsigned int satype,
- unsigned int transport_proto,
- const struct pfkey_proto_info *proto_info,
- time_t use_lifetime,
- unsigned int op,
- const char *text_said);
- bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
- time_t *use_time);
- bool (*add_sa)(const struct kernel_sa *sa, bool replace);
- bool (*grp_sa)(const struct kernel_sa *sa_outer,
- const struct kernel_sa *sa_inner);
- bool (*del_sa)(const struct kernel_sa *sa);
- bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
- ipsec_spi_t (*get_spi)(const ip_address *src,
- const ip_address *dst,
- int proto,
- bool tunnel_mode,
- unsigned reqid,
- ipsec_spi_t min,
- ipsec_spi_t max,
- const char *text_said);
+ enum {
+ KERNEL_TYPE_NONE,
+ KERNEL_TYPE_KLIPS,
+ KERNEL_TYPE_LINUX,
+ } type;
+ bool inbound_eroute;
+ bool policy_lifetime;
+ int *async_fdp;
+
+ void (*init)(void);
+ void (*pfkey_register)(void);
+ void (*pfkey_register_response)(const struct sadb_msg *msg);
+ void (*process_queue)(void);
+ void (*process_msg)(void);
+ bool (*raw_eroute)(const ip_address *this_host,
+ const ip_subnet *this_client,
+ const ip_address *that_host,
+ const ip_subnet *that_client,
+ ipsec_spi_t spi,
+ unsigned int satype,
+ unsigned int transport_proto,
+ const struct pfkey_proto_info *proto_info,
+ time_t use_lifetime,
+ unsigned int op,
+ const char *text_said);
+ bool (*get_policy)(const struct kernel_sa *sa, bool inbound,
+ time_t *use_time);
+ bool (*add_sa)(const struct kernel_sa *sa, bool replace);
+ bool (*grp_sa)(const struct kernel_sa *sa_outer,
+ const struct kernel_sa *sa_inner);
+ bool (*del_sa)(const struct kernel_sa *sa);
+ bool (*get_sa)(const struct kernel_sa *sa, u_int *bytes);
+ ipsec_spi_t (*get_spi)(const ip_address *src,
+ const ip_address *dst,
+ int proto,
+ bool tunnel_mode,
+ unsigned reqid,
+ ipsec_spi_t min,
+ ipsec_spi_t max,
+ const char *text_said);
};
@@ -126,13 +124,13 @@ extern const struct kernel_ops *kernel_ops;
/* information from /proc/net/ipsec_eroute */
struct eroute_info {
- unsigned long count;
- ip_subnet ours;
- ip_subnet his;
- ip_address dst;
- ip_said said;
- int transport_proto;
- struct eroute_info *next;
+ unsigned long count;
+ ip_subnet ours;
+ ip_subnet his;
+ ip_address dst;
+ ip_said said;
+ int transport_proto;
+ struct eroute_info *next;
};
extern struct eroute_info *orphaned_holds;
@@ -144,13 +142,13 @@ extern void show_shunt_status(void);
* Is there a PF_KEY equivalent?
*/
#ifndef EM_MAXRELSPIS
-# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
+# define EM_MAXRELSPIS 4 /* AH ESP IPCOMP IPIP */
#endif
extern void record_and_initiate_opportunistic(const ip_subnet *
- , const ip_subnet *
- , int transport_proto
- , const char *why);
+ , const ip_subnet *
+ , int transport_proto
+ , const char *why);
extern void init_kernel(void);
@@ -160,39 +158,39 @@ extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);
extern bool has_bare_hold(const ip_address *src, const ip_address *dst
- , int transport_proto);
+ , int transport_proto);
extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst
- , policy_prio_t policy_prio
- , ipsec_spi_t shunt_spi /* in host order! */
- , bool repl
- , unsigned int transport_proto
- , const char *why);
+ , policy_prio_t policy_prio
+ , ipsec_spi_t shunt_spi /* in host order! */
+ , bool repl
+ , unsigned int transport_proto
+ , const char *why);
extern bool assign_hold(struct connection *c
- , struct spd_route *sr
- , int transport_proto
- , const ip_address *src, const ip_address *dst);
+ , struct spd_route *sr
+ , int transport_proto
+ , const ip_address *src, const ip_address *dst);
extern ipsec_spi_t shunt_policy_spi(struct connection *c, bool prospective);
-struct state; /* forward declaration of tag */
+struct state; /* forward declaration of tag */
extern ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid
- , int proto
- , struct spd_route *sr
- , bool tunnel_mode);
+ , int proto
+ , struct spd_route *sr
+ , bool tunnel_mode);
extern ipsec_spi_t get_my_cpi(struct spd_route *sr, bool tunnel_mode);
extern bool install_inbound_ipsec_sa(struct state *st);
extern bool install_ipsec_sa(struct state *st, bool inbound_also);
extern void delete_ipsec_sa(struct state *st, bool inbound_only);
extern bool route_and_eroute(struct connection *c
- , struct spd_route *sr
- , struct state *st);
+ , struct spd_route *sr
+ , struct state *st);
extern bool was_eroute_idle(struct state *st, time_t idle_max
- , time_t *idle_time);
+ , time_t *idle_time);
extern bool get_sa_info(struct state *st, bool inbound, u_int *bytes
- , time_t *use_time);
+ , time_t *use_time);
extern bool update_ipsec_sa(struct state *st);
diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c
index 571d9cc9b..1590bdf02 100644
--- a/src/pluto/kernel_alg.c
+++ b/src/pluto/kernel_alg.c
@@ -1,5 +1,6 @@
/* Kernel runtime algorithm handling interface
- * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_alg.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +26,6 @@
#include <pfkey.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "constants.h"
#include "defs.h"
@@ -38,22 +36,10 @@
#include "kernel.h"
#include "kernel_alg.h"
#include "alg_info.h"
-
-#ifndef NO_PLUTO
#include "log.h"
#include "whack.h"
#include "db_ops.h"
-#else
-/*
- * macros/functions for compilation without pluto (eg: spi for manual conns)
- */
-extern int debug;
-#include <assert.h>
-#define passert(x) assert(x)
-#define DBG(cond, action) { if (debug) { action ; } }
-#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args);
-#define plog(x, args...) fprintf(stderr, x "\n" , ##args);
-#endif /* NO_PLUTO */
+
/* ALG storage */
static struct sadb_alg esp_aalg[SADB_AALG_MAX+1];
static struct sadb_alg esp_ealg[SADB_EALG_MAX+1];
@@ -62,714 +48,669 @@ static int esp_aalg_num = 0;
#define ESP_EALG_PRESENT(algo) (((algo)<=SADB_EALG_MAX)&&(esp_ealg[(algo)].sadb_alg_id==(algo)))
#define ESP_EALG_FOR_EACH_UPDOWN(algo) \
- for (algo=SADB_EALG_MAX; algo >0 ; algo--) \
- if (ESP_EALG_PRESENT(algo))
+ for (algo=SADB_EALG_MAX; algo >0 ; algo--) \
+ if (ESP_EALG_PRESENT(algo))
#define ESP_AALG_PRESENT(algo) ((algo<=SADB_AALG_MAX)&&(esp_aalg[(algo)].sadb_alg_id==(algo)))
#define ESP_AALG_FOR_EACH_UPDOWN(algo) \
- for (algo=SADB_AALG_MAX; algo >0 ; algo--) \
- if (ESP_AALG_PRESENT(algo))
+ for (algo=SADB_AALG_MAX; algo >0 ; algo--) \
+ if (ESP_AALG_PRESENT(algo))
-static struct sadb_alg*
-sadb_alg_ptr (int satype, int exttype, int alg_id, int rw)
+static struct sadb_alg* sadb_alg_ptr (int satype, int exttype, int alg_id,
+ int rw)
{
- struct sadb_alg *alg_p = NULL;
-
- switch (exttype)
- {
- case SADB_EXT_SUPPORTED_AUTH:
- if (alg_id > SADB_AALG_MAX)
- return NULL;
- break;
- case SADB_EXT_SUPPORTED_ENCRYPT:
- if (alg_id > SADB_EALG_MAX)
- return NULL;
- break;
- default:
- return NULL;
- }
-
- switch (satype)
- {
- case SADB_SATYPE_ESP:
- alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
- &esp_ealg[alg_id] : &esp_aalg[alg_id];
- /* get for write: increment elem count */
- if (rw)
+ struct sadb_alg *alg_p = NULL;
+
+ switch (exttype)
{
- (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
- esp_ealg_num++ : esp_aalg_num++;
+ case SADB_EXT_SUPPORTED_AUTH:
+ if (alg_id > SADB_AALG_MAX)
+ return NULL;
+ break;
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ if (alg_id > SADB_EALG_MAX)
+ return NULL;
+ break;
+ default:
+ return NULL;
}
- break;
- case SADB_SATYPE_AH:
- default:
- return NULL;
- }
-
- return alg_p;
+
+ switch (satype)
+ {
+ case SADB_SATYPE_ESP:
+ alg_p = (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
+ &esp_ealg[alg_id] : &esp_aalg[alg_id];
+ /* get for write: increment elem count */
+ if (rw)
+ {
+ (exttype == SADB_EXT_SUPPORTED_ENCRYPT)?
+ esp_ealg_num++ : esp_aalg_num++;
+ }
+ break;
+ case SADB_SATYPE_AH:
+ default:
+ return NULL;
+ }
+
+ return alg_p;
}
-const struct sadb_alg *
-kernel_alg_sadb_alg_get(int satype, int exttype, int alg_id)
+const struct sadb_alg* kernel_alg_sadb_alg_get(int satype, int exttype,
+ int alg_id)
{
- return sadb_alg_ptr(satype, exttype, alg_id, 0);
+ return sadb_alg_ptr(satype, exttype, alg_id, 0);
}
/*
- * Forget previous registration
+ * Forget previous registration
*/
-static void
-kernel_alg_init(void)
+static void kernel_alg_init(void)
{
- DBG(DBG_KLIPS,
- DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)",
- &esp_aalg, (int)sizeof (esp_aalg),
- &esp_ealg, (int)sizeof (esp_ealg))
- )
- memset (&esp_aalg, 0, sizeof (esp_aalg));
- memset (&esp_ealg, 0, sizeof (esp_ealg));
- esp_ealg_num=esp_aalg_num = 0;
+ DBG(DBG_KLIPS,
+ DBG_log("alg_init(): memset(%p, 0, %d) memset(%p, 0, %d)",
+ &esp_aalg, (int)sizeof (esp_aalg),
+ &esp_ealg, (int)sizeof (esp_ealg))
+ )
+ memset (&esp_aalg, 0, sizeof (esp_aalg));
+ memset (&esp_ealg, 0, sizeof (esp_ealg));
+ esp_ealg_num=esp_aalg_num = 0;
}
-static int
-kernel_alg_add(int satype, int exttype, const struct sadb_alg *sadb_alg)
+static int kernel_alg_add(int satype, int exttype,
+ const struct sadb_alg *sadb_alg)
{
- struct sadb_alg *alg_p = NULL;
- int alg_id = sadb_alg->sadb_alg_id;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d",
- satype, exttype, sadb_alg->sadb_alg_id)
- )
- if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1)))
- return -1;
-
- /* This logic "mimics" KLIPS: first algo implementation will be used */
- if (alg_p->sadb_alg_id)
- {
+ struct sadb_alg *alg_p = NULL;
+ int alg_id = sadb_alg->sadb_alg_id;
+
DBG(DBG_KLIPS,
- DBG_log("kernel_alg_add(): discarding already setup "
- "satype=%d, exttype=%d, alg_id=%d",
- satype, exttype, sadb_alg->sadb_alg_id)
+ DBG_log("kernel_alg_add(): satype=%d, exttype=%d, alg_id=%d",
+ satype, exttype, sadb_alg->sadb_alg_id)
)
- return 0;
- }
- *alg_p = *sadb_alg;
- return 1;
+ if (!(alg_p = sadb_alg_ptr(satype, exttype, alg_id, 1)))
+ return -1;
+
+ /* This logic "mimics" KLIPS: first algo implementation will be used */
+ if (alg_p->sadb_alg_id)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_add(): discarding already setup "
+ "satype=%d, exttype=%d, alg_id=%d",
+ satype, exttype, sadb_alg->sadb_alg_id)
+ )
+ return 0;
+ }
+ *alg_p = *sadb_alg;
+ return 1;
}
-bool
-kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len,
- struct alg_info_esp *alg_info __attribute__((unused)))
+bool kernel_alg_esp_enc_ok(u_int alg_id, u_int key_len,
+ struct alg_info_esp *alg_info __attribute__((unused)))
{
- struct sadb_alg *alg_p = NULL;
-
- /*
- * test #1: encrypt algo must be present
- */
- int ret = ESP_EALG_PRESENT(alg_id);
- if (!ret) goto out;
-
- alg_p = &esp_ealg[alg_id];
-
- /*
- * test #2: if key_len specified, it must be in range
- */
- if (key_len
- && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits))
- {
- plog("kernel_alg_db_add() key_len not in range: alg_id=%d, "
- "key_len=%d, alg_minbits=%d, alg_maxbits=%d"
- , alg_id, key_len
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits);
- ret = FALSE;
- }
+ struct sadb_alg *alg_p = NULL;
+
+ /*
+ * test #1: encrypt algo must be present
+ */
+ int ret = ESP_EALG_PRESENT(alg_id);
+ if (!ret) goto out;
+
+ alg_p = &esp_ealg[alg_id];
+
+ /*
+ * test #2: if key_len specified, it must be in range
+ */
+ if (key_len
+ && (key_len < alg_p->sadb_alg_minbits || key_len > alg_p->sadb_alg_maxbits))
+ {
+ plog("kernel_alg_db_add() key_len not in range: alg_id=%d, "
+ "key_len=%d, alg_minbits=%d, alg_maxbits=%d"
+ , alg_id, key_len
+ , alg_p->sadb_alg_minbits
+ , alg_p->sadb_alg_maxbits);
+ ret = FALSE;
+ }
out:
- if (ret)
- {
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_ok(%d,%d): "
- "alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "res=%d, ret=%d"
- , alg_id, key_len
- , alg_p->sadb_alg_id
- , alg_p->sadb_alg_ivlen
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- , alg_p->sadb_alg_reserved
- , ret);
- )
- }
- else
- {
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len);
- )
- }
- return ret;
+ if (ret)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_esp_enc_ok(%d,%d): "
+ "alg_id=%d, "
+ "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
+ "res=%d, ret=%d"
+ , alg_id, key_len
+ , alg_p->sadb_alg_id
+ , alg_p->sadb_alg_ivlen
+ , alg_p->sadb_alg_minbits
+ , alg_p->sadb_alg_maxbits
+ , alg_p->sadb_alg_reserved
+ , ret);
+ )
+ }
+ else
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_esp_enc_ok(%d,%d): NO", alg_id, key_len);
+ )
+ }
+ return ret;
}
/*
* ML: make F_STRICT logic consider enc,auth algorithms
*/
-#ifndef NO_PLUTO
-bool
-kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg, struct alg_info_esp *alg_info)
+bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg,
+ struct alg_info_esp *alg_info)
{
- int ealg_insecure;
-
- /*
- * key_len passed comes from esp_attrs read from peer
- * For many older algoritms (eg 3DES) this key_len is fixed
- * and get passed as 0.
- * ... then get default key_len
- */
- if (key_len == 0)
- key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE;
-
- /*
- * simple test to toss low key_len, will accept it only
- * if specified in "esp" string
- */
- ealg_insecure = (key_len < 128) ;
-
- if (ealg_insecure
- || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT))
- {
- int i;
- struct esp_info *esp_info;
+ int ealg_insecure;
- if (alg_info)
+ /*
+ * key_len passed comes from esp_attrs read from peer
+ * For many older algoritms (eg 3DES) this key_len is fixed
+ * and get passed as 0.
+ * ... then get default key_len
+ */
+ if (key_len == 0)
+ key_len = kernel_alg_esp_enc_keylen(ealg) * BITS_PER_BYTE;
+
+ /*
+ * simple test to toss low key_len, will accept it only
+ * if specified in "esp" string
+ */
+ ealg_insecure = (key_len < 128) ;
+
+ if (ealg_insecure
+ || (alg_info && alg_info->alg_info_flags & ALG_INFO_F_STRICT))
{
- ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
- {
- if (esp_info->esp_ealg_id == ealg
- && (esp_info->esp_ealg_keylen == 0 || key_len == 0
- || esp_info->esp_ealg_keylen == key_len)
- && esp_info->esp_aalg_id == aalg)
+ int i;
+ struct esp_info *esp_info;
+
+ if (alg_info)
{
- if (ealg_insecure)
- {
- loglog(RC_LOG_SERIOUS
- , "You should NOT use insecure ESP algorithms [%s (%d)]!"
- , enum_name(&esp_transformid_names, ealg), key_len);
- }
- return TRUE;
+ ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
+ {
+ if (esp_info->esp_ealg_id == ealg
+ && (esp_info->esp_ealg_keylen == 0 || key_len == 0
+ || esp_info->esp_ealg_keylen == key_len)
+ && esp_info->esp_aalg_id == aalg)
+ {
+ if (ealg_insecure)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "You should NOT use insecure ESP algorithms [%s (%d)]!"
+ , enum_name(&esp_transformid_names, ealg), key_len);
+ }
+ return TRUE;
+ }
+ }
}
- }
+ plog("IPSec Transform [%s (%d), %s] refused due to %s",
+ enum_name(&esp_transformid_names, ealg), key_len,
+ enum_name(&auth_alg_names, aalg),
+ ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag");
+ return FALSE;
}
- plog("IPSec Transform [%s (%d), %s] refused due to %s",
- enum_name(&esp_transformid_names, ealg), key_len,
- enum_name(&auth_alg_names, aalg),
- ealg_insecure ? "insecure key_len and enc. alg. not listed in \"esp\" string" : "strict flag");
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
-#endif /* NO_PLUTO */
-/*
- * Load kernel_alg arrays from /proc
- * used in manual mode from klips/utils/spi.c
+/**
+ * Load kernel_alg arrays from /proc used in manual mode from klips/utils/spi.c
*/
-int
-kernel_alg_proc_read(void)
+int kernel_alg_proc_read(void)
{
- int satype;
- int supp_exttype;
- int alg_id, ivlen, minbits, maxbits;
- struct sadb_alg sadb_alg;
- int ret;
- char buf[128];
+ int satype;
+ int supp_exttype;
+ int alg_id, ivlen, minbits, maxbits;
+ struct sadb_alg sadb_alg;
+ int ret;
+ char buf[128];
- FILE *fp=fopen("/proc/net/pf_key_supported", "r");
+ FILE *fp=fopen("/proc/net/pf_key_supported", "r");
- if (!fp)
- return -1;
+ if (!fp)
+ return -1;
- kernel_alg_init();
+ kernel_alg_init();
- while (fgets(buf, sizeof(buf), fp))
- {
- if (buf[0] != ' ') /* skip titles */
- continue;
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ if (buf[0] != ' ') /* skip titles */
+ continue;
- sscanf(buf, "%d %d %d %d %d %d"
- ,&satype, &supp_exttype
- , &alg_id, &ivlen
- , &minbits, &maxbits);
+ sscanf(buf, "%d %d %d %d %d %d"
+ ,&satype, &supp_exttype
+ , &alg_id, &ivlen
+ , &minbits, &maxbits);
- switch (satype)
- {
- case SADB_SATYPE_ESP:
- switch(supp_exttype)
- {
- case SADB_EXT_SUPPORTED_AUTH:
- case SADB_EXT_SUPPORTED_ENCRYPT:
- sadb_alg.sadb_alg_id = alg_id;
- sadb_alg.sadb_alg_ivlen = ivlen;
- sadb_alg.sadb_alg_minbits = minbits;
- sadb_alg.sadb_alg_maxbits = maxbits;
- ret = kernel_alg_add(satype, supp_exttype, &sadb_alg);
- DBG(DBG_CRYPT,
- DBG_log("kernel_alg_proc_read() alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "ret=%d"
- , sadb_alg.sadb_alg_id
- , sadb_alg.sadb_alg_ivlen
- , sadb_alg.sadb_alg_minbits
- , sadb_alg.sadb_alg_maxbits
- , ret)
- )
- }
- default:
- continue;
+ switch (satype)
+ {
+ case SADB_SATYPE_ESP:
+ switch(supp_exttype)
+ {
+ case SADB_EXT_SUPPORTED_AUTH:
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ sadb_alg.sadb_alg_id = alg_id;
+ sadb_alg.sadb_alg_ivlen = ivlen;
+ sadb_alg.sadb_alg_minbits = minbits;
+ sadb_alg.sadb_alg_maxbits = maxbits;
+ ret = kernel_alg_add(satype, supp_exttype, &sadb_alg);
+ DBG(DBG_CRYPT,
+ DBG_log("kernel_alg_proc_read() alg_id=%d, "
+ "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
+ "ret=%d"
+ , sadb_alg.sadb_alg_id
+ , sadb_alg.sadb_alg_ivlen
+ , sadb_alg.sadb_alg_minbits
+ , sadb_alg.sadb_alg_maxbits
+ , ret)
+ )
+ }
+ default:
+ continue;
+ }
}
- }
- fclose(fp);
- return 0;
+ fclose(fp);
+ return 0;
}
-/*
- * Load kernel_alg arrays pluto's SADB_REGISTER
- * user by pluto/kernel.c
+/**
+ * Load kernel_alg arrays pluto's SADB_REGISTER user by pluto/kernel.c
*/
-
-void
-kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen)
+void kernel_alg_register_pfkey(const struct sadb_msg *msg_buf, int buflen)
{
- /* Trick: one 'type-mangle-able' pointer to ease offset/assign */
- union {
- const struct sadb_msg *msg;
- const struct sadb_supported *supported;
- const struct sadb_ext *ext;
- const struct sadb_alg *alg;
- const char *ch;
- } sadb;
-
- int satype;
- int msglen;
- int i = 0;
-
- /* Initialize alg arrays */
- kernel_alg_init();
- satype = msg_buf->sadb_msg_satype;
- sadb.msg = msg_buf;
- msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN;
- msglen -= sizeof(struct sadb_msg);
- buflen -= sizeof(struct sadb_msg);
- passert(buflen > 0);
-
- sadb.msg++;
-
- while(msglen)
- {
- int supp_exttype = sadb.supported->sadb_supported_exttype;
- int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
- "sadb_msg_len=%d sadb_supported_len=%d"
- , satype==SADB_SATYPE_ESP? "ESP" : "AH"
- , msg_buf->sadb_msg_len, supp_len)
- )
- sadb.supported++;
- msglen -= supp_len;
- buflen -= supp_len;
- passert(buflen >= 0);
-
- for (supp_len -= sizeof(struct sadb_supported);
- supp_len;
- supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++)
+ /* Trick: one 'type-mangle-able' pointer to ease offset/assign */
+ union {
+ const struct sadb_msg *msg;
+ const struct sadb_supported *supported;
+ const struct sadb_ext *ext;
+ const struct sadb_alg *alg;
+ const char *ch;
+ } sadb;
+
+ int satype;
+ int msglen;
+ int i = 0;
+
+ /* Initialize alg arrays */
+ kernel_alg_init();
+ satype = msg_buf->sadb_msg_satype;
+ sadb.msg = msg_buf;
+ msglen = sadb.msg->sadb_msg_len*IPSEC_PFKEYv2_ALIGN;
+ msglen -= sizeof(struct sadb_msg);
+ buflen -= sizeof(struct sadb_msg);
+ passert(buflen > 0);
+
+ sadb.msg++;
+
+ while(msglen)
{
- int ret = kernel_alg_add(satype, supp_exttype, sadb.alg);
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
- "alg[%d], exttype=%d, satype=%d, alg_id=%d, "
- "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
- "res=%d, ret=%d"
- , satype==SADB_SATYPE_ESP? "ESP" : "AH"
- , i
- , supp_exttype
- , satype
- , sadb.alg->sadb_alg_id
- , sadb.alg->sadb_alg_ivlen
- , sadb.alg->sadb_alg_minbits
- , sadb.alg->sadb_alg_maxbits
- , sadb.alg->sadb_alg_reserved
- , ret)
- )
+ int supp_exttype = sadb.supported->sadb_supported_exttype;
+ int supp_len = sadb.supported->sadb_supported_len*IPSEC_PFKEYv2_ALIGN;
+
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
+ "sadb_msg_len=%d sadb_supported_len=%d"
+ , satype==SADB_SATYPE_ESP? "ESP" : "AH"
+ , msg_buf->sadb_msg_len, supp_len)
+ )
+ sadb.supported++;
+ msglen -= supp_len;
+ buflen -= supp_len;
+ passert(buflen >= 0);
+
+ for (supp_len -= sizeof(struct sadb_supported);
+ supp_len;
+ supp_len -= sizeof(struct sadb_alg), sadb.alg++,i++)
+ {
+ int ret = kernel_alg_add(satype, supp_exttype, sadb.alg);
+
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_register_pfkey(): SADB_SATYPE_%s: "
+ "alg[%d], exttype=%d, satype=%d, alg_id=%d, "
+ "alg_ivlen=%d, alg_minbits=%d, alg_maxbits=%d, "
+ "res=%d, ret=%d"
+ , satype==SADB_SATYPE_ESP? "ESP" : "AH"
+ , i
+ , supp_exttype
+ , satype
+ , sadb.alg->sadb_alg_id
+ , sadb.alg->sadb_alg_ivlen
+ , sadb.alg->sadb_alg_minbits
+ , sadb.alg->sadb_alg_maxbits
+ , sadb.alg->sadb_alg_reserved
+ , ret)
+ )
+ }
}
- }
}
-u_int
-kernel_alg_esp_enc_keylen(u_int alg_id)
+u_int kernel_alg_esp_enc_keylen(u_int alg_id)
{
- u_int keylen = 0;
+ u_int keylen = 0;
- if (!ESP_EALG_PRESENT(alg_id))
- goto none;
+ if (!ESP_EALG_PRESENT(alg_id))
+ goto none;
- keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE;
+ keylen = esp_ealg[alg_id].sadb_alg_maxbits/BITS_PER_BYTE;
- switch (alg_id)
- {
- /*
- * this is veryUgly[TM]
- * Peer should have sent KEY_LENGTH attribute for ESP_AES
- * but if not do force it to 128 instead of using sadb_alg_maxbits
- * from kernel.
- */
- case ESP_AES:
- keylen = 128/BITS_PER_BYTE;
- break;
- }
-
-none:
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_enc_keylen():"
- "alg_id=%d, keylen=%d",
- alg_id, keylen)
- )
- return keylen;
+ switch (alg_id)
+ {
+ /*
+ * this is veryUgly[TM]
+ * Peer should have sent KEY_LENGTH attribute for ESP_AES
+ * but if not do force it to 128 instead of using sadb_alg_maxbits
+ * from kernel.
+ */
+ case ESP_AES:
+ keylen = 128/BITS_PER_BYTE;
+ break;
+ }
+
+none:
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_esp_enc_keylen():"
+ "alg_id=%d, keylen=%d",
+ alg_id, keylen)
+ )
+ return keylen;
}
-struct sadb_alg *
-kernel_alg_esp_sadb_alg(u_int alg_id)
+struct sadb_alg* kernel_alg_esp_sadb_alg(u_int alg_id)
{
- struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id))
- ? &esp_ealg[alg_id] : NULL;
-
- DBG(DBG_KLIPS,
- DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p"
- , alg_id, sadb_alg)
- )
- return sadb_alg;
+ struct sadb_alg *sadb_alg = (ESP_EALG_PRESENT(alg_id))
+ ? &esp_ealg[alg_id] : NULL;
+
+ DBG(DBG_KLIPS,
+ DBG_log("kernel_alg_esp_sadb_alg(): alg_id=%d, sadb_alg=%p"
+ , alg_id, sadb_alg)
+ )
+ return sadb_alg;
}
-#ifndef NO_PLUTO
void kernel_alg_list(void)
{
- u_int sadb_id;
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered ESP Encryption Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++)
- {
- if (ESP_EALG_PRESENT(sadb_id))
+ char buf[BUF_LEN];
+ char *pos;
+ int n, len;
+ u_int sadb_id;
+
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of registered ESP Algorithms:");
+ whack_log(RC_COMMENT, " ");
+
+ pos = buf;
+ *pos = '\0';
+ len = BUF_LEN;
+ for (sadb_id = 1; sadb_id <= SADB_EALG_MAX; sadb_id++)
{
- struct sadb_alg *alg_p = &esp_ealg[sadb_id];
-
- whack_log(RC_COMMENT, "#%-5d %s, blocksize: %d, keylen: %d-%d"
- , sadb_id
- , enum_name(&esp_transformid_names, sadb_id)
- , alg_p->sadb_alg_ivlen
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- );
+ if (ESP_EALG_PRESENT(sadb_id))
+ {
+ n = snprintf(pos, len, " %s",
+ enum_name(&esp_transformid_names, sadb_id));
+ pos += n;
+ len -= n;
+ if (len <= 0)
+ {
+ break;
+ }
+ }
}
- }
-
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of registered ESP Authentication Algorithms:");
- whack_log(RC_COMMENT, " ");
-
- for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++)
- {
- if (ESP_AALG_PRESENT(sadb_id))
+ whack_log(RC_COMMENT, " encryption:%s", buf);
+
+ pos = buf;
+ *pos = '\0';
+ len = BUF_LEN;
+ for (sadb_id = 1; sadb_id <= SADB_AALG_MAX; sadb_id++)
{
- u_int aaid = alg_info_esp_sadb2aa(sadb_id);
- struct sadb_alg *alg_p = &esp_aalg[sadb_id];
-
- whack_log(RC_COMMENT, "#%-5d %s, keylen: %d-%d"
- , aaid
- , enum_name(&auth_alg_names, aaid)
- , alg_p->sadb_alg_minbits
- , alg_p->sadb_alg_maxbits
- );
+ if (ESP_AALG_PRESENT(sadb_id))
+ {
+ u_int aaid = alg_info_esp_sadb2aa(sadb_id);
+
+ n = snprintf(pos, len, " %s", enum_name(&auth_alg_names, aaid));
+ pos += n;
+ len -= n;
+ if (len <= 0)
+ {
+ break;
+ }
+ }
}
- }
+ whack_log(RC_COMMENT, " integrity: %s", buf);
}
-void
-kernel_alg_show_connection(struct connection *c, const char *instance)
+void kernel_alg_show_connection(struct connection *c, const char *instance)
{
- char buf[256];
- struct state *st;
-
- if (c->alg_info_esp)
- {
- alg_info_snprint(buf, sizeof(buf), (struct alg_info *)c->alg_info_esp);
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithms wanted: %s"
- , c->name
- , instance
- , buf);
- }
- if (c->alg_info_esp)
- {
- alg_info_snprint_esp(buf, sizeof(buf), c->alg_info_esp);
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithms loaded: %s"
- , c->name
- , instance
- , buf);
- }
- st = state_with_serialno(c->newest_ipsec_sa);
- if (st && st->st_esp.present)
- whack_log(RC_COMMENT
- , "\"%s\"%s: ESP algorithm newest: %s_%d-%s; pfsgroup=%s"
- , c->name
- , instance
- , enum_show(&esp_transformid_names, st->st_esp.attrs.transid)
- +4 /* strlen("ESP_") */
- , st->st_esp.attrs.key_len
- , enum_show(&auth_alg_names, st->st_esp.attrs.auth)+
- +15 /* strlen("AUTH_ALGORITHM_") */
- , c->policy & POLICY_PFS ?
- c->alg_info_esp->esp_pfsgroup ?
- enum_show(&oakley_group_names,
- c->alg_info_esp->esp_pfsgroup)
- +13 /*strlen("OAKLEY_GROUP_")*/
- : "<Phase1>"
- : "<N/A>"
- );
+ struct state *st = state_with_serialno(c->newest_ipsec_sa);
+
+ if (st && st->st_esp.present)
+ {
+ const char *aalg_name, *pfsgroup_name;
+
+ aalg_name = (c->policy & POLICY_AUTHENTICATE) ?
+ enum_show(&ah_transformid_names, st->st_ah.attrs.transid):
+ enum_show(&auth_alg_names, st->st_esp.attrs.auth);
+
+ pfsgroup_name = (c->policy & POLICY_PFS) ?
+ (c->alg_info_esp->esp_pfsgroup) ?
+ enum_show(&oakley_group_names,
+ c->alg_info_esp->esp_pfsgroup) :
+ "<Phase1>" : "<N/A>";
+
+ if (st->st_esp.attrs.key_len)
+ {
+ whack_log(RC_COMMENT, "\"%s\"%s: ESP%s proposal: %s_%u/%s/%s",
+ c->name, instance,
+ (st->st_ah.present) ? "/AH" : "",
+ enum_show(&esp_transformid_names, st->st_esp.attrs.transid),
+ st->st_esp.attrs.key_len, aalg_name, pfsgroup_name);
+ }
+ else
+ {
+ whack_log(RC_COMMENT, "\"%s\"%s: ESP%s proposal: %s/%s/%s",
+ c->name, instance,
+ (st->st_ah.present) ? "/AH" : "",
+ enum_show(&esp_transformid_names, st->st_esp.attrs.transid),
+ aalg_name, pfsgroup_name);
+ }
+ }
}
-#endif /* NO_PLUTO */
-bool
-kernel_alg_esp_auth_ok(u_int auth,
- struct alg_info_esp *alg_info __attribute__((unused)))
+bool kernel_alg_esp_auth_ok(u_int auth,
+ struct alg_info_esp *alg_info __attribute__((unused)))
{
- return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth));
+ return ESP_AALG_PRESENT(alg_info_esp_aa2sadb(auth));
}
-u_int
-kernel_alg_esp_auth_keylen(u_int auth)
+u_int kernel_alg_esp_auth_keylen(u_int auth)
{
- u_int sadb_aalg = alg_info_esp_aa2sadb(auth);
+ u_int sadb_aalg = alg_info_esp_aa2sadb(auth);
- u_int a_keylen = (sadb_aalg)
- ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE
- : 0;
+ u_int a_keylen = (sadb_aalg)
+ ? esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE
+ : 0;
- DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING,
- DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): "
- "a_keylen=%d", auth, sadb_aalg, a_keylen)
- )
- return a_keylen;
+ DBG(DBG_CONTROL | DBG_CRYPT | DBG_PARSING,
+ DBG_log("kernel_alg_esp_auth_keylen(auth=%d, sadb_aalg=%d): "
+ "a_keylen=%d", auth, sadb_aalg, a_keylen)
+ )
+ return a_keylen;
}
-struct esp_info *
-kernel_alg_esp_info(int transid, int auth)
+struct esp_info* kernel_alg_esp_info(int transid, int auth)
{
- int sadb_aalg, sadb_ealg;
- static struct esp_info ei_buf;
-
- sadb_ealg = transid;
- sadb_aalg = alg_info_esp_aa2sadb(auth);
-
- if (!ESP_EALG_PRESENT(sadb_ealg))
- goto none;
- if (!ESP_AALG_PRESENT(sadb_aalg))
- goto none;
-
- memset(&ei_buf, 0, sizeof (ei_buf));
- ei_buf.transid = transid;
- ei_buf.auth = auth;
-
- /* don't return "default" keylen because this value is used from
- * setup_half_ipsec_sa() to "validate" keylen
- * In effect, enckeylen will be used as "max" value
- */
- ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE;
- ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE;
- ei_buf.encryptalg = sadb_ealg;
- ei_buf.authalg = sadb_aalg;
-
- DBG(DBG_PARSING,
- DBG_log("kernel_alg_esp_info():"
- "transid=%d, auth=%d, ei=%p, "
- "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d",
- transid, auth, &ei_buf,
- (int)ei_buf.enckeylen, (int)ei_buf.authkeylen,
- ei_buf.encryptalg, ei_buf.authalg)
- )
- return &ei_buf;
+ int sadb_aalg, sadb_ealg;
+ static struct esp_info ei_buf;
+
+ sadb_ealg = transid;
+ sadb_aalg = alg_info_esp_aa2sadb(auth);
+
+ if (!ESP_EALG_PRESENT(sadb_ealg))
+ goto none;
+ if (!ESP_AALG_PRESENT(sadb_aalg))
+ goto none;
+
+ memset(&ei_buf, 0, sizeof (ei_buf));
+ ei_buf.transid = transid;
+ ei_buf.auth = auth;
+
+ /* don't return "default" keylen because this value is used from
+ * setup_half_ipsec_sa() to "validate" keylen
+ * In effect, enckeylen will be used as "max" value
+ */
+ ei_buf.enckeylen = esp_ealg[sadb_ealg].sadb_alg_maxbits/BITS_PER_BYTE;
+ ei_buf.authkeylen = esp_aalg[sadb_aalg].sadb_alg_maxbits/BITS_PER_BYTE;
+ ei_buf.encryptalg = sadb_ealg;
+ ei_buf.authalg = sadb_aalg;
+
+ DBG(DBG_PARSING,
+ DBG_log("kernel_alg_esp_info():"
+ "transid=%d, auth=%d, ei=%p, "
+ "enckeylen=%d, authkeylen=%d, encryptalg=%d, authalg=%d",
+ transid, auth, &ei_buf,
+ (int)ei_buf.enckeylen, (int)ei_buf.authkeylen,
+ ei_buf.encryptalg, ei_buf.authalg)
+ )
+ return &ei_buf;
none:
- DBG(DBG_PARSING,
- DBG_log("kernel_alg_esp_info():"
- "transid=%d, auth=%d, ei=NULL",
- transid, auth)
- )
- return NULL;
+ DBG(DBG_PARSING,
+ DBG_log("kernel_alg_esp_info():"
+ "transid=%d, auth=%d, ei=NULL",
+ transid, auth)
+ )
+ return NULL;
}
-#ifndef NO_PLUTO
-static void
-kernel_alg_policy_algorithms(struct esp_info *esp_info)
+static void kernel_alg_policy_algorithms(struct esp_info *esp_info)
{
- u_int ealg_id = esp_info->esp_ealg_id;
-
- switch(ealg_id)
- {
- case 0:
- case ESP_DES:
- case ESP_3DES:
- case ESP_NULL:
- case ESP_CAST:
- break;
- default:
- if (!esp_info->esp_ealg_keylen)
+ u_int ealg_id = esp_info->esp_ealg_id;
+
+ switch(ealg_id)
{
- /* algos that need KEY_LENGTH
- *
- * Note: this is a very dirty hack ;-)
- * Idea: Add a key_length_needed attribute to
- * esp_ealg ??
- */
- esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits;
+ case 0:
+ case ESP_DES:
+ case ESP_3DES:
+ case ESP_NULL:
+ case ESP_CAST:
+ break;
+ default:
+ if (!esp_info->esp_ealg_keylen)
+ {
+ /* algos that need KEY_LENGTH
+ *
+ * Note: this is a very dirty hack ;-)
+ * Idea: Add a key_length_needed attribute to
+ * esp_ealg ??
+ */
+ esp_info->esp_ealg_keylen = esp_ealg[ealg_id].sadb_alg_maxbits;
+ }
}
- }
}
-static bool
-kernel_alg_db_add(struct db_context *db_ctx, struct esp_info *esp_info, lset_t policy)
+static bool kernel_alg_db_add(struct db_context *db_ctx,
+ struct esp_info *esp_info, lset_t policy)
{
- u_int ealg_id, aalg_id;
-
- ealg_id = esp_info->esp_ealg_id;
+ u_int ealg_id, aalg_id;
- if (!ESP_EALG_PRESENT(ealg_id))
- {
- DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id);
- return FALSE;
- }
-
- if (!(policy & POLICY_AUTHENTICATE)) /* skip ESP auth attrs for AH */
- {
- aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id);
+ ealg_id = esp_info->esp_ealg_id;
- if (!ESP_AALG_PRESENT(aalg_id))
+ if (!ESP_EALG_PRESENT(ealg_id))
{
- DBG_log("kernel_alg_db_add() kernel auth "
- "aalg_id=%d not present", aalg_id);
- return FALSE;
+ DBG_log("kernel_alg_db_add() kernel enc ealg_id=%d not present", ealg_id);
+ return FALSE;
}
- }
+
+ if (!(policy & POLICY_AUTHENTICATE)) /* skip ESP auth attrs for AH */
+ {
+ aalg_id = alg_info_esp_aa2sadb(esp_info->esp_aalg_id);
- /* do algo policy */
- kernel_alg_policy_algorithms(esp_info);
+ if (!ESP_AALG_PRESENT(aalg_id))
+ {
+ DBG_log("kernel_alg_db_add() kernel auth "
+ "aalg_id=%d not present", aalg_id);
+ return FALSE;
+ }
+ }
- /* open new transformation */
- db_trans_add(db_ctx, ealg_id);
+ /* do algo policy */
+ kernel_alg_policy_algorithms(esp_info);
- /* add ESP auth attr */
- if (!(policy & POLICY_AUTHENTICATE))
- db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id);
+ /* open new transformation */
+ db_trans_add(db_ctx, ealg_id);
- /* add keylegth if specified in esp= string */
- if (esp_info->esp_ealg_keylen)
- db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen);
-
- return TRUE;
+ /* add ESP auth attr */
+ if (!(policy & POLICY_AUTHENTICATE))
+ db_attr_add_values(db_ctx, AUTH_ALGORITHM, esp_info->esp_aalg_id);
+
+ /* add keylegth if specified in esp= string */
+ if (esp_info->esp_ealg_keylen)
+ db_attr_add_values(db_ctx, KEY_LENGTH, esp_info->esp_ealg_keylen);
+
+ return TRUE;
}
-/*
- * Create proposal with runtime kernel algos, merging
- * with passed proposal if not NULL
+/*
+ * Create proposal with runtime kernel algos, merging
+ * with passed proposal if not NULL
*
- * for now this function does free() previous returned
- * malloced pointer (this quirk allows easier spdb.c change)
+ * for now this function does free() previous returned
+ * malloced pointer (this quirk allows easier spdb.c change)
*/
-struct db_context *
-kernel_alg_db_new(struct alg_info_esp *alg_info, lset_t policy )
+struct db_context* kernel_alg_db_new(struct alg_info_esp *alg_info,
+ lset_t policy )
{
- const struct esp_info *esp_info;
- struct esp_info tmp_esp_info;
- struct db_context *ctx_new=NULL;
- struct db_trans *t;
- struct db_prop *prop;
- u_int trans_cnt;
- int tn = 0;
-
- if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */
- return NULL;
+ const struct esp_info *esp_info;
+ struct esp_info tmp_esp_info;
+ struct db_context *ctx_new = NULL;
+ struct db_prop *prop;
+ u_int trans_cnt = esp_ealg_num * esp_aalg_num;
- trans_cnt = esp_ealg_num * esp_aalg_num;
- DBG(DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() initial trans_cnt=%d"
- , trans_cnt)
- )
-
- /* pass aprox. number of transforms and attributes */
- ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2);
+ if (!(policy & POLICY_ENCRYPT)) /* not possible, I think */
+ {
+ return NULL;
+ }
- /*
- * Loop: for each element (struct esp_info) of alg_info,
- * if kernel support is present then build the transform (and attrs)
- * if NULL alg_info, propose everything ...
- */
+ /* pass aprox. number of transforms and attributes */
+ ctx_new = db_prop_new(PROTO_IPSEC_ESP, trans_cnt, trans_cnt * 2);
- if (alg_info)
- {
- int i;
+ /*
+ * Loop: for each element (struct esp_info) of alg_info,
+ * if kernel support is present then build the transform (and attrs)
+ * if NULL alg_info, propose everything ...
+ */
- ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
+ if (alg_info)
{
- tmp_esp_info = *esp_info;
- kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
+ int i;
+
+ ALG_INFO_ESP_FOREACH(alg_info, esp_info, i)
+ {
+ tmp_esp_info = *esp_info;
+ kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
+ }
}
- }
- else
- {
- u_int ealg_id;
-
- ESP_EALG_FOR_EACH_UPDOWN(ealg_id)
+ else
{
- u_int aalg_id;
-
- tmp_esp_info.esp_ealg_id = ealg_id;
- tmp_esp_info.esp_ealg_keylen = 0;
-
- for (aalg_id = 1; aalg_id <= SADB_AALG_MAX; aalg_id++)
- {
- if (ESP_AALG_PRESENT(aalg_id))
+ u_int ealg_id;
+
+ ESP_EALG_FOR_EACH_UPDOWN(ealg_id)
{
- tmp_esp_info.esp_aalg_id = alg_info_esp_sadb2aa(aalg_id);
- tmp_esp_info.esp_aalg_keylen = 0;
- kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
+ u_int aalg_id;
+
+ tmp_esp_info.esp_ealg_id = ealg_id;
+ tmp_esp_info.esp_ealg_keylen = 0;
+
+ for (aalg_id = 1; aalg_id <= SADB_AALG_MAX; aalg_id++)
+ {
+ if (ESP_AALG_PRESENT(aalg_id))
+ {
+ tmp_esp_info.esp_aalg_id = alg_info_esp_sadb2aa(aalg_id);
+ tmp_esp_info.esp_aalg_keylen = 0;
+ kernel_alg_db_add(ctx_new, &tmp_esp_info, policy);
+ }
+ }
}
- }
}
- }
-
- prop = db_prop_get(ctx_new);
-
- DBG(DBG_CONTROL|DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() "
- "will return p_new->protoid=%d, p_new->trans_cnt=%d"
- , prop->protoid, prop->trans_cnt)
- )
-
- for (t = prop->trans, tn = 0; tn < prop->trans_cnt; tn++)
- {
- DBG(DBG_CONTROL|DBG_EMITTING,
- DBG_log("kernel_alg_db_prop_new() "
- " trans[%d]: transid=%d, attr_cnt=%d, "
- "attrs[0].type=%d, attrs[0].val=%d"
- , tn
- , t[tn].transid, t[tn].attr_cnt
- , t[tn].attrs[0].type, t[tn].attrs[0].val)
- )
- }
- return ctx_new;
+ prop = db_prop_get(ctx_new);
+ return ctx_new;
}
-#endif /* NO_PLUTO */
+
diff --git a/src/pluto/kernel_alg.h b/src/pluto/kernel_alg.h
index 14c2664aa..5ce8c3003 100644
--- a/src/pluto/kernel_alg.h
+++ b/src/pluto/kernel_alg.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_alg.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _KERNEL_ALG_H
diff --git a/src/pluto/kernel_netlink.c b/src/pluto/kernel_netlink.c
index 4269de66e..b4b4774c7 100644
--- a/src/pluto/kernel_netlink.c
+++ b/src/pluto/kernel_netlink.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_netlink.c 3850 2008-04-18 20:01:49Z andreas $
*/
#if defined(linux) && defined(KERNEL26_SUPPORT)
@@ -39,7 +37,7 @@
#include "kernel_netlink.h"
#include "kernel_pfkey.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "kernel_alg.h"
/* Minimum priority number in SPD used by pluto. */
@@ -48,72 +46,72 @@
static int netlinkfd = NULL_FD;
static int netlink_bcast_fd = NULL_FD;
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
+#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
static sparse_names xfrm_type_names = {
- NE(NLMSG_NOOP),
- NE(NLMSG_ERROR),
- NE(NLMSG_DONE),
- NE(NLMSG_OVERRUN),
+ NE(NLMSG_NOOP),
+ NE(NLMSG_ERROR),
+ NE(NLMSG_DONE),
+ NE(NLMSG_OVERRUN),
- NE(XFRM_MSG_NEWSA),
- NE(XFRM_MSG_DELSA),
- NE(XFRM_MSG_GETSA),
+ NE(XFRM_MSG_NEWSA),
+ NE(XFRM_MSG_DELSA),
+ NE(XFRM_MSG_GETSA),
- NE(XFRM_MSG_NEWPOLICY),
- NE(XFRM_MSG_DELPOLICY),
- NE(XFRM_MSG_GETPOLICY),
+ NE(XFRM_MSG_NEWPOLICY),
+ NE(XFRM_MSG_DELPOLICY),
+ NE(XFRM_MSG_GETPOLICY),
- NE(XFRM_MSG_ALLOCSPI),
- NE(XFRM_MSG_ACQUIRE),
- NE(XFRM_MSG_EXPIRE),
+ NE(XFRM_MSG_ALLOCSPI),
+ NE(XFRM_MSG_ACQUIRE),
+ NE(XFRM_MSG_EXPIRE),
- NE(XFRM_MSG_UPDPOLICY),
- NE(XFRM_MSG_UPDSA),
+ NE(XFRM_MSG_UPDPOLICY),
+ NE(XFRM_MSG_UPDSA),
- NE(XFRM_MSG_POLEXPIRE),
+ NE(XFRM_MSG_POLEXPIRE),
- NE(XFRM_MSG_MAX),
+ NE(XFRM_MSG_MAX),
- { 0, sparse_end }
+ { 0, sparse_end }
};
#undef NE
/* Authentication algorithms */
static sparse_names aalg_list = {
- { SADB_X_AALG_NULL, "digest_null" },
- { SADB_AALG_MD5HMAC, "md5" },
- { SADB_AALG_SHA1HMAC, "sha1" },
- { SADB_X_AALG_SHA2_256HMAC, "sha256" },
- { SADB_X_AALG_SHA2_384HMAC, "sha384" },
- { SADB_X_AALG_SHA2_512HMAC, "sha512" },
- { SADB_X_AALG_RIPEMD160HMAC, "ripemd160" },
- { SADB_X_AALG_AES_XCBC_MAC, "xcbc(aes)"},
- { SADB_X_AALG_NULL, "null" },
- { 0, sparse_end }
+ { SADB_X_AALG_NULL, "digest_null" },
+ { SADB_AALG_MD5HMAC, "md5" },
+ { SADB_AALG_SHA1HMAC, "sha1" },
+ { SADB_X_AALG_SHA2_256HMAC, "sha256" },
+ { SADB_X_AALG_SHA2_384HMAC, "sha384" },
+ { SADB_X_AALG_SHA2_512HMAC, "sha512" },
+ { SADB_X_AALG_RIPEMD160HMAC, "ripemd160" },
+ { SADB_X_AALG_AES_XCBC_MAC, "xcbc(aes)"},
+ { SADB_X_AALG_NULL, "null" },
+ { 0, sparse_end }
};
/* Encryption algorithms */
static sparse_names ealg_list = {
- { SADB_EALG_NULL, "cipher_null" },
- { SADB_EALG_DESCBC, "des" },
- { SADB_EALG_3DESCBC, "des3_ede" },
- { SADB_X_EALG_CASTCBC, "cast128" },
- { SADB_X_EALG_BLOWFISHCBC, "blowfish" },
- { SADB_X_EALG_AESCBC, "aes" },
- { SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
- { SADB_X_EALG_SERPENTCBC, "serpent" },
- { SADB_X_EALG_TWOFISHCBC, "twofish" },
- { 0, sparse_end }
+ { SADB_EALG_NULL, "cipher_null" },
+ { SADB_EALG_DESCBC, "des" },
+ { SADB_EALG_3DESCBC, "des3_ede" },
+ { SADB_X_EALG_CASTCBC, "cast128" },
+ { SADB_X_EALG_BLOWFISHCBC, "blowfish" },
+ { SADB_X_EALG_AESCBC, "aes" },
+ { SADB_X_EALG_CAMELLIACBC, "cbc(camellia)" },
+ { SADB_X_EALG_SERPENTCBC, "serpent" },
+ { SADB_X_EALG_TWOFISHCBC, "twofish" },
+ { 0, sparse_end }
};
/* Compression algorithms */
static sparse_names calg_list = {
- { SADB_X_CALG_DEFLATE, "deflate" },
- { SADB_X_CALG_LZS, "lzs" },
- { SADB_X_CALG_LZJH, "lzjh" },
- { 0, sparse_end }
+ { SADB_X_CALG_DEFLATE, "deflate" },
+ { SADB_X_CALG_LZS, "lzs" },
+ { SADB_X_CALG_LZJH, "lzjh" },
+ { 0, sparse_end }
};
/** ip2xfrm - Take an IP address and convert to an xfrm.
@@ -124,14 +122,14 @@ static sparse_names calg_list = {
static void
ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
{
- if (addr->u.v4.sin_family == AF_INET)
- {
- xaddr->a4 = addr->u.v4.sin_addr.s_addr;
- }
- else
- {
- memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
- }
+ if (addr->u.v4.sin_family == AF_INET)
+ {
+ xaddr->a4 = addr->u.v4.sin_addr.s_addr;
+ }
+ else
+ {
+ memcpy(xaddr->a6, &addr->u.v6.sin6_addr, sizeof(xaddr->a6));
+ }
}
/** init_netlink - Initialize the netlink inferface. Opens the sockets and
@@ -140,32 +138,32 @@ ip2xfrm(const ip_address *addr, xfrm_address_t *xaddr)
static void
init_netlink(void)
{
- struct sockaddr_nl addr;
+ struct sockaddr_nl addr;
- netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
+ netlinkfd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
- if (netlinkfd < 0)
- exit_log_errno((e, "socket() in init_netlink()"));
+ if (netlinkfd < 0)
+ exit_log_errno((e, "socket() in init_netlink()"));
- if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
+ if (fcntl(netlinkfd, F_SETFD, FD_CLOEXEC) != 0)
+ exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_netlink()"));
- netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
+ netlink_bcast_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_XFRM);
- if (netlink_bcast_fd < 0)
- exit_log_errno((e, "socket() for bcast in init_netlink()"));
+ if (netlink_bcast_fd < 0)
+ exit_log_errno((e, "socket() for bcast in init_netlink()"));
- if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
+ if (fcntl(netlink_bcast_fd, F_SETFD, FD_CLOEXEC) != 0)
+ exit_log_errno((e, "fcntl(FD_CLOEXEC) for bcast in init_netlink()"));
- if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
- exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
+ if (fcntl(netlink_bcast_fd, F_SETFL, O_NONBLOCK) != 0)
+ exit_log_errno((e, "fcntl(O_NONBLOCK) for bcast in init_netlink()"));
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = getpid();
- addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
- if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
- exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = getpid();
+ addr.nl_groups = XFRMGRP_ACQUIRE | XFRMGRP_EXPIRE;
+ if (bind(netlink_bcast_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+ exit_log_errno((e, "Failed to bind bcast socket in init_netlink()"));
}
/** send_netlink_msg
@@ -182,139 +180,139 @@ static bool
send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
, const char *description, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- char data[1024];
- } rsp;
-
- size_t len;
- ssize_t r;
- struct sockaddr_nl addr;
- static uint32_t seq;
-
- if (no_klips)
- {
- return TRUE;
- }
-
- hdr->nlmsg_seq = ++seq;
- len = hdr->nlmsg_len;
- do {
- r = write(netlinkfd, hdr, len);
- } while (r < 0 && errno == EINTR);
- if (r < 0)
- {
- log_errno((e
- , "netlink write() of %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
- }
- else if ((size_t)r != len)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink write() of %s message"
- " for %s %s truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)len);
- return FALSE;
- }
-
- for (;;) {
- socklen_t alen;
+ struct {
+ struct nlmsghdr n;
+ struct nlmsgerr e;
+ char data[1024];
+ } rsp;
+
+ size_t len;
+ ssize_t r;
+ struct sockaddr_nl addr;
+ static uint32_t seq;
+
+ if (no_klips)
+ {
+ return TRUE;
+ }
- alen = sizeof(addr);
- r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
+ hdr->nlmsg_seq = ++seq;
+ len = hdr->nlmsg_len;
+ do {
+ r = write(netlinkfd, hdr, len);
+ } while (r < 0 && errno == EINTR);
if (r < 0)
{
- if (errno == EINTR)
- {
- continue;
- }
- log_errno((e
- , "netlink recvfrom() of response to our %s message"
- " for %s %s failed"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said));
- return FALSE;
+ log_errno((e
+ , "netlink write() of %s message"
+ " for %s %s failed"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said));
+ return FALSE;
}
- else if ((size_t) r < sizeof(rsp.n))
+ else if ((size_t)r != len)
{
- plog("netlink read truncated message: %ld bytes; ignore message"
- , (long) r);
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink write() of %s message"
+ " for %s %s truncated: %ld instead of %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long)r, (unsigned long)len);
+ return FALSE;
}
- else if (addr.nl_pid != 0)
+
+ for (;;) {
+ socklen_t alen;
+
+ alen = sizeof(addr);
+ r = recvfrom(netlinkfd, &rsp, sizeof(rsp), 0
+ , (struct sockaddr *)&addr, &alen);
+ if (r < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ log_errno((e
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s failed"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said));
+ return FALSE;
+ }
+ else if ((size_t) r < sizeof(rsp.n))
+ {
+ plog("netlink read truncated message: %ld bytes; ignore message"
+ , (long) r);
+ continue;
+ }
+ else if (addr.nl_pid != 0)
+ {
+ /* not for us: ignore */
+ DBG(DBG_KLIPS,
+ DBG_log("netlink: ignoring %s message from process %u"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
+ , addr.nl_pid));
+ continue;
+ }
+ else if (rsp.n.nlmsg_seq != seq)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
+ , rsp.n.nlmsg_seq, seq
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
+ continue;
+ }
+ break;
+ }
+
+ if (rsp.n.nlmsg_len > (size_t) r)
{
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("netlink: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was truncated: %ld instead of %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long) len, (unsigned long) rsp.n.nlmsg_len);
+ return FALSE;
}
- else if (rsp.n.nlmsg_seq != seq)
+ else if (rsp.n.nlmsg_type != NLMSG_ERROR
+ && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
{
- DBG(DBG_KLIPS,
- DBG_log("netlink: ignoring out of sequence (%u/%u) message %s"
- , rsp.n.nlmsg_seq, seq
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
- continue;
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was of wrong type (%s)"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
+ return FALSE;
}
- break;
- }
-
- if (rsp.n.nlmsg_len > (size_t) r)
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was truncated: %ld instead of %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long) len, (unsigned long) rsp.n.nlmsg_len);
- return FALSE;
- }
- else if (rsp.n.nlmsg_type != NLMSG_ERROR
- && (rbuf && rsp.n.nlmsg_type != rbuf->nlmsg_type))
- {
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was of wrong type (%s)"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type));
- return FALSE;
- }
- else if (rbuf)
- {
- if ((size_t) r > rbuf_len)
+ else if (rbuf)
{
- loglog(RC_LOG_SERIOUS
- , "netlink recvfrom() of response to our %s message"
- " for %s %s was too long: %ld > %lu"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , description, text_said
- , (long)r, (unsigned long)rbuf_len);
- return FALSE;
+ if ((size_t) r > rbuf_len)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "netlink recvfrom() of response to our %s message"
+ " for %s %s was too long: %ld > %lu"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , description, text_said
+ , (long)r, (unsigned long)rbuf_len);
+ return FALSE;
+ }
+ memcpy(rbuf, &rsp, r);
+ return TRUE;
+ }
+ else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink response for %s %s included errno %d: %s"
+ , description, text_said
+ , -rsp.e.error
+ , strerror(-rsp.e.error));
+ return FALSE;
}
- memcpy(rbuf, &rsp, r);
- return TRUE;
- }
- else if (rsp.n.nlmsg_type == NLMSG_ERROR && rsp.e.error)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink response for %s %s included errno %d: %s"
- , description, text_said
- , -rsp.e.error
- , strerror(-rsp.e.error));
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
/** netlink_policy -
@@ -327,36 +325,36 @@ send_netlink_msg(struct nlmsghdr *hdr, struct nlmsghdr *rbuf, size_t rbuf_len
static bool
netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct nlmsgerr e;
- } rsp;
- int error;
-
- rsp.n.nlmsg_type = NLMSG_ERROR;
- if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
- {
- return FALSE;
- }
+ struct {
+ struct nlmsghdr n;
+ struct nlmsgerr e;
+ } rsp;
+ int error;
+
+ rsp.n.nlmsg_type = NLMSG_ERROR;
+ if (!send_netlink_msg(hdr, &rsp.n, sizeof(rsp), "policy", text_said))
+ {
+ return FALSE;
+ }
- error = -rsp.e.error;
- if (!error)
- {
- return TRUE;
- }
+ error = -rsp.e.error;
+ if (!error)
+ {
+ return TRUE;
+ }
- if (error == ENOENT && enoent_ok)
- {
- return TRUE;
- }
-
- loglog(RC_LOG_SERIOUS
- , "ERROR: netlink %s response for flow %s included errno %d: %s"
- , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
- , text_said
- , error
- , strerror(error));
- return FALSE;
+ if (error == ENOENT && enoent_ok)
+ {
+ return TRUE;
+ }
+
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: netlink %s response for flow %s included errno %d: %s"
+ , sparse_val_show(xfrm_type_names, hdr->nlmsg_type)
+ , text_said
+ , error
+ , strerror(error));
+ return FALSE;
}
/** netlink_raw_eroute
@@ -376,192 +374,192 @@ netlink_policy(struct nlmsghdr *hdr, bool enoent_ok, const char *text_said)
*/
static bool
netlink_raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info
- , time_t use_lifetime UNUSED
- , unsigned int op
- , const char *text_said)
+ , const ip_subnet *this_client
+ , const ip_address *that_host
+ , const ip_subnet *that_client
+ , ipsec_spi_t spi
+ , unsigned int satype
+ , unsigned int transport_proto
+ , const struct pfkey_proto_info *proto_info
+ , time_t use_lifetime UNUSED
+ , unsigned int op
+ , const char *text_said)
{
- struct {
- struct nlmsghdr n;
- union {
- struct xfrm_userpolicy_info p;
- struct xfrm_userpolicy_id id;
- } u;
- char data[1024];
- } req;
- int shift;
- int dir;
- int family;
- int policy;
- bool ok;
- bool enoent_ok;
-
- policy = IPSEC_POLICY_IPSEC;
-
- if (satype == SADB_X_SATYPE_INT)
- {
- /* shunt route */
- switch (ntohl(spi))
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct xfrm_userpolicy_info p;
+ struct xfrm_userpolicy_id id;
+ } u;
+ char data[1024];
+ } req;
+ int shift;
+ int dir;
+ int family;
+ int policy;
+ bool ok;
+ bool enoent_ok;
+
+ policy = IPSEC_POLICY_IPSEC;
+
+ if (satype == SADB_X_SATYPE_INT)
{
- case SPI_PASS:
- policy = IPSEC_POLICY_NONE;
- break;
- case SPI_DROP:
- case SPI_REJECT:
- default:
- policy = IPSEC_POLICY_DISCARD;
- break;
- case SPI_TRAP:
- case SPI_TRAPSUBNET:
- case SPI_HOLD:
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- return TRUE;
- }
- break;
- }
- }
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-
- family = that_client->addr.u.v4.sin_family;
- shift = (family == AF_INET) ? 5 : 7;
-
- req.u.p.sel.sport = portof(&this_client->addr);
- req.u.p.sel.dport = portof(&that_client->addr);
- req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
- req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
- ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
- ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
- req.u.p.sel.prefixlen_s = this_client->maskbits;
- req.u.p.sel.prefixlen_d = that_client->maskbits;
- req.u.p.sel.proto = transport_proto;
- req.u.p.sel.family = family;
-
- dir = XFRM_POLICY_OUT;
- if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
- {
- dir = XFRM_POLICY_IN;
- }
-
- if ((op & ERO_MASK) == ERO_DELETE)
- {
- req.u.id.dir = dir;
- req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
- }
- else
- {
- int src, dst;
-
- req.u.p.dir = dir;
-
- src = req.u.p.sel.prefixlen_s;
- dst = req.u.p.sel.prefixlen_d;
- if (dir != XFRM_POLICY_OUT) {
- src = req.u.p.sel.prefixlen_d;
- dst = req.u.p.sel.prefixlen_s;
+ /* shunt route */
+ switch (ntohl(spi))
+ {
+ case SPI_PASS:
+ policy = IPSEC_POLICY_NONE;
+ break;
+ case SPI_DROP:
+ case SPI_REJECT:
+ default:
+ policy = IPSEC_POLICY_DISCARD;
+ break;
+ case SPI_TRAP:
+ case SPI_TRAPSUBNET:
+ case SPI_HOLD:
+ if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
+ {
+ return TRUE;
+ }
+ break;
+ }
}
- req.u.p.priority = MIN_SPD_PRIORITY
- + (((2 << shift) - src) << shift)
- + (2 << shift) - dst;
- req.u.p.action = XFRM_POLICY_ALLOW;
- if (policy == IPSEC_POLICY_DISCARD)
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+
+ family = that_client->addr.u.v4.sin_family;
+ shift = (family == AF_INET) ? 5 : 7;
+
+ req.u.p.sel.sport = portof(&this_client->addr);
+ req.u.p.sel.dport = portof(&that_client->addr);
+ req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
+ req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
+ ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);
+ ip2xfrm(&that_client->addr, &req.u.p.sel.daddr);
+ req.u.p.sel.prefixlen_s = this_client->maskbits;
+ req.u.p.sel.prefixlen_d = that_client->maskbits;
+ req.u.p.sel.proto = transport_proto;
+ req.u.p.sel.family = family;
+
+ dir = XFRM_POLICY_OUT;
+ if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
{
- req.u.p.action = XFRM_POLICY_BLOCK;
+ dir = XFRM_POLICY_IN;
}
- req.u.p.lft.soft_use_expires_seconds = use_lifetime;
- req.u.p.lft.soft_byte_limit = XFRM_INF;
- req.u.p.lft.soft_packet_limit = XFRM_INF;
- req.u.p.lft.hard_byte_limit = XFRM_INF;
- req.u.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
- if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
+
+ if ((op & ERO_MASK) == ERO_DELETE)
{
- req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
+ req.u.id.dir = dir;
+ req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.id)));
}
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
- }
-
- if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
- {
- struct rtattr *attr;
- struct xfrm_user_tmpl tmpl[4];
- int i;
-
- memset(tmpl, 0, sizeof(tmpl));
- for (i = 0; proto_info[i].proto; i++)
+ else
{
- tmpl[i].reqid = proto_info[i].reqid;
- tmpl[i].id.proto = proto_info[i].proto;
- tmpl[i].optional =
- proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
- tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
- tmpl[i].mode =
- proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
-
- if (!tmpl[i].mode)
- {
- continue;
- }
-
- ip2xfrm(this_host, &tmpl[i].saddr);
- ip2xfrm(that_host, &tmpl[i].id.daddr);
+ int src, dst;
+
+ req.u.p.dir = dir;
+
+ src = req.u.p.sel.prefixlen_s;
+ dst = req.u.p.sel.prefixlen_d;
+ if (dir != XFRM_POLICY_OUT) {
+ src = req.u.p.sel.prefixlen_d;
+ dst = req.u.p.sel.prefixlen_s;
+ }
+ req.u.p.priority = MIN_SPD_PRIORITY
+ + (((2 << shift) - src) << shift)
+ + (2 << shift) - dst;
+
+ req.u.p.action = XFRM_POLICY_ALLOW;
+ if (policy == IPSEC_POLICY_DISCARD)
+ {
+ req.u.p.action = XFRM_POLICY_BLOCK;
+ }
+ req.u.p.lft.soft_use_expires_seconds = use_lifetime;
+ req.u.p.lft.soft_byte_limit = XFRM_INF;
+ req.u.p.lft.soft_packet_limit = XFRM_INF;
+ req.u.p.lft.hard_byte_limit = XFRM_INF;
+ req.u.p.lft.hard_packet_limit = XFRM_INF;
+
+ req.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+ if (op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT))
+ {
+ req.n.nlmsg_type = XFRM_MSG_UPDPOLICY;
+ }
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.u.p)));
}
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
- attr->rta_type = XFRMA_TMPL;
- attr->rta_len = i * sizeof(tmpl[0]);
- memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
- attr->rta_len = RTA_LENGTH(attr->rta_len);
- req.n.nlmsg_len += attr->rta_len;
- }
-
- enoent_ok = FALSE;
- if (op == ERO_DEL_INBOUND)
- {
- enoent_ok = TRUE;
- }
- else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
- {
- enoent_ok = TRUE;
- }
-
- ok = netlink_policy(&req.n, enoent_ok, text_said);
- switch (dir)
- {
- case XFRM_POLICY_IN:
- if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
+ if (policy == IPSEC_POLICY_IPSEC && (op & ERO_MASK) != ERO_DELETE)
{
- req.u.id.dir = XFRM_POLICY_FWD;
+ struct rtattr *attr;
+ struct xfrm_user_tmpl tmpl[4];
+ int i;
+
+ memset(tmpl, 0, sizeof(tmpl));
+ for (i = 0; proto_info[i].proto; i++)
+ {
+ tmpl[i].reqid = proto_info[i].reqid;
+ tmpl[i].id.proto = proto_info[i].proto;
+ tmpl[i].optional =
+ proto_info[i].proto == IPPROTO_COMP && dir != XFRM_POLICY_OUT;
+ tmpl[i].aalgos = tmpl[i].ealgos = tmpl[i].calgos = ~0;
+ tmpl[i].mode =
+ proto_info[i].encapsulation == ENCAPSULATION_MODE_TUNNEL;
+
+ if (!tmpl[i].mode)
+ {
+ continue;
+ }
+
+ ip2xfrm(this_host, &tmpl[i].saddr);
+ ip2xfrm(that_host, &tmpl[i].id.daddr);
+ }
+
+ attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
+ attr->rta_type = XFRMA_TMPL;
+ attr->rta_len = i * sizeof(tmpl[0]);
+ memcpy(RTA_DATA(attr), tmpl, attr->rta_len);
+ attr->rta_len = RTA_LENGTH(attr->rta_len);
+ req.n.nlmsg_len += attr->rta_len;
}
- else if (!ok)
+
+ enoent_ok = FALSE;
+ if (op == ERO_DEL_INBOUND)
{
- break;
+ enoent_ok = TRUE;
}
- else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
- && satype != SADB_X_SATYPE_INT)
+ else if (op == ERO_DELETE && ntohl(spi) == SPI_HOLD)
{
- break;
+ enoent_ok = TRUE;
}
- else
+
+ ok = netlink_policy(&req.n, enoent_ok, text_said);
+ switch (dir)
{
- req.u.p.dir = XFRM_POLICY_FWD;
+ case XFRM_POLICY_IN:
+ if (req.n.nlmsg_type == XFRM_MSG_DELPOLICY)
+ {
+ req.u.id.dir = XFRM_POLICY_FWD;
+ }
+ else if (!ok)
+ {
+ break;
+ }
+ else if (proto_info[0].encapsulation != ENCAPSULATION_MODE_TUNNEL
+ && satype != SADB_X_SATYPE_INT)
+ {
+ break;
+ }
+ else
+ {
+ req.u.p.dir = XFRM_POLICY_FWD;
+ }
+ ok &= netlink_policy(&req.n, enoent_ok, text_said);
+ break;
}
- ok &= netlink_policy(&req.n, enoent_ok, text_said);
- break;
- }
- return ok;
+ return ok;
}
/** netlink_add_sa - Add an SA into the kernel SPDB via netlink
@@ -573,130 +571,130 @@ netlink_raw_eroute(const ip_address *this_host
static bool
netlink_add_sa(const struct kernel_sa *sa, bool replace)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_info p;
- char data[1024];
- } req;
- struct rtattr *attr;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
-
- ip2xfrm(sa->src, &req.p.saddr);
- ip2xfrm(sa->dst, &req.p.id.daddr);
-
- req.p.id.spi = sa->spi;
- req.p.id.proto = satype2proto(sa->satype);
- req.p.family = sa->src->u.v4.sin_family;
- req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
- req.p.replay_window = sa->replay_window;
- req.p.reqid = sa->reqid;
- req.p.lft.soft_byte_limit = XFRM_INF;
- req.p.lft.soft_packet_limit = XFRM_INF;
- req.p.lft.hard_byte_limit = XFRM_INF;
- req.p.lft.hard_packet_limit = XFRM_INF;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
-
- attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
-
- if (sa->authalg)
- {
- struct xfrm_algo algo;
- const char *name;
-
- name = sparse_name(aalg_list, sa->authalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
- , sa->authalg);
- return FALSE;
- }
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_info p;
+ char data[1024];
+ } req;
+ struct rtattr *attr;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.n.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
+ ip2xfrm(sa->src, &req.p.saddr);
+ ip2xfrm(sa->dst, &req.p.id.daddr);
- attr->rta_type = XFRMA_ALG_AUTH;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
+ req.p.id.spi = sa->spi;
+ req.p.id.proto = satype2proto(sa->satype);
+ req.p.family = sa->src->u.v4.sin_family;
+ req.p.mode = (sa->encapsulation == ENCAPSULATION_MODE_TUNNEL);
+ req.p.replay_window = sa->replay_window;
+ req.p.reqid = sa->reqid;
+ req.p.lft.soft_byte_limit = XFRM_INF;
+ req.p.lft.soft_packet_limit = XFRM_INF;
+ req.p.lft.hard_byte_limit = XFRM_INF;
+ req.p.lft.hard_packet_limit = XFRM_INF;
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
- , sa->authkeylen);
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.p)));
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr = (struct rtattr *)((char *)&req + req.n.nlmsg_len);
+
+ if (sa->authalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- if (sa->encalg)
- {
- struct xfrm_algo algo;
- const char *name;
+ name = sparse_name(aalg_list, sa->authalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown authentication algorithm: %u"
+ , sa->authalg);
+ return FALSE;
+ }
- name = sparse_name(ealg_list, sa->encalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
- , sa->encalg);
- return FALSE;
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = sa->authkeylen * BITS_PER_BYTE;
+
+ attr->rta_type = XFRMA_ALG_AUTH;
+ attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->authkeylen);
+
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->authkey
+ , sa->authkeylen);
+
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
}
- strcpy(algo.alg_name, name);
- algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
+ if (sa->encalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- attr->rta_type = XFRMA_ALG_CRYPT;
- attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
+ name = sparse_name(ealg_list, sa->encalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown encryption algorithm: %u"
+ , sa->encalg);
+ return FALSE;
+ }
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
- , sa->enckeylen);
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = sa->enckeylen * BITS_PER_BYTE;
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr->rta_type = XFRMA_ALG_CRYPT;
+ attr->rta_len = RTA_LENGTH(sizeof(algo) + sa->enckeylen);
- if (sa->compalg)
- {
- struct xfrm_algo algo;
- const char *name;
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ memcpy((char *)RTA_DATA(attr) + sizeof(algo), sa->enckey
+ , sa->enckeylen);
- name = sparse_name(calg_list, sa->compalg);
- if (!name) {
- loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
- , sa->compalg);
- return FALSE;
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
}
- strcpy(algo.alg_name, name);
- algo.alg_key_len = 0;
+ if (sa->compalg)
+ {
+ struct xfrm_algo algo;
+ const char *name;
- attr->rta_type = XFRMA_ALG_COMP;
- attr->rta_len = RTA_LENGTH(sizeof(algo));
+ name = sparse_name(calg_list, sa->compalg);
+ if (!name) {
+ loglog(RC_LOG_SERIOUS, "unknown compression algorithm: %u"
+ , sa->compalg);
+ return FALSE;
+ }
- memcpy(RTA_DATA(attr), &algo, sizeof(algo));
+ strcpy(algo.alg_name, name);
+ algo.alg_key_len = 0;
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ attr->rta_type = XFRMA_ALG_COMP;
+ attr->rta_len = RTA_LENGTH(sizeof(algo));
- if (sa->natt_type)
- {
- struct xfrm_encap_tmpl natt;
+ memcpy(RTA_DATA(attr), &algo, sizeof(algo));
- natt.encap_type = sa->natt_type;
- natt.encap_sport = ntohs(sa->natt_sport);
- natt.encap_dport = ntohs(sa->natt_dport);
- memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
+ }
- attr->rta_type = XFRMA_ENCAP;
- attr->rta_len = RTA_LENGTH(sizeof(natt));
+ if (sa->natt_type)
+ {
+ struct xfrm_encap_tmpl natt;
+
+ natt.encap_type = sa->natt_type;
+ natt.encap_sport = ntohs(sa->natt_sport);
+ natt.encap_dport = ntohs(sa->natt_dport);
+ memset (&natt.encap_oa, 0, sizeof (natt.encap_oa));
- memcpy(RTA_DATA(attr), &natt, sizeof(natt));
+ attr->rta_type = XFRMA_ENCAP;
+ attr->rta_len = RTA_LENGTH(sizeof(natt));
- req.n.nlmsg_len += attr->rta_len;
- attr = (struct rtattr *)((char *)attr + attr->rta_len);
- }
+ memcpy(RTA_DATA(attr), &natt, sizeof(natt));
- return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
+ req.n.nlmsg_len += attr->rta_len;
+ attr = (struct rtattr *)((char *)attr + attr->rta_len);
+ }
+
+ return send_netlink_msg(&req.n, NULL, 0, "Add SA", sa->text_said);
}
/** netlink_del_sa - Delete an SA from the Kernel
@@ -707,113 +705,113 @@ netlink_add_sa(const struct kernel_sa *sa, bool replace)
static bool
netlink_del_sa(const struct kernel_sa *sa)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- char data[1024];
- } req;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id id;
+ char data[1024];
+ } req;
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.n.nlmsg_type = XFRM_MSG_DELSA;
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.n.nlmsg_type = XFRM_MSG_DELSA;
- ip2xfrm(sa->dst, &req.id.daddr);
+ ip2xfrm(sa->dst, &req.id.daddr);
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
+ req.id.spi = sa->spi;
+ req.id.family = sa->src->u.v4.sin_family;
+ req.id.proto = sa->proto;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
+ return send_netlink_msg(&req.n, NULL, 0, "Del SA", sa->text_said);
}
static bool
netlink_error(const char *req_type, const struct nlmsghdr *n
, const struct nlmsgerr *e, int rsp_size)
{
- if (n->nlmsg_type == NLMSG_ERROR)
- {
- DBG(DBG_KLIPS,
- DBG_log("%s returned with errno %d: %s"
- , req_type
- , -e->error
- , strerror(-e->error))
- )
- return TRUE;
- }
- if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
- {
- plog("%s returned message with length %lu < %lu bytes"
- , req_type
- , (unsigned long) n->nlmsg_len
- , (unsigned long) rsp_size);
- return TRUE;
- }
- return FALSE;
+ if (n->nlmsg_type == NLMSG_ERROR)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("%s returned with errno %d: %s"
+ , req_type
+ , -e->error
+ , strerror(-e->error))
+ )
+ return TRUE;
+ }
+ if (n->nlmsg_len < NLMSG_LENGTH(rsp_size))
+ {
+ plog("%s returned message with length %lu < %lu bytes"
+ , req_type
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) rsp_size);
+ return TRUE;
+ }
+ return FALSE;
}
static bool
netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
-
- req.id.sel.sport = portof(&sa->src_client->addr);
- req.id.sel.dport = portof(&sa->dst_client->addr);
- req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
- req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
- ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
- ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
- req.id.sel.prefixlen_s = sa->src_client->maskbits;
- req.id.sel.prefixlen_d = sa->dst_client->maskbits;
- req.id.sel.proto = sa->transport_proto;
- req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id id;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_userpolicy_info info;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
+
+ req.id.sel.sport = portof(&sa->src_client->addr);
+ req.id.sel.dport = portof(&sa->dst_client->addr);
+ req.id.sel.sport_mask = (req.id.sel.sport) ? ~0:0;
+ req.id.sel.dport_mask = (req.id.sel.dport) ? ~0:0;
+ ip2xfrm(&sa->src_client->addr, &req.id.sel.saddr);
+ ip2xfrm(&sa->dst_client->addr, &req.id.sel.daddr);
+ req.id.sel.prefixlen_s = sa->src_client->maskbits;
+ req.id.sel.prefixlen_d = sa->dst_client->maskbits;
+ req.id.sel.proto = sa->transport_proto;
+ req.id.sel.family = sa->dst_client->addr.u.v4.sin_family;
+
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+
+ req.id.dir = (inbound)? XFRM_POLICY_IN:XFRM_POLICY_OUT;
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return FALSE;
+
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
- *use_time = (time_t)rsp.u.info.curlft.use_time;
+ *use_time = (time_t)rsp.u.info.curlft.use_time;
- if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
- {
- time_t use_time_fwd;
+ if (inbound && sa->encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ {
+ time_t use_time_fwd;
- req.id.dir = XFRM_POLICY_FWD;
+ req.id.dir = XFRM_POLICY_FWD;
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return FALSE;
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return FALSE;
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
- use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
- *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
- }
- return TRUE;
+ use_time_fwd = (time_t)rsp.u.info.curlft.use_time;
+ *use_time = (*use_time > use_time_fwd)? *use_time : use_time_fwd;
+ }
+ return TRUE;
}
@@ -825,60 +823,60 @@ netlink_get_policy(const struct kernel_sa *sa, bool inbound, time_t *use_time)
static bool
netlink_get_sa(const struct kernel_sa *sa, u_int *bytes)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_usersa_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info info;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETSA;
-
- ip2xfrm(sa->dst, &req.id.daddr);
-
- req.id.spi = sa->spi;
- req.id.family = sa->src->u.v4.sin_family;
- req.id.proto = sa->proto;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_usersa_id id;
+ } req;
- if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
- return FALSE;
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_usersa_info info;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETSA;
+
+ ip2xfrm(sa->dst, &req.id.daddr);
- *bytes = (u_int) rsp.u.info.curlft.bytes;
+ req.id.spi = sa->spi;
+ req.id.family = sa->src->u.v4.sin_family;
+ req.id.proto = sa->proto;
- return TRUE;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SA", sa->text_said))
+ return FALSE;
+
+ if (netlink_error("XFRM_MSG_GETSA", &rsp.n, &rsp.u.e, sizeof(rsp.u.info)))
+ return FALSE;
+
+ *bytes = (u_int) rsp.u.info.curlft.bytes;
+
+ return TRUE;
}
static void
linux_pfkey_register_response(const struct sadb_msg *msg)
{
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_ESP:
+ switch (msg->sadb_msg_satype)
+ {
+ case SADB_SATYPE_ESP:
#ifndef NO_KERNEL_ALG
- kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
+ kernel_alg_register_pfkey(msg, msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
#endif
- break;
- case SADB_X_SATYPE_IPCOMP:
- can_do_IPcomp = TRUE;
- break;
- default:
- break;
- }
+ break;
+ case SADB_X_SATYPE_IPCOMP:
+ can_do_IPcomp = TRUE;
+ break;
+ default:
+ break;
+ }
}
/** linux_pfkey_register - Register via PFKEY our capabilities
@@ -887,10 +885,10 @@ linux_pfkey_register_response(const struct sadb_msg *msg)
static void
linux_pfkey_register(void)
{
- pfkey_register_proto(SADB_SATYPE_AH, "AH");
- pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
- pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
- pfkey_close();
+ pfkey_register_proto(SADB_SATYPE_AH, "AH");
+ pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
+ pfkey_register_proto(SADB_X_SATYPE_IPCOMP, "IPCOMP");
+ pfkey_close();
}
/** Create ip_address out of xfrm_address_t.
@@ -903,18 +901,18 @@ linux_pfkey_register(void)
static err_t
xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
{
- switch (family)
- {
- case AF_INET: /* IPv4 */
- case AF_UNSPEC: /* Unspecified, we assume IPv4 */
- initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
- return NULL;
- case AF_INET6: /* IPv6 */
- initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
- return NULL;
- default:
- return "unknown address family";
- }
+ switch (family)
+ {
+ case AF_INET: /* IPv4 */
+ case AF_UNSPEC: /* Unspecified, we assume IPv4 */
+ initaddr((const void *) &src->a4, sizeof(src->a4), AF_INET, dst);
+ return NULL;
+ case AF_INET6: /* IPv6 */
+ initaddr((const void *) &src->a6, sizeof(src->a6), AF_INET6, dst);
+ return NULL;
+ default:
+ return "unknown address family";
+ }
}
/* Create a pair of ip_address's out of xfrm_sel.
@@ -926,29 +924,29 @@ xfrm_to_ip_address(unsigned family, const xfrm_address_t *src, ip_address *dst)
*/
static err_t
xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
- , ip_address *src
- , ip_address *dst)
+ , ip_address *src
+ , ip_address *dst)
{
- int family;
- err_t ugh;
-
- family = sel->family;
-
- if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
- || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
- return ugh;
-
- /* family has been verified in xfrm_to_ip_address. */
- if (family == AF_INET)
- {
- src->u.v4.sin_port = sel->sport;
- dst->u.v4.sin_port = sel->dport;
- }
- else
- {
- src->u.v6.sin6_port = sel->sport;
- dst->u.v6.sin6_port = sel->dport;
- }
+ int family;
+ err_t ugh;
+
+ family = sel->family;
+
+ if ((ugh = xfrm_to_ip_address(family, &sel->saddr, src))
+ || (ugh = xfrm_to_ip_address(family, &sel->daddr, dst)))
+ return ugh;
+
+ /* family has been verified in xfrm_to_ip_address. */
+ if (family == AF_INET)
+ {
+ src->u.v4.sin_port = sel->sport;
+ dst->u.v4.sin_port = sel->dport;
+ }
+ else
+ {
+ src->u.v6.sin6_port = sel->sport;
+ dst->u.v6.sin6_port = sel->dport;
+ }
return NULL;
}
@@ -956,194 +954,194 @@ xfrm_sel_to_ip_pair(const struct xfrm_selector *sel
static void
netlink_acquire(struct nlmsghdr *n)
{
- struct xfrm_user_acquire *acquire;
- ip_address src, dst;
- ip_subnet ours, his;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
- {
- plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*acquire));
- return;
- }
-
- acquire = NLMSG_DATA(n);
- transport_proto = acquire->sel.proto;
-
- /* XXX also the type of src/dst should be checked to make sure
- * that they aren't v4 to v6 or something goofy
- */
-
- if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
- && !(ugh = addrtosubnet(&src, &ours))
- && !(ugh = addrtosubnet(&dst, &his)))
- record_and_initiate_opportunistic(&ours, &his, transport_proto
- , "%acquire-netlink");
-
- if (ugh != NULL)
- plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
+ struct xfrm_user_acquire *acquire;
+ ip_address src, dst;
+ ip_subnet ours, his;
+ unsigned transport_proto;
+ err_t ugh = NULL;
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*acquire)))
+ {
+ plog("netlink_acquire got message with length %lu < %lu bytes; ignore message"
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) sizeof(*acquire));
+ return;
+ }
+
+ acquire = NLMSG_DATA(n);
+ transport_proto = acquire->sel.proto;
+
+ /* XXX also the type of src/dst should be checked to make sure
+ * that they aren't v4 to v6 or something goofy
+ */
+
+ if (!(ugh = xfrm_sel_to_ip_pair(&acquire->sel, &src, &dst))
+ && !(ugh = addrtosubnet(&src, &ours))
+ && !(ugh = addrtosubnet(&dst, &his)))
+ record_and_initiate_opportunistic(&ours, &his, transport_proto
+ , "%acquire-netlink");
+
+ if (ugh != NULL)
+ plog("XFRM_MSG_ACQUIRE message from kernel malformed: %s", ugh);
}
static void
netlink_shunt_expire(struct xfrm_userpolicy_info *pol)
{
- ip_address src, dst;
- unsigned transport_proto;
- err_t ugh = NULL;
-
- transport_proto = pol->sel.proto;
-
- if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
- {
- plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
- return;
- }
-
- replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
- , "delete expired bare shunt");
+ ip_address src, dst;
+ unsigned transport_proto;
+ err_t ugh = NULL;
+
+ transport_proto = pol->sel.proto;
+
+ if (!(ugh = xfrm_sel_to_ip_pair(&pol->sel, &src, &dst)))
+ {
+ plog("XFRM_MSG_POLEXPIRE message from kernel malformed: %s", ugh);
+ return;
+ }
+
+ replace_bare_shunt(&src, &dst, BOTTOM_PRIO, SPI_PASS, FALSE, transport_proto
+ , "delete expired bare shunt");
}
static void
netlink_policy_expire(struct nlmsghdr *n)
{
- struct xfrm_user_polexpire *upe;
- struct {
- struct nlmsghdr n;
- struct xfrm_userpolicy_id id;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_userpolicy_info pol;
- } u;
- char data[1024];
- } rsp;
-
- if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
- {
- plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
- , (unsigned long) n->nlmsg_len
- , (unsigned long) sizeof(*upe));
- return;
- }
-
- upe = NLMSG_DATA(n);
- req.id.dir = upe->pol.dir;
- req.id.index = upe->pol.index;
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
-
- rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
- return;
-
- if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
- return;
-
- if (req.id.index != rsp.u.pol.index)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced: "
- "dir=%d, oldindex=%d, newindex=%d"
- , req.id.dir, req.id.index, rsp.u.pol.index));
- return;
- }
-
- if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
- {
- DBG(DBG_KLIPS,
- DBG_log("netlink_policy_expire: policy was replaced "
- " and you have won the lottery: "
- "dir=%d, index=%d"
- , req.id.dir, req.id.index));
- return;
- }
-
- switch (upe->pol.dir)
- {
- case XFRM_POLICY_OUT:
- netlink_shunt_expire(&rsp.u.pol);
- break;
- }
+ struct xfrm_user_polexpire *upe;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userpolicy_id id;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_userpolicy_info pol;
+ } u;
+ char data[1024];
+ } rsp;
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*upe)))
+ {
+ plog("netlink_policy_expire got message with length %lu < %lu bytes; ignore message"
+ , (unsigned long) n->nlmsg_len
+ , (unsigned long) sizeof(*upe));
+ return;
+ }
+
+ upe = NLMSG_DATA(n);
+ req.id.dir = upe->pol.dir;
+ req.id.index = upe->pol.index;
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_GETPOLICY;
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.id)));
+
+ rsp.n.nlmsg_type = XFRM_MSG_NEWPOLICY;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get policy", "?"))
+ return;
+
+ if (netlink_error("XFRM_MSG_GETPOLICY", &rsp.n, &rsp.u.e, sizeof(rsp.u.pol)))
+ return;
+
+ if (req.id.index != rsp.u.pol.index)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_policy_expire: policy was replaced: "
+ "dir=%d, oldindex=%d, newindex=%d"
+ , req.id.dir, req.id.index, rsp.u.pol.index));
+ return;
+ }
+
+ if (upe->pol.curlft.add_time != rsp.u.pol.curlft.add_time)
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_policy_expire: policy was replaced "
+ " and you have won the lottery: "
+ "dir=%d, index=%d"
+ , req.id.dir, req.id.index));
+ return;
+ }
+
+ switch (upe->pol.dir)
+ {
+ case XFRM_POLICY_OUT:
+ netlink_shunt_expire(&rsp.u.pol);
+ break;
+ }
}
static bool
netlink_get(void)
{
- struct {
- struct nlmsghdr n;
- char data[1024];
- } rsp;
- ssize_t r;
- struct sockaddr_nl addr;
- socklen_t alen;
-
- alen = sizeof(addr);
- r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
- , (struct sockaddr *)&addr, &alen);
- if (r < 0)
- {
- if (errno == EAGAIN)
- return FALSE;
- if (errno != EINTR)
- log_errno((e, "recvfrom() failed in netlink_get"));
- return TRUE;
- }
- else if ((size_t) r < sizeof(rsp.n))
- {
- plog("netlink_get read truncated message: %ld bytes; ignore message"
- , (long) r);
- return TRUE;
- }
- else if (addr.nl_pid != 0)
- {
- /* not for us: ignore */
+ struct {
+ struct nlmsghdr n;
+ char data[1024];
+ } rsp;
+ ssize_t r;
+ struct sockaddr_nl addr;
+ socklen_t alen;
+
+ alen = sizeof(addr);
+ r = recvfrom(netlink_bcast_fd, &rsp, sizeof(rsp), 0
+ , (struct sockaddr *)&addr, &alen);
+ if (r < 0)
+ {
+ if (errno == EAGAIN)
+ return FALSE;
+ if (errno != EINTR)
+ log_errno((e, "recvfrom() failed in netlink_get"));
+ return TRUE;
+ }
+ else if ((size_t) r < sizeof(rsp.n))
+ {
+ plog("netlink_get read truncated message: %ld bytes; ignore message"
+ , (long) r);
+ return TRUE;
+ }
+ else if (addr.nl_pid != 0)
+ {
+ /* not for us: ignore */
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_get: ignoring %s message from process %u"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
+ , addr.nl_pid));
+ return TRUE;
+ }
+ else if ((size_t) r != rsp.n.nlmsg_len)
+ {
+ plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
+ , (long) r
+ , (unsigned long) rsp.n.nlmsg_len);
+ return TRUE;
+ }
+
DBG(DBG_KLIPS,
- DBG_log("netlink_get: ignoring %s message from process %u"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)
- , addr.nl_pid));
- return TRUE;
- }
- else if ((size_t) r != rsp.n.nlmsg_len)
- {
- plog("netlink_get read message with length %ld that doesn't equal nlmsg_len %lu bytes; ignore message"
- , (long) r
- , (unsigned long) rsp.n.nlmsg_len);
+ DBG_log("netlink_get: %s message"
+ , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
+
+ switch (rsp.n.nlmsg_type)
+ {
+ case XFRM_MSG_ACQUIRE:
+ netlink_acquire(&rsp.n);
+ break;
+ case XFRM_MSG_POLEXPIRE:
+ netlink_policy_expire(&rsp.n);
+ break;
+ default:
+ /* ignored */
+ break;
+ }
+
return TRUE;
- }
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get: %s message"
- , sparse_val_show(xfrm_type_names, rsp.n.nlmsg_type)));
-
- switch (rsp.n.nlmsg_type)
- {
- case XFRM_MSG_ACQUIRE:
- netlink_acquire(&rsp.n);
- break;
- case XFRM_MSG_POLEXPIRE:
- netlink_policy_expire(&rsp.n);
- break;
- default:
- /* ignored */
- break;
- }
-
- return TRUE;
}
static void
netlink_process_msg(void)
{
- while (netlink_get())
- ;
+ while (netlink_get())
+ ;
}
static ipsec_spi_t
@@ -1156,65 +1154,65 @@ netlink_get_spi(const ip_address *src
, ipsec_spi_t max
, const char *text_said)
{
- struct {
- struct nlmsghdr n;
- struct xfrm_userspi_info spi;
- } req;
-
- struct {
- struct nlmsghdr n;
- union {
- struct nlmsgerr e;
- struct xfrm_usersa_info sa;
- } u;
- char data[1024];
- } rsp;
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
-
- ip2xfrm(src, &req.spi.info.saddr);
- ip2xfrm(dst, &req.spi.info.id.daddr);
- req.spi.info.mode = tunnel_mode;
- req.spi.info.reqid = reqid;
- req.spi.info.id.proto = proto;
- req.spi.info.family = src->u.v4.sin_family;
- req.spi.min = min;
- req.spi.max = max;
-
- req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
- rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
-
- if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
- return 0;
-
- if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
- return 0;
-
- DBG(DBG_KLIPS,
- DBG_log("netlink_get_spi: allocated 0x%x for %s"
- , ntohl(rsp.u.sa.id.spi), text_said));
- return rsp.u.sa.id.spi;
+ struct {
+ struct nlmsghdr n;
+ struct xfrm_userspi_info spi;
+ } req;
+
+ struct {
+ struct nlmsghdr n;
+ union {
+ struct nlmsgerr e;
+ struct xfrm_usersa_info sa;
+ } u;
+ char data[1024];
+ } rsp;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = XFRM_MSG_ALLOCSPI;
+
+ ip2xfrm(src, &req.spi.info.saddr);
+ ip2xfrm(dst, &req.spi.info.id.daddr);
+ req.spi.info.mode = tunnel_mode;
+ req.spi.info.reqid = reqid;
+ req.spi.info.id.proto = proto;
+ req.spi.info.family = src->u.v4.sin_family;
+ req.spi.min = min;
+ req.spi.max = max;
+
+ req.n.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(req.spi)));
+ rsp.n.nlmsg_type = XFRM_MSG_NEWSA;
+
+ if (!send_netlink_msg(&req.n, &rsp.n, sizeof(rsp), "Get SPI", text_said))
+ return 0;
+
+ if (netlink_error("XFRM_MSG_ALLOCSPI", &rsp.n, &rsp.u.e, sizeof(rsp.u.sa)))
+ return 0;
+
+ DBG(DBG_KLIPS,
+ DBG_log("netlink_get_spi: allocated 0x%x for %s"
+ , ntohl(rsp.u.sa.id.spi), text_said));
+ return rsp.u.sa.id.spi;
}
const struct kernel_ops linux_kernel_ops = {
- type: KERNEL_TYPE_LINUX,
- inbound_eroute: 1,
- policy_lifetime: 1,
- async_fdp: &netlink_bcast_fd,
-
- init: init_netlink,
- pfkey_register: linux_pfkey_register,
- pfkey_register_response: linux_pfkey_register_response,
- process_msg: netlink_process_msg,
- raw_eroute: netlink_raw_eroute,
- get_policy: netlink_get_policy,
- add_sa: netlink_add_sa,
- del_sa: netlink_del_sa,
- get_sa: netlink_get_sa,
- process_queue: NULL,
- grp_sa: NULL,
- get_spi: netlink_get_spi,
+ type: KERNEL_TYPE_LINUX,
+ inbound_eroute: 1,
+ policy_lifetime: 1,
+ async_fdp: &netlink_bcast_fd,
+
+ init: init_netlink,
+ pfkey_register: linux_pfkey_register,
+ pfkey_register_response: linux_pfkey_register_response,
+ process_msg: netlink_process_msg,
+ raw_eroute: netlink_raw_eroute,
+ get_policy: netlink_get_policy,
+ add_sa: netlink_add_sa,
+ del_sa: netlink_del_sa,
+ get_sa: netlink_get_sa,
+ process_queue: NULL,
+ grp_sa: NULL,
+ get_spi: netlink_get_spi,
};
#endif /* linux && KLIPS */
diff --git a/src/pluto/kernel_netlink.h b/src/pluto/kernel_netlink.h
index 91ba71c5c..65163c966 100644
--- a/src/pluto/kernel_netlink.h
+++ b/src/pluto/kernel_netlink.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_netlink.h 3252 2007-10-06 21:24:50Z andreas $
*/
#if defined(KLIPS) && defined(linux)
diff --git a/src/pluto/kernel_noklips.c b/src/pluto/kernel_noklips.c
index 4ac3eb153..82a6ab648 100644
--- a/src/pluto/kernel_noklips.c
+++ b/src/pluto/kernel_noklips.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_noklips.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <errno.h>
@@ -39,7 +37,7 @@
#include "kernel.h"
#include "kernel_noklips.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
void
init_noklips(void)
@@ -71,30 +69,30 @@ noklips_register(void)
static bool
noklips_raw_eroute(const ip_address *this_host UNUSED
- , const ip_subnet *this_client UNUSED
- , const ip_address *that_host UNUSED
- , const ip_subnet *that_client UNUSED
- , ipsec_spi_t spi UNUSED
- , unsigned int satype UNUSED
- , unsigned int transport_proto UNUSED
- , const struct pfkey_proto_info *proto_info UNUSED
- , time_t use_lifetime UNUSED
- , unsigned int op UNUSED
- , const char *text_said UNUSED)
+ , const ip_subnet *this_client UNUSED
+ , const ip_address *that_host UNUSED
+ , const ip_subnet *that_client UNUSED
+ , ipsec_spi_t spi UNUSED
+ , unsigned int satype UNUSED
+ , unsigned int transport_proto UNUSED
+ , const struct pfkey_proto_info *proto_info UNUSED
+ , time_t use_lifetime UNUSED
+ , unsigned int op UNUSED
+ , const char *text_said UNUSED)
{
return TRUE;
}
static bool
noklips_add_sa(const struct kernel_sa *sa UNUSED
- , bool replace UNUSED)
+ , bool replace UNUSED)
{
return TRUE;
}
static bool
noklips_grp_sa(const struct kernel_sa *sa0 UNUSED
- , const struct kernel_sa *sa1 UNUSED)
+ , const struct kernel_sa *sa1 UNUSED)
{
return TRUE;
}
@@ -107,20 +105,20 @@ noklips_del_sa(const struct kernel_sa *sa UNUSED)
const struct kernel_ops noklips_kernel_ops = {
- type: KERNEL_TYPE_NONE,
- async_fdp: NULL,
-
- init: init_noklips,
- pfkey_register: noklips_register,
- pfkey_register_response: noklips_register_response,
- process_queue: noklips_dequeue,
- process_msg: noklips_event,
- raw_eroute: noklips_raw_eroute,
- add_sa: noklips_add_sa,
- grp_sa: noklips_grp_sa,
- del_sa: noklips_del_sa,
- get_sa: NULL,
- get_spi: NULL,
- inbound_eroute: FALSE,
- policy_lifetime: FALSE
+ type: KERNEL_TYPE_NONE,
+ async_fdp: NULL,
+
+ init: init_noklips,
+ pfkey_register: noklips_register,
+ pfkey_register_response: noklips_register_response,
+ process_queue: noklips_dequeue,
+ process_msg: noklips_event,
+ raw_eroute: noklips_raw_eroute,
+ add_sa: noklips_add_sa,
+ grp_sa: noklips_grp_sa,
+ del_sa: noklips_del_sa,
+ get_sa: NULL,
+ get_spi: NULL,
+ inbound_eroute: FALSE,
+ policy_lifetime: FALSE
};
diff --git a/src/pluto/kernel_noklips.h b/src/pluto/kernel_noklips.h
index db819eed7..3da55d80b 100644
--- a/src/pluto/kernel_noklips.h
+++ b/src/pluto/kernel_noklips.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_noklips.h 3252 2007-10-06 21:24:50Z andreas $
*/
extern void init_noklips(void);
diff --git a/src/pluto/kernel_pfkey.c b/src/pluto/kernel_pfkey.c
index 742afaf52..7ac405fd4 100644
--- a/src/pluto/kernel_pfkey.c
+++ b/src/pluto/kernel_pfkey.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_pfkey.c 3252 2007-10-06 21:24:50Z andreas $
*/
#ifdef KLIPS
@@ -40,7 +38,7 @@
#include "kernel.h"
#include "kernel_pfkey.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "demux.h"
#include "nat_traversal.h"
#include "alg_info.h"
@@ -50,64 +48,64 @@
static int pfkeyfd = NULL_FD;
typedef u_int32_t pfkey_seq_t;
-static pfkey_seq_t pfkey_seq = 0; /* sequence number for our PF_KEY messages */
+static pfkey_seq_t pfkey_seq = 0; /* sequence number for our PF_KEY messages */
static pid_t pid;
-#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
+#define NE(x) { x, #x } /* Name Entry -- shorthand for sparse_names */
static sparse_names pfkey_type_names = {
- NE(SADB_RESERVED),
- NE(SADB_GETSPI),
- NE(SADB_UPDATE),
- NE(SADB_ADD),
- NE(SADB_DELETE),
- NE(SADB_GET),
- NE(SADB_ACQUIRE),
- NE(SADB_REGISTER),
- NE(SADB_EXPIRE),
- NE(SADB_FLUSH),
- NE(SADB_DUMP),
- NE(SADB_X_PROMISC),
- NE(SADB_X_PCHANGE),
- NE(SADB_X_GRPSA),
- NE(SADB_X_ADDFLOW),
- NE(SADB_X_DELFLOW),
- NE(SADB_X_DEBUG),
- NE(SADB_X_NAT_T_NEW_MAPPING),
- NE(SADB_MAX),
- { 0, sparse_end }
+ NE(SADB_RESERVED),
+ NE(SADB_GETSPI),
+ NE(SADB_UPDATE),
+ NE(SADB_ADD),
+ NE(SADB_DELETE),
+ NE(SADB_GET),
+ NE(SADB_ACQUIRE),
+ NE(SADB_REGISTER),
+ NE(SADB_EXPIRE),
+ NE(SADB_FLUSH),
+ NE(SADB_DUMP),
+ NE(SADB_X_PROMISC),
+ NE(SADB_X_PCHANGE),
+ NE(SADB_X_GRPSA),
+ NE(SADB_X_ADDFLOW),
+ NE(SADB_X_DELFLOW),
+ NE(SADB_X_DEBUG),
+ NE(SADB_X_NAT_T_NEW_MAPPING),
+ NE(SADB_MAX),
+ { 0, sparse_end }
};
#ifdef NEVER /* not needed yet */
static sparse_names pfkey_ext_names = {
- NE(SADB_EXT_RESERVED),
- NE(SADB_EXT_SA),
- NE(SADB_EXT_LIFETIME_CURRENT),
- NE(SADB_EXT_LIFETIME_HARD),
- NE(SADB_EXT_LIFETIME_SOFT),
- NE(SADB_EXT_ADDRESS_SRC),
- NE(SADB_EXT_ADDRESS_DST),
- NE(SADB_EXT_ADDRESS_PROXY),
- NE(SADB_EXT_KEY_AUTH),
- NE(SADB_EXT_KEY_ENCRYPT),
- NE(SADB_EXT_IDENTITY_SRC),
- NE(SADB_EXT_IDENTITY_DST),
- NE(SADB_EXT_SENSITIVITY),
- NE(SADB_EXT_PROPOSAL),
- NE(SADB_EXT_SUPPORTED_AUTH),
- NE(SADB_EXT_SUPPORTED_ENCRYPT),
- NE(SADB_EXT_SPIRANGE),
- NE(SADB_X_EXT_KMPRIVATE),
- NE(SADB_X_EXT_SATYPE2),
- NE(SADB_X_EXT_SA2),
- NE(SADB_X_EXT_ADDRESS_DST2),
- NE(SADB_X_EXT_ADDRESS_SRC_FLOW),
- NE(SADB_X_EXT_ADDRESS_DST_FLOW),
- NE(SADB_X_EXT_ADDRESS_SRC_MASK),
- NE(SADB_X_EXT_ADDRESS_DST_MASK),
- NE(SADB_X_EXT_DEBUG),
- { 0, sparse_end }
+ NE(SADB_EXT_RESERVED),
+ NE(SADB_EXT_SA),
+ NE(SADB_EXT_LIFETIME_CURRENT),
+ NE(SADB_EXT_LIFETIME_HARD),
+ NE(SADB_EXT_LIFETIME_SOFT),
+ NE(SADB_EXT_ADDRESS_SRC),
+ NE(SADB_EXT_ADDRESS_DST),
+ NE(SADB_EXT_ADDRESS_PROXY),
+ NE(SADB_EXT_KEY_AUTH),
+ NE(SADB_EXT_KEY_ENCRYPT),
+ NE(SADB_EXT_IDENTITY_SRC),
+ NE(SADB_EXT_IDENTITY_DST),
+ NE(SADB_EXT_SENSITIVITY),
+ NE(SADB_EXT_PROPOSAL),
+ NE(SADB_EXT_SUPPORTED_AUTH),
+ NE(SADB_EXT_SUPPORTED_ENCRYPT),
+ NE(SADB_EXT_SPIRANGE),
+ NE(SADB_X_EXT_KMPRIVATE),
+ NE(SADB_X_EXT_SATYPE2),
+ NE(SADB_X_EXT_SA2),
+ NE(SADB_X_EXT_ADDRESS_DST2),
+ NE(SADB_X_EXT_ADDRESS_SRC_FLOW),
+ NE(SADB_X_EXT_ADDRESS_DST_FLOW),
+ NE(SADB_X_EXT_ADDRESS_SRC_MASK),
+ NE(SADB_X_EXT_ADDRESS_DST_MASK),
+ NE(SADB_X_EXT_DEBUG),
+ { 0, sparse_end }
};
#endif /* NEVER */
@@ -116,24 +114,24 @@ static sparse_names pfkey_ext_names = {
void
init_pfkey(void)
{
- pid = getpid();
+ pid = getpid();
- /* open PF_KEY socket */
+ /* open PF_KEY socket */
- pfkeyfd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+ pfkeyfd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (pfkeyfd == -1)
- exit_log_errno((e, "socket() in init_pfkeyfd()"));
+ if (pfkeyfd == -1)
+ exit_log_errno((e, "socket() in init_pfkeyfd()"));
-#ifdef NEVER /* apparently unsupported! */
- if (fcntl(pfkeyfd, F_SETFL, O_NONBLOCK) != 0)
- exit_log_errno((e, "fcntl(O_NONBLOCK) in init_pfkeyfd()"));
+#ifdef NEVER /* apparently unsupported! */
+ if (fcntl(pfkeyfd, F_SETFL, O_NONBLOCK) != 0)
+ exit_log_errno((e, "fcntl(O_NONBLOCK) in init_pfkeyfd()"));
#endif
- if (fcntl(pfkeyfd, F_SETFD, FD_CLOEXEC) != 0)
- exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_pfkeyfd()"));
+ if (fcntl(pfkeyfd, F_SETFD, FD_CLOEXEC) != 0)
+ exit_log_errno((e, "fcntl(FD_CLOEXEC) in init_pfkeyfd()"));
- DBG(DBG_KLIPS,
- DBG_log("process %u listening for PF_KEY_V2 on file descriptor %d", (unsigned)pid, pfkeyfd));
+ DBG(DBG_KLIPS,
+ DBG_log("process %u listening for PF_KEY_V2 on file descriptor %d", (unsigned)pid, pfkeyfd));
}
/* Kinds of PF_KEY message from the kernel:
@@ -153,9 +151,9 @@ init_pfkey(void)
*/
typedef union {
- unsigned char bytes[PFKEYv2_MAX_MSGSIZE];
- struct sadb_msg msg;
- } pfkey_buf;
+ unsigned char bytes[PFKEYv2_MAX_MSGSIZE];
+ struct sadb_msg msg;
+ } pfkey_buf;
/* queue of unprocessed PF_KEY messages input from kernel
* Note that the pfkey_buf may be partly allocated, reflecting
@@ -163,41 +161,41 @@ typedef union {
* must come first.
*/
typedef struct pfkey_item {
- struct pfkey_item *next;
- pfkey_buf buf;
- } pfkey_item;
+ struct pfkey_item *next;
+ pfkey_buf buf;
+ } pfkey_item;
-static pfkey_item *pfkey_iq_head = NULL; /* oldest */
-static pfkey_item *pfkey_iq_tail; /* youngest */
+static pfkey_item *pfkey_iq_head = NULL; /* oldest */
+static pfkey_item *pfkey_iq_tail; /* youngest */
static bool
pfkey_input_ready(void)
{
- fd_set readfds;
- int ndes;
- struct timeval tm;
+ fd_set readfds;
+ int ndes;
+ struct timeval tm;
- tm.tv_sec = 0; /* don't wait at all */
- tm.tv_usec = 0;
+ tm.tv_sec = 0; /* don't wait at all */
+ tm.tv_usec = 0;
- FD_ZERO(&readfds); /* we only care about pfkeyfd */
- FD_SET(pfkeyfd, &readfds);
+ FD_ZERO(&readfds); /* we only care about pfkeyfd */
+ FD_SET(pfkeyfd, &readfds);
- do {
- ndes = select(pfkeyfd + 1, &readfds, NULL, NULL, &tm);
- } while (ndes == -1 && errno == EINTR);
+ do {
+ ndes = select(pfkeyfd + 1, &readfds, NULL, NULL, &tm);
+ } while (ndes == -1 && errno == EINTR);
- if (ndes < 0)
- {
- log_errno((e, "select() failed in pfkey_get()"));
- return FALSE;
- }
+ if (ndes < 0)
+ {
+ log_errno((e, "select() failed in pfkey_get()"));
+ return FALSE;
+ }
- if (ndes == 0)
- return FALSE; /* nothing to read */
+ if (ndes == 0)
+ return FALSE; /* nothing to read */
- passert(ndes == 1 && FD_ISSET(pfkeyfd, &readfds));
- return TRUE;
+ passert(ndes == 1 && FD_ISSET(pfkeyfd, &readfds));
+ return TRUE;
}
/* get a PF_KEY message from kernel.
@@ -210,93 +208,93 @@ pfkey_input_ready(void)
static bool
pfkey_get(pfkey_buf *buf)
{
- for (;;)
- {
- /* len must be less than PFKEYv2_MAX_MSGSIZE,
- * so it should fit in an int. We use this fact when printing it.
- */
- ssize_t len;
+ for (;;)
+ {
+ /* len must be less than PFKEYv2_MAX_MSGSIZE,
+ * so it should fit in an int. We use this fact when printing it.
+ */
+ ssize_t len;
- if (!pfkey_input_ready())
- return FALSE;
+ if (!pfkey_input_ready())
+ return FALSE;
- len = read(pfkeyfd, buf->bytes, sizeof(buf->bytes));
+ len = read(pfkeyfd, buf->bytes, sizeof(buf->bytes));
- if (len < 0)
- {
- if (errno == EAGAIN)
- return FALSE;
+ if (len < 0)
+ {
+ if (errno == EAGAIN)
+ return FALSE;
- log_errno((e, "read() failed in pfkey_get()"));
- return FALSE;
- }
- else if ((size_t) len < sizeof(buf->msg))
- {
- plog("pfkey_get read truncated PF_KEY message: %d bytes; ignoring message"
- , (int) len);
- }
- else if ((size_t) len != buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN)
- {
- plog("pfkey_get read PF_KEY message with length %d that doesn't equal sadb_msg_len %u * %u; ignoring message"
- , (int) len
- , (unsigned) buf->msg.sadb_msg_len
- , (unsigned) IPSEC_PFKEYv2_ALIGN);
- }
- else if (!(buf->msg.sadb_msg_pid == (unsigned)pid
- || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_ACQUIRE)
- || (buf->msg.sadb_msg_type == SADB_REGISTER)
- || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING)))
- {
- /* not for us: ignore */
- DBG(DBG_KLIPS,
- DBG_log("pfkey_get: ignoring PF_KEY %s message %u for process %u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid));
- }
- else
- {
- DBG(DBG_KLIPS,
- DBG_log("pfkey_get: %s message %u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_seq));
- return TRUE;
+ log_errno((e, "read() failed in pfkey_get()"));
+ return FALSE;
+ }
+ else if ((size_t) len < sizeof(buf->msg))
+ {
+ plog("pfkey_get read truncated PF_KEY message: %d bytes; ignoring message"
+ , (int) len);
+ }
+ else if ((size_t) len != buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN)
+ {
+ plog("pfkey_get read PF_KEY message with length %d that doesn't equal sadb_msg_len %u * %u; ignoring message"
+ , (int) len
+ , (unsigned) buf->msg.sadb_msg_len
+ , (unsigned) IPSEC_PFKEYv2_ALIGN);
+ }
+ else if (!(buf->msg.sadb_msg_pid == (unsigned)pid
+ || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_ACQUIRE)
+ || (buf->msg.sadb_msg_type == SADB_REGISTER)
+ || (buf->msg.sadb_msg_pid == 0 && buf->msg.sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING)))
+ {
+ /* not for us: ignore */
+ DBG(DBG_KLIPS,
+ DBG_log("pfkey_get: ignoring PF_KEY %s message %u for process %u"
+ , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
+ , buf->msg.sadb_msg_seq
+ , buf->msg.sadb_msg_pid));
+ }
+ else
+ {
+ DBG(DBG_KLIPS,
+ DBG_log("pfkey_get: %s message %u"
+ , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
+ , buf->msg.sadb_msg_seq));
+ return TRUE;
+ }
}
- }
}
/* get a response to a specific message */
static bool
pfkey_get_response(pfkey_buf *buf, pfkey_seq_t seq)
{
- while (pfkey_get(buf))
- {
- if (buf->msg.sadb_msg_pid == (unsigned)pid
- && buf->msg.sadb_msg_seq == seq)
+ while (pfkey_get(buf))
{
- return TRUE;
- }
- else
- {
- /* Not for us: queue it. */
- size_t bl = buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
- pfkey_item *it = alloc_bytes(offsetof(pfkey_item, buf) + bl, "pfkey_item");
-
- memcpy(&it->buf, buf, bl);
-
- it->next = NULL;
- if (pfkey_iq_head == NULL)
- {
- pfkey_iq_head = it;
- }
- else
- {
- pfkey_iq_tail->next = it;
- }
- pfkey_iq_tail = it;
+ if (buf->msg.sadb_msg_pid == (unsigned)pid
+ && buf->msg.sadb_msg_seq == seq)
+ {
+ return TRUE;
+ }
+ else
+ {
+ /* Not for us: queue it. */
+ size_t bl = buf->msg.sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
+ pfkey_item *it = malloc(offsetof(pfkey_item, buf) + bl);
+
+ memcpy(&it->buf, buf, bl);
+
+ it->next = NULL;
+ if (pfkey_iq_head == NULL)
+ {
+ pfkey_iq_head = it;
+ }
+ else
+ {
+ pfkey_iq_tail->next = it;
+ }
+ pfkey_iq_tail = it;
+ }
}
- }
- return FALSE;
+ return FALSE;
}
/* Process a SADB_REGISTER message from the kernel.
@@ -307,34 +305,34 @@ pfkey_get_response(pfkey_buf *buf, pfkey_seq_t seq)
static void
klips_pfkey_register_response(const struct sadb_msg *msg)
{
- /* Find out what the kernel can support.
- * In fact, the only question at the moment
- * is whether it can support IPcomp.
- * So we ignore the rest.
- * ??? we really should pay attention to what transforms are supported.
- */
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_AH:
- break;
- case SADB_SATYPE_ESP:
+ /* Find out what the kernel can support.
+ * In fact, the only question at the moment
+ * is whether it can support IPcomp.
+ * So we ignore the rest.
+ * ??? we really should pay attention to what transforms are supported.
+ */
+ switch (msg->sadb_msg_satype)
+ {
+ case SADB_SATYPE_AH:
+ break;
+ case SADB_SATYPE_ESP:
#ifndef NO_KERNEL_ALG
- kernel_alg_register_pfkey(msg, sizeof (pfkey_buf));
+ kernel_alg_register_pfkey(msg, sizeof (pfkey_buf));
#endif
- break;
- case SADB_X_SATYPE_COMP:
- /* ??? There ought to be an extension to list the
- * supported algorithms, but RFC 2367 doesn't
- * list one for IPcomp. KLIPS uses SADB_X_CALG_DEFLATE.
- * Since we only implement deflate, we'll assume this.
- */
- can_do_IPcomp = TRUE;
- break;
- case SADB_X_SATYPE_IPIP:
- break;
- default:
- break;
- }
+ break;
+ case SADB_X_SATYPE_COMP:
+ /* ??? There ought to be an extension to list the
+ * supported algorithms, but RFC 2367 doesn't
+ * list one for IPcomp. KLIPS uses SADB_X_CALG_DEFLATE.
+ * Since we only implement deflate, we'll assume this.
+ */
+ can_do_IPcomp = TRUE;
+ break;
+ case SADB_X_SATYPE_IPIP:
+ break;
+ default:
+ break;
+ }
}
/* Processs a SADB_ACQUIRE message from KLIPS.
@@ -357,33 +355,33 @@ klips_pfkey_register_response(const struct sadb_msg *msg)
static void
process_pfkey_acquire(pfkey_buf *buf, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
- struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
- int src_proto = srcx->sadb_address_proto;
- int dst_proto = dstx->sadb_address_proto;
- ip_address *src = (ip_address*)&srcx[1];
- ip_address *dst = (ip_address*)&dstx[1];
- ip_subnet ours, his;
- err_t ugh = NULL;
-
- /* assumption: we're only catching our own outgoing packets
- * so source is our end and destination is the other end.
- * Verifying this is not actually convenient.
- *
- * This stylized control structure yields a complaint or
- * desired results. For compactness, a pointer value is
- * treated as a boolean. Logically, the structure is:
- * keep going as long as things are OK.
- */
- if (buf->msg.sadb_msg_pid == 0 /* we only wish to hear from kernel */
- && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ")
- && !(ugh = addrtypeof(src) == addrtypeof(dst)? NULL : "conflicting address types")
- && !(ugh = addrtosubnet(src, &ours))
- && !(ugh = addrtosubnet(dst, &his)))
- record_and_initiate_opportunistic(&ours, &his, src_proto, "%acquire");
-
- if (ugh != NULL)
- plog("SADB_ACQUIRE message from KLIPS malformed: %s", ugh);
+ struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
+ struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
+ int src_proto = srcx->sadb_address_proto;
+ int dst_proto = dstx->sadb_address_proto;
+ ip_address *src = (ip_address*)&srcx[1];
+ ip_address *dst = (ip_address*)&dstx[1];
+ ip_subnet ours, his;
+ err_t ugh = NULL;
+
+ /* assumption: we're only catching our own outgoing packets
+ * so source is our end and destination is the other end.
+ * Verifying this is not actually convenient.
+ *
+ * This stylized control structure yields a complaint or
+ * desired results. For compactness, a pointer value is
+ * treated as a boolean. Logically, the structure is:
+ * keep going as long as things are OK.
+ */
+ if (buf->msg.sadb_msg_pid == 0 /* we only wish to hear from kernel */
+ && !(ugh = src_proto == dst_proto? NULL : "src and dst protocols differ")
+ && !(ugh = addrtypeof(src) == addrtypeof(dst)? NULL : "conflicting address types")
+ && !(ugh = addrtosubnet(src, &ours))
+ && !(ugh = addrtosubnet(dst, &his)))
+ record_and_initiate_opportunistic(&ours, &his, src_proto, "%acquire");
+
+ if (ugh != NULL)
+ plog("SADB_ACQUIRE message from KLIPS malformed: %s", ugh);
}
@@ -394,73 +392,73 @@ process_pfkey_acquire(pfkey_buf *buf, struct sadb_ext *extensions[SADB_EXT_MAX +
static void
pfkey_async(pfkey_buf *buf)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- if (pfkey_msg_parse(&buf->msg, NULL, extensions, EXT_BITS_OUT))
- {
- plog("pfkey_async:"
- " unparseable PF_KEY message:"
- " %s len=%d, errno=%d, seq=%d, pid=%d; message ignored"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_len
- , buf->msg.sadb_msg_errno
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid);
- }
- else
- {
- DBG(DBG_CONTROL | DBG_KLIPS, DBG_log("pfkey_async:"
- " %s len=%u, errno=%u, satype=%u, seq=%u, pid=%u"
- , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
- , buf->msg.sadb_msg_len
- , buf->msg.sadb_msg_errno
- , buf->msg.sadb_msg_satype
- , buf->msg.sadb_msg_seq
- , buf->msg.sadb_msg_pid));
-
- switch (buf->msg.sadb_msg_type)
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+
+ if (pfkey_msg_parse(&buf->msg, NULL, extensions, EXT_BITS_OUT))
{
- case SADB_REGISTER:
- kernel_ops->pfkey_register_response(&buf->msg);
- break;
- case SADB_ACQUIRE:
- /* to simulate loss of ACQUIRE, delete this call */
- process_pfkey_acquire(buf, extensions);
- break;
- case SADB_X_NAT_T_NEW_MAPPING:
- process_pfkey_nat_t_new_mapping(&(buf->msg), extensions);
- break;
- default:
- /* ignored */
- break;
+ plog("pfkey_async:"
+ " unparseable PF_KEY message:"
+ " %s len=%d, errno=%d, seq=%d, pid=%d; message ignored"
+ , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
+ , buf->msg.sadb_msg_len
+ , buf->msg.sadb_msg_errno
+ , buf->msg.sadb_msg_seq
+ , buf->msg.sadb_msg_pid);
+ }
+ else
+ {
+ DBG(DBG_CONTROL | DBG_KLIPS, DBG_log("pfkey_async:"
+ " %s len=%u, errno=%u, satype=%u, seq=%u, pid=%u"
+ , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
+ , buf->msg.sadb_msg_len
+ , buf->msg.sadb_msg_errno
+ , buf->msg.sadb_msg_satype
+ , buf->msg.sadb_msg_seq
+ , buf->msg.sadb_msg_pid));
+
+ switch (buf->msg.sadb_msg_type)
+ {
+ case SADB_REGISTER:
+ kernel_ops->pfkey_register_response(&buf->msg);
+ break;
+ case SADB_ACQUIRE:
+ /* to simulate loss of ACQUIRE, delete this call */
+ process_pfkey_acquire(buf, extensions);
+ break;
+ case SADB_X_NAT_T_NEW_MAPPING:
+ process_pfkey_nat_t_new_mapping(&(buf->msg), extensions);
+ break;
+ default:
+ /* ignored */
+ break;
+ }
}
- }
}
/* asynchronous messages from our queue */
static void
pfkey_dequeue(void)
{
- while (pfkey_iq_head != NULL)
- {
- pfkey_item *it = pfkey_iq_head;
-
- pfkey_async(&it->buf);
- pfkey_iq_head = it->next;
- pfree(it);
- }
-
- /* Handle any orphaned holds, but only if no pfkey input is pending.
- * For each, we initiate Opportunistic.
- * note: we don't need to advance the pointer because
- * record_and_initiate_opportunistic will remove the current
- * record each time we call it.
- */
- while (orphaned_holds != NULL && !pfkey_input_ready())
- record_and_initiate_opportunistic(&orphaned_holds->ours
- , &orphaned_holds->his
- , orphaned_holds->transport_proto
- , "%hold found-pfkey");
+ while (pfkey_iq_head != NULL)
+ {
+ pfkey_item *it = pfkey_iq_head;
+
+ pfkey_async(&it->buf);
+ pfkey_iq_head = it->next;
+ free(it);
+ }
+
+ /* Handle any orphaned holds, but only if no pfkey input is pending.
+ * For each, we initiate Opportunistic.
+ * note: we don't need to advance the pointer because
+ * record_and_initiate_opportunistic will remove the current
+ * record each time we call it.
+ */
+ while (orphaned_holds != NULL && !pfkey_input_ready())
+ record_and_initiate_opportunistic(&orphaned_holds->ours
+ , &orphaned_holds->his
+ , orphaned_holds->transport_proto
+ , "%hold found-pfkey");
}
@@ -468,10 +466,10 @@ pfkey_dequeue(void)
static void
pfkey_event(void)
{
- pfkey_buf buf;
+ pfkey_buf buf;
- if (pfkey_get(&buf))
- pfkey_async(&buf);
+ if (pfkey_get(&buf))
+ pfkey_async(&buf);
}
static bool
@@ -480,17 +478,17 @@ pfkey_build(int error
, const char *text_said
, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- if (error == 0)
- {
- return TRUE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "building of %s %s failed, code %d"
- , description, text_said, error);
- pfkey_extensions_free(extensions);
- return FALSE;
- }
+ if (error == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "building of %s %s failed, code %d"
+ , description, text_said, error);
+ pfkey_extensions_free(extensions);
+ return FALSE;
+ }
}
/* pfkey_extensions_init + pfkey_build + pfkey_msg_hdr_build */
@@ -501,10 +499,10 @@ pfkey_msg_start(u_int8_t msg_type
, const char *text_said
, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- pfkey_extensions_init(extensions);
- return pfkey_build(pfkey_msg_hdr_build(&extensions[0], msg_type
- , satype, 0, ++pfkey_seq, pid)
- , description, text_said, extensions);
+ pfkey_extensions_init(extensions);
+ return pfkey_build(pfkey_msg_hdr_build(&extensions[0], msg_type
+ , satype, 0, ++pfkey_seq, pid)
+ , description, text_said, extensions);
}
/* pfkey_build + pfkey_address_build */
@@ -515,15 +513,15 @@ pfkeyext_address(u_int16_t exttype
, const char *text_said
, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- /* the following variable is only needed to silence
- * a warning caused by the fact that the argument
- * to sockaddrof is NOT pointer to const!
- */
- ip_address t = *address;
-
- return pfkey_build(pfkey_address_build(extensions + exttype
- , exttype, 0, 0, sockaddrof(&t))
- , description, text_said, extensions);
+ /* the following variable is only needed to silence
+ * a warning caused by the fact that the argument
+ * to sockaddrof is NOT pointer to const!
+ */
+ ip_address t = *address;
+
+ return pfkey_build(pfkey_address_build(extensions + exttype
+ , exttype, 0, 0, sockaddrof(&t))
+ , description, text_said, extensions);
}
/* pfkey_build + pfkey_x_protocol_build */
@@ -533,10 +531,10 @@ pfkeyext_protocol(int transport_proto
, const char *text_said
, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- return (transport_proto == 0)? TRUE
- : pfkey_build(
- pfkey_x_protocol_build(extensions + SADB_X_EXT_PROTOCOL, transport_proto)
- , description, text_said, extensions);
+ return (transport_proto == 0)? TRUE
+ : pfkey_build(
+ pfkey_x_protocol_build(extensions + SADB_X_EXT_PROTOCOL, transport_proto)
+ , description, text_said, extensions);
}
@@ -551,376 +549,376 @@ finish_pfkey_msg(struct sadb_ext *extensions[SADB_EXT_MAX + 1]
, const char *text_said
, pfkey_buf *response)
{
- struct sadb_msg *pfkey_msg;
- bool success = TRUE;
- int error;
-
- error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
-
- if (error != 0)
- {
- loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d"
- , description, text_said, error);
- success = FALSE;
- }
- else
- {
- size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
+ struct sadb_msg *pfkey_msg;
+ bool success = TRUE;
+ int error;
- DBG(DBG_KLIPS,
- DBG_log("finish_pfkey_msg: %s message %u for %s %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said);
- DBG_dump(NULL, (void *) pfkey_msg, len));
+ error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN);
- if (!no_klips)
+ if (error != 0)
{
- ssize_t r = write(pfkeyfd, pfkey_msg, len);
-
- if (r != (ssize_t)len)
- {
- if (r < 0)
- {
- log_errno((e
- , "pfkey write() of %s message %u"
- " for %s %s failed"
- , sparse_val_show(pfkey_type_names
- , pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said));
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: pfkey write() of %s message %u"
- " for %s %s truncated: %ld instead of %ld"
- , sparse_val_show(pfkey_type_names
- , pfkey_msg->sadb_msg_type)
- , pfkey_msg->sadb_msg_seq
- , description, text_said
- , (long)r, (long)len);
- }
+ loglog(RC_LOG_SERIOUS, "pfkey_msg_build of %s %s failed, code %d"
+ , description, text_said, error);
success = FALSE;
+ }
+ else
+ {
+ size_t len = pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN;
- /* if we were compiled with debugging, but we haven't already
- * dumped the KLIPS command, do so.
- */
-#ifdef DEBUG
- if ((cur_debugging & DBG_KLIPS) == 0)
- DBG_dump(NULL, (void *) pfkey_msg, len);
-#endif
- }
- else
- {
- /* Check response from KLIPS.
- * It ought to be an echo, perhaps with additional info.
- * If the caller wants it, response will point to space.
- */
- pfkey_buf b;
- pfkey_buf *bp = response != NULL? response : &b;
+ DBG(DBG_KLIPS,
+ DBG_log("finish_pfkey_msg: %s message %u for %s %s"
+ , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
+ , pfkey_msg->sadb_msg_seq
+ , description, text_said);
+ DBG_dump(NULL, (void *) pfkey_msg, len));
- if (!pfkey_get_response(bp, ((struct sadb_msg *) extensions[0])->sadb_msg_seq))
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR: no response to our PF_KEY %s message for %s %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said);
- success = FALSE;
- }
- else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type)
- {
- loglog(RC_LOG_SERIOUS
- , "FreeS/WAN ERROR: response to our PF_KEY %s message for %s %s was of wrong type (%s)"
- , sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said
- , sparse_val_show(pfkey_type_names, bp->msg.sadb_msg_type));
- success = FALSE;
- }
- else if (response == NULL && bp->msg.sadb_msg_errno != 0)
+ if (!no_klips)
{
- /* KLIPS is signalling a problem */
- loglog(RC_LOG_SERIOUS
- , "ERROR: PF_KEY %s response for %s %s included errno %u: %s"
- , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
- , description, text_said
- , (unsigned) bp->msg.sadb_msg_errno
- , strerror(bp->msg.sadb_msg_errno));
- success = FALSE;
+ ssize_t r = write(pfkeyfd, pfkey_msg, len);
+
+ if (r != (ssize_t)len)
+ {
+ if (r < 0)
+ {
+ log_errno((e
+ , "pfkey write() of %s message %u"
+ " for %s %s failed"
+ , sparse_val_show(pfkey_type_names
+ , pfkey_msg->sadb_msg_type)
+ , pfkey_msg->sadb_msg_seq
+ , description, text_said));
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: pfkey write() of %s message %u"
+ " for %s %s truncated: %ld instead of %ld"
+ , sparse_val_show(pfkey_type_names
+ , pfkey_msg->sadb_msg_type)
+ , pfkey_msg->sadb_msg_seq
+ , description, text_said
+ , (long)r, (long)len);
+ }
+ success = FALSE;
+
+ /* if we were compiled with debugging, but we haven't already
+ * dumped the KLIPS command, do so.
+ */
+#ifdef DEBUG
+ if ((cur_debugging & DBG_KLIPS) == 0)
+ DBG_dump(NULL, (void *) pfkey_msg, len);
+#endif
+ }
+ else
+ {
+ /* Check response from KLIPS.
+ * It ought to be an echo, perhaps with additional info.
+ * If the caller wants it, response will point to space.
+ */
+ pfkey_buf b;
+ pfkey_buf *bp = response != NULL? response : &b;
+
+ if (!pfkey_get_response(bp, ((struct sadb_msg *) extensions[0])->sadb_msg_seq))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: no response to our PF_KEY %s message for %s %s"
+ , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
+ , description, text_said);
+ success = FALSE;
+ }
+ else if (pfkey_msg->sadb_msg_type != bp->msg.sadb_msg_type)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "FreeS/WAN ERROR: response to our PF_KEY %s message for %s %s was of wrong type (%s)"
+ , sparse_name(pfkey_type_names, pfkey_msg->sadb_msg_type)
+ , description, text_said
+ , sparse_val_show(pfkey_type_names, bp->msg.sadb_msg_type));
+ success = FALSE;
+ }
+ else if (response == NULL && bp->msg.sadb_msg_errno != 0)
+ {
+ /* KLIPS is signalling a problem */
+ loglog(RC_LOG_SERIOUS
+ , "ERROR: PF_KEY %s response for %s %s included errno %u: %s"
+ , sparse_val_show(pfkey_type_names, pfkey_msg->sadb_msg_type)
+ , description, text_said
+ , (unsigned) bp->msg.sadb_msg_errno
+ , strerror(bp->msg.sadb_msg_errno));
+ success = FALSE;
+ }
+ }
}
- }
}
- }
- /* all paths must exit this way to free resources */
- pfkey_extensions_free(extensions);
- pfkey_msg_free(&pfkey_msg);
- return success;
+ /* all paths must exit this way to free resources */
+ pfkey_extensions_free(extensions);
+ pfkey_msg_free(&pfkey_msg);
+ return success;
}
/* register SA types that can be negotiated */
void
pfkey_register_proto(unsigned satype, const char *satypename)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- pfkey_buf pfb;
-
- if (!(pfkey_msg_start(SADB_REGISTER
- , satype
- , satypename, NULL, extensions)
- && finish_pfkey_msg(extensions, satypename, "", &pfb)))
- {
- /* ??? should this be loglog */
- plog("no KLIPS support for %s", satypename);
- }
- else
- {
- kernel_ops->pfkey_register_response(&pfb.msg);
- DBG(DBG_KLIPS,
- DBG_log("%s registered with kernel.", satypename));
- }
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+ pfkey_buf pfb;
+
+ if (!(pfkey_msg_start(SADB_REGISTER
+ , satype
+ , satypename, NULL, extensions)
+ && finish_pfkey_msg(extensions, satypename, "", &pfb)))
+ {
+ /* ??? should this be loglog */
+ plog("no KLIPS support for %s", satypename);
+ }
+ else
+ {
+ kernel_ops->pfkey_register_response(&pfb.msg);
+ DBG(DBG_KLIPS,
+ DBG_log("%s registered with kernel.", satypename));
+ }
}
static void
klips_pfkey_register(void)
{
- pfkey_register_proto(SADB_SATYPE_AH, "AH");
- pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
- can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
- pfkey_register_proto(SADB_X_SATYPE_COMP, "IPCOMP");
- pfkey_register_proto(SADB_X_SATYPE_IPIP, "IPIP");
+ pfkey_register_proto(SADB_SATYPE_AH, "AH");
+ pfkey_register_proto(SADB_SATYPE_ESP, "ESP");
+ can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
+ pfkey_register_proto(SADB_X_SATYPE_COMP, "IPCOMP");
+ pfkey_register_proto(SADB_X_SATYPE_IPIP, "IPIP");
}
static bool
pfkey_raw_eroute(const ip_address *this_host
- , const ip_subnet *this_client
- , const ip_address *that_host
- , const ip_subnet *that_client
- , ipsec_spi_t spi
- , unsigned int satype
- , unsigned int transport_proto
- , const struct pfkey_proto_info *proto_info UNUSED
- , time_t use_lifetime UNUSED
- , unsigned int op
- , const char *text_said)
+ , const ip_subnet *this_client
+ , const ip_address *that_host
+ , const ip_subnet *that_client
+ , ipsec_spi_t spi
+ , unsigned int satype
+ , unsigned int transport_proto
+ , const struct pfkey_proto_info *proto_info UNUSED
+ , time_t use_lifetime UNUSED
+ , unsigned int op
+ , const char *text_said)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- ip_address
- sflow_ska,
- dflow_ska,
- smask_ska,
- dmask_ska;
- int sport = ntohs(portof(&this_client->addr));
- int dport = ntohs(portof(&that_client->addr));
-
- networkof(this_client, &sflow_ska);
- maskof(this_client, &smask_ska);
- setportof(sport ? ~0:0, &smask_ska);
-
- networkof(that_client, &dflow_ska);
- maskof(that_client, &dmask_ska);
- setportof(dport ? ~0:0, &dmask_ska);
-
- if (!pfkey_msg_start(op & ERO_MASK, satype
- , "pfkey_msg_hdr flow", text_said, extensions))
- {
- return FALSE;
- }
-
- if (op != ERO_DELETE)
- {
- if (!(pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , spi /* in network order */
- , 0, 0, 0, 0, op >> ERO_FLAG_SHIFT)
- , "pfkey_sa add flow", text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, this_host
- , "pfkey_addr_s add flow", text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, that_host
- , "pfkey_addr_d add flow", text_said
- , extensions)))
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+ ip_address
+ sflow_ska,
+ dflow_ska,
+ smask_ska,
+ dmask_ska;
+ int sport = ntohs(portof(&this_client->addr));
+ int dport = ntohs(portof(&that_client->addr));
+
+ networkof(this_client, &sflow_ska);
+ maskof(this_client, &smask_ska);
+ setportof(sport ? ~0:0, &smask_ska);
+
+ networkof(that_client, &dflow_ska);
+ maskof(that_client, &dmask_ska);
+ setportof(dport ? ~0:0, &dmask_ska);
+
+ if (!pfkey_msg_start(op & ERO_MASK, satype
+ , "pfkey_msg_hdr flow", text_said, extensions))
{
- return FALSE;
+ return FALSE;
}
- }
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_FLOW, &sflow_ska
- , "pfkey_addr_sflow", text_said, extensions))
- {
- return FALSE;
- }
+ if (op != ERO_DELETE)
+ {
+ if (!(pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
+ , SADB_EXT_SA
+ , spi /* in network order */
+ , 0, 0, 0, 0, op >> ERO_FLAG_SHIFT)
+ , "pfkey_sa add flow", text_said, extensions)
+
+ && pfkeyext_address(SADB_EXT_ADDRESS_SRC, this_host
+ , "pfkey_addr_s add flow", text_said, extensions)
+
+ && pfkeyext_address(SADB_EXT_ADDRESS_DST, that_host
+ , "pfkey_addr_d add flow", text_said
+ , extensions)))
+ {
+ return FALSE;
+ }
+ }
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_FLOW, &dflow_ska
- , "pfkey_addr_dflow", text_said, extensions))
- {
- return FALSE;
- }
+ if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_FLOW, &sflow_ska
+ , "pfkey_addr_sflow", text_said, extensions))
+ {
+ return FALSE;
+ }
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_MASK, &smask_ska
- , "pfkey_addr_smask", text_said, extensions))
- {
- return FALSE;
- }
+ if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_FLOW, &dflow_ska
+ , "pfkey_addr_dflow", text_said, extensions))
+ {
+ return FALSE;
+ }
- if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_MASK, &dmask_ska
- , "pfkey_addr_dmask", text_said, extensions))
- {
- return FALSE;
- }
+ if (!pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_MASK, &smask_ska
+ , "pfkey_addr_smask", text_said, extensions))
+ {
+ return FALSE;
+ }
- if (!pfkeyext_protocol(transport_proto
- , "pfkey_x_protocol", text_said, extensions))
- {
- return FALSE;
- }
+ if (!pfkeyext_address(SADB_X_EXT_ADDRESS_DST_MASK, &dmask_ska
+ , "pfkey_addr_dmask", text_said, extensions))
+ {
+ return FALSE;
+ }
+
+ if (!pfkeyext_protocol(transport_proto
+ , "pfkey_x_protocol", text_said, extensions))
+ {
+ return FALSE;
+ }
- return finish_pfkey_msg(extensions, "flow", text_said, NULL);
+ return finish_pfkey_msg(extensions, "flow", text_said, NULL);
}
static bool
pfkey_add_sa(const struct kernel_sa *sa, bool replace)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
-
- return pfkey_msg_start(replace ? SADB_UPDATE : SADB_ADD, sa->satype
- , "pfkey_msg_hdr Add SA", sa->text_said, extensions)
-
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa->spi /* in network order */
- , sa->replay_window, SADB_SASTATE_MATURE
- , sa->authalg, sa->encalg ? sa->encalg: sa->compalg, 0)
- , "pfkey_sa Add SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
- , "pfkey_addr_s Add SA", sa->text_said, extensions)
-
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
- , "pfkey_addr_d Add SA", sa->text_said, extensions)
-
- && (sa->authkeylen == 0
- || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_AUTH]
- , SADB_EXT_KEY_AUTH, sa->authkeylen * BITS_PER_BYTE
- , sa->authkey)
- , "pfkey_key_a Add SA", sa->text_said, extensions))
-
- && (sa->enckeylen == 0
- || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_ENCRYPT]
- , SADB_EXT_KEY_ENCRYPT, sa->enckeylen * BITS_PER_BYTE
- , sa->enckey)
- , "pfkey_key_e Add SA", sa->text_said, extensions))
-
- && (sa->natt_type == 0
- || pfkey_build(pfkey_x_nat_t_type_build(
- &extensions[SADB_X_EXT_NAT_T_TYPE], sa->natt_type),
- "pfkey_nat_t_type Add ESP SA", sa->text_said, extensions))
- && (sa->natt_sport == 0
- || pfkey_build(pfkey_x_nat_t_port_build(
- &extensions[SADB_X_EXT_NAT_T_SPORT], SADB_X_EXT_NAT_T_SPORT,
- sa->natt_sport), "pfkey_nat_t_sport Add ESP SA", sa->text_said,
- extensions))
- && (sa->natt_dport == 0
- || pfkey_build(pfkey_x_nat_t_port_build(
- &extensions[SADB_X_EXT_NAT_T_DPORT], SADB_X_EXT_NAT_T_DPORT,
- sa->natt_dport), "pfkey_nat_t_dport Add ESP SA", sa->text_said,
- extensions))
- && (sa->natt_type == 0 || isanyaddr(sa->natt_oa)
- || pfkeyext_address(SADB_X_EXT_NAT_T_OA, sa->natt_oa
- , "pfkey_nat_t_oa Add ESP SA", sa->text_said, extensions))
-
- && finish_pfkey_msg(extensions, "Add SA", sa->text_said, NULL);
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+
+ return pfkey_msg_start(replace ? SADB_UPDATE : SADB_ADD, sa->satype
+ , "pfkey_msg_hdr Add SA", sa->text_said, extensions)
+
+ && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
+ , SADB_EXT_SA
+ , sa->spi /* in network order */
+ , sa->replay_window, SADB_SASTATE_MATURE
+ , sa->authalg, sa->encalg ? sa->encalg: sa->compalg, 0)
+ , "pfkey_sa Add SA", sa->text_said, extensions)
+
+ && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
+ , "pfkey_addr_s Add SA", sa->text_said, extensions)
+
+ && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
+ , "pfkey_addr_d Add SA", sa->text_said, extensions)
+
+ && (sa->authkeylen == 0
+ || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_AUTH]
+ , SADB_EXT_KEY_AUTH, sa->authkeylen * BITS_PER_BYTE
+ , sa->authkey)
+ , "pfkey_key_a Add SA", sa->text_said, extensions))
+
+ && (sa->enckeylen == 0
+ || pfkey_build(pfkey_key_build(&extensions[SADB_EXT_KEY_ENCRYPT]
+ , SADB_EXT_KEY_ENCRYPT, sa->enckeylen * BITS_PER_BYTE
+ , sa->enckey)
+ , "pfkey_key_e Add SA", sa->text_said, extensions))
+
+ && (sa->natt_type == 0
+ || pfkey_build(pfkey_x_nat_t_type_build(
+ &extensions[SADB_X_EXT_NAT_T_TYPE], sa->natt_type),
+ "pfkey_nat_t_type Add ESP SA", sa->text_said, extensions))
+ && (sa->natt_sport == 0
+ || pfkey_build(pfkey_x_nat_t_port_build(
+ &extensions[SADB_X_EXT_NAT_T_SPORT], SADB_X_EXT_NAT_T_SPORT,
+ sa->natt_sport), "pfkey_nat_t_sport Add ESP SA", sa->text_said,
+ extensions))
+ && (sa->natt_dport == 0
+ || pfkey_build(pfkey_x_nat_t_port_build(
+ &extensions[SADB_X_EXT_NAT_T_DPORT], SADB_X_EXT_NAT_T_DPORT,
+ sa->natt_dport), "pfkey_nat_t_dport Add ESP SA", sa->text_said,
+ extensions))
+ && (sa->natt_type == 0 || isanyaddr(sa->natt_oa)
+ || pfkeyext_address(SADB_X_EXT_NAT_T_OA, sa->natt_oa
+ , "pfkey_nat_t_oa Add ESP SA", sa->text_said, extensions))
+
+ && finish_pfkey_msg(extensions, "Add SA", sa->text_said, NULL);
}
static bool
pfkey_grp_sa(const struct kernel_sa *sa0, const struct kernel_sa *sa1)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- return pfkey_msg_start(SADB_X_GRPSA, sa1->satype
- , "pfkey_msg_hdr group", sa1->text_said, extensions)
+ return pfkey_msg_start(SADB_X_GRPSA, sa1->satype
+ , "pfkey_msg_hdr group", sa1->text_said, extensions)
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa1->spi /* in network order */
- , 0, 0, 0, 0, 0)
- , "pfkey_sa group", sa1->text_said, extensions)
+ && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
+ , SADB_EXT_SA
+ , sa1->spi /* in network order */
+ , 0, 0, 0, 0, 0)
+ , "pfkey_sa group", sa1->text_said, extensions)
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa1->dst
- , "pfkey_addr_d group", sa1->text_said, extensions)
+ && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa1->dst
+ , "pfkey_addr_d group", sa1->text_said, extensions)
- && pfkey_build(pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2]
- , sa0->satype)
- , "pfkey_satype group", sa0->text_said, extensions)
+ && pfkey_build(pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2]
+ , sa0->satype)
+ , "pfkey_satype group", sa0->text_said, extensions)
- && pfkey_build(pfkey_sa_build(&extensions[SADB_X_EXT_SA2]
- , SADB_X_EXT_SA2
- , sa0->spi /* in network order */
- , 0, 0, 0, 0, 0)
- , "pfkey_sa2 group", sa0->text_said, extensions)
+ && pfkey_build(pfkey_sa_build(&extensions[SADB_X_EXT_SA2]
+ , SADB_X_EXT_SA2
+ , sa0->spi /* in network order */
+ , 0, 0, 0, 0, 0)
+ , "pfkey_sa2 group", sa0->text_said, extensions)
- && pfkeyext_address(SADB_X_EXT_ADDRESS_DST2, sa0->dst
- , "pfkey_addr_d2 group", sa0->text_said, extensions)
+ && pfkeyext_address(SADB_X_EXT_ADDRESS_DST2, sa0->dst
+ , "pfkey_addr_d2 group", sa0->text_said, extensions)
- && finish_pfkey_msg(extensions, "group", sa1->text_said, NULL);
+ && finish_pfkey_msg(extensions, "group", sa1->text_said, NULL);
}
static bool
pfkey_del_sa(const struct kernel_sa *sa)
{
- struct sadb_ext *extensions[SADB_EXT_MAX + 1];
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1];
- return pfkey_msg_start(SADB_DELETE, proto2satype(sa->proto)
- , "pfkey_msg_hdr delete SA", sa->text_said, extensions)
+ return pfkey_msg_start(SADB_DELETE, proto2satype(sa->proto)
+ , "pfkey_msg_hdr delete SA", sa->text_said, extensions)
- && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
- , SADB_EXT_SA
- , sa->spi /* in host order */
- , 0, SADB_SASTATE_MATURE, 0, 0, 0)
- , "pfkey_sa delete SA", sa->text_said, extensions)
+ && pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
+ , SADB_EXT_SA
+ , sa->spi /* in host order */
+ , 0, SADB_SASTATE_MATURE, 0, 0, 0)
+ , "pfkey_sa delete SA", sa->text_said, extensions)
- && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
- , "pfkey_addr_s delete SA", sa->text_said, extensions)
+ && pfkeyext_address(SADB_EXT_ADDRESS_SRC, sa->src
+ , "pfkey_addr_s delete SA", sa->text_said, extensions)
- && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
- , "pfkey_addr_d delete SA", sa->text_said, extensions)
+ && pfkeyext_address(SADB_EXT_ADDRESS_DST, sa->dst
+ , "pfkey_addr_d delete SA", sa->text_said, extensions)
- && finish_pfkey_msg(extensions, "Delete SA", sa->text_said, NULL);
+ && finish_pfkey_msg(extensions, "Delete SA", sa->text_said, NULL);
}
void
pfkey_close(void)
{
- while (pfkey_iq_head != NULL)
- {
- pfkey_item *it = pfkey_iq_head;
+ while (pfkey_iq_head != NULL)
+ {
+ pfkey_item *it = pfkey_iq_head;
- pfkey_iq_head = it->next;
- pfree(it);
- }
+ pfkey_iq_head = it->next;
+ free(it);
+ }
- close(pfkeyfd);
- pfkeyfd = NULL_FD;
+ close(pfkeyfd);
+ pfkeyfd = NULL_FD;
}
const struct kernel_ops klips_kernel_ops = {
- type: KERNEL_TYPE_KLIPS,
- async_fdp: &pfkeyfd,
-
- pfkey_register: klips_pfkey_register,
- pfkey_register_response: klips_pfkey_register_response,
- process_queue: pfkey_dequeue,
- process_msg: pfkey_event,
- raw_eroute: pfkey_raw_eroute,
- add_sa: pfkey_add_sa,
- grp_sa: pfkey_grp_sa,
- del_sa: pfkey_del_sa,
- get_sa: NULL,
- get_spi: NULL,
- inbound_eroute: FALSE,
- policy_lifetime: FALSE,
- init: NULL
+ type: KERNEL_TYPE_KLIPS,
+ async_fdp: &pfkeyfd,
+
+ pfkey_register: klips_pfkey_register,
+ pfkey_register_response: klips_pfkey_register_response,
+ process_queue: pfkey_dequeue,
+ process_msg: pfkey_event,
+ raw_eroute: pfkey_raw_eroute,
+ add_sa: pfkey_add_sa,
+ grp_sa: pfkey_grp_sa,
+ del_sa: pfkey_del_sa,
+ get_sa: NULL,
+ get_spi: NULL,
+ inbound_eroute: FALSE,
+ policy_lifetime: FALSE,
+ init: NULL
};
#endif /* KLIPS */
diff --git a/src/pluto/kernel_pfkey.h b/src/pluto/kernel_pfkey.h
index 23ac982e8..ad20a5888 100644
--- a/src/pluto/kernel_pfkey.h
+++ b/src/pluto/kernel_pfkey.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: kernel_pfkey.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifdef KLIPS
diff --git a/src/pluto/keys.c b/src/pluto/keys.c
index 1aed7a63f..6dfbd6732 100644
--- a/src/pluto/keys.c
+++ b/src/pluto/keys.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: keys.c 3738 2008-04-02 19:04:45Z andreas $
*/
#include <stddef.h>
@@ -25,33 +23,34 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <glob.h>
#ifndef GLOB_ABORTED
-# define GLOB_ABORTED GLOB_ABEND /* fix for old versions */
+# define GLOB_ABORTED GLOB_ABEND /* fix for old versions */
#endif
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <library.h>
+#include <asn1/asn1.h>
#include "constants.h"
#include "defs.h"
-#include "mp_defs.h"
#include "id.h"
#include "x509.h"
-#include "pgp.h"
+#include "pgpcert.h"
#include "certs.h"
#include "smartcard.h"
#include "connections.h"
#include "state.h"
#include "lex.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "timer.h"
#include "fetch.h"
#include "xauth.h"
@@ -61,77 +60,34 @@ const char *shared_secrets_file = SHARED_SECRETS_FILE;
typedef struct id_list id_list_t;
struct id_list {
- struct id id;
- id_list_t *next;
+ struct id id;
+ id_list_t *next;
};
typedef struct secret secret_t;
struct secret {
- id_list_t *ids;
- enum PrivateKeyKind kind;
- union {
- chunk_t preshared_secret;
- RSA_private_key_t RSA_private_key;
- xauth_t xauth_secret;
- smartcard_t *smartcard;
- } u;
- secret_t *next;
+ id_list_t *ids;
+ enum PrivateKeyKind kind;
+ union {
+ chunk_t preshared_secret;
+ xauth_t xauth_secret;
+ private_key_t *private_key;
+ smartcard_t *smartcard;
+ } u;
+ secret_t *next;
};
-static pubkey_t*
-allocate_RSA_public_key(const cert_t cert)
-{
- pubkey_t *pk = alloc_thing(pubkey_t, "pubkey");
- chunk_t e = empty_chunk, n = empty_chunk;
-
- switch (cert.type)
- {
- case CERT_PGP:
- e = cert.u.pgp->publicExponent;
- n = cert.u.pgp->modulus;
- break;
- case CERT_X509_SIGNATURE:
- e = cert.u.x509->publicExponent;
- n = cert.u.x509->modulus;
- break;
- default:
- plog("RSA public key allocation error");
- }
-
- init_RSA_public_key(&pk->u.rsa, e, n);
- DBG(DBG_RAW,
- RSA_show_public_key(&pk->u.rsa)
- )
-
- pk->alg = PUBKEY_ALG_RSA;
- pk->id = empty_id;
- pk->issuer = empty_chunk;
- pk->serial = empty_chunk;
-
- return pk;
-}
-
/*
* free a public key struct
*/
-static void
-free_public_key(pubkey_t *pk)
+static void free_public_key(pubkey_t *pk)
{
- free_id_content(&pk->id);
- freeanychunk(pk->issuer);
- freeanychunk(pk->serial);
-
- /* algorithm-specific freeing */
- switch (pk->alg)
- {
- case PUBKEY_ALG_RSA:
- free_RSA_public_content(&pk->u.rsa);
- break;
- default:
- bad_case(pk->alg);
- }
- pfree(pk);
+ DESTROY_IF(pk->public_key);
+ free_id_content(&pk->id);
+ free(pk->issuer.ptr);
+ free(pk->serial.ptr);
+ free(pk);
}
secret_t *secrets = NULL;
@@ -140,227 +96,215 @@ secret_t *secrets = NULL;
* me and the peer. We match the Id (if none, the IP address).
* Failure is indicated by a NULL.
*/
-static const secret_t *
-get_secret(const struct connection *c, enum PrivateKeyKind kind, bool asym)
+static const secret_t* get_secret(const struct connection *c,
+ enum PrivateKeyKind kind, bool asym)
{
- enum { /* bits */
- match_default = 01,
- match_him = 02,
- match_me = 04
- };
-
- unsigned int best_match = 0;
- secret_t *best = NULL;
- secret_t *s;
- const struct id *my_id = &c->spd.this.id
- , *his_id = &c->spd.that.id;
- struct id rw_id;
-
- /* is there a certificate assigned to this connection? */
- if (kind == PPK_RSA && c->spd.this.cert.type != CERT_NONE)
- {
- pubkey_t *my_public_key = allocate_RSA_public_key(c->spd.this.cert);
-
- for (s = secrets; s != NULL; s = s->next)
+ enum { /* bits */
+ match_default = 0x01,
+ match_him = 0x02,
+ match_me = 0x04
+ };
+
+ unsigned int best_match = 0;
+ secret_t *best = NULL;
+ secret_t *s;
+ const struct id *my_id = &c->spd.this.id
+ , *his_id = &c->spd.that.id;
+ struct id rw_id;
+
+ /* is there a certificate assigned to this connection? */
+ if (kind == PPK_PUBKEY && c->spd.this.cert.type != CERT_NONE)
{
- if (s->kind == kind &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &my_public_key->u.rsa))
- {
- best = s;
- break; /* we have found the private key - no sense in searching further */
- }
- }
- free_public_key(my_public_key);
- return best;
- }
-
- if (his_id_was_instantiated(c))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- rw_id.kind = c->spd.that.id.kind;
- rw_id.name = empty_chunk;
- happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
- his_id = &rw_id;
- }
- else if (kind == PPK_PSK
- && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK))
- && ((c->kind == CK_TEMPLATE && c->spd.that.id.kind == ID_NONE) ||
- (c->kind == CK_INSTANCE && id_is_ipaddr(&c->spd.that.id))))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- rw_id.kind = ID_IPV4_ADDR;
- happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
- his_id = &rw_id;
- }
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == kind)
- {
- unsigned int match = 0;
+ public_key_t *pub_key = cert_get_public_key(c->spd.this.cert);
- if (s->ids == NULL)
- {
- /* a default (signified by lack of ids):
- * accept if no more specific match found
- */
- match = match_default;
- }
- else
- {
- /* check if both ends match ids */
- id_list_t *i;
-
- for (i = s->ids; i != NULL; i = i->next)
+ for (s = secrets; s != NULL; s = s->next)
{
- if (same_id(my_id, &i->id))
- match |= match_me;
-
- if (same_id(his_id, &i->id))
- match |= match_him;
+ if (s->kind == kind &&
+ s->u.private_key->belongs_to(s->u.private_key, pub_key))
+ {
+ best = s;
+ break; /* we have found the private key - no sense in searching further */
+ }
}
+ return best;
+ }
- /* If our end matched the only id in the list,
- * default to matching any peer.
- * A more specific match will trump this.
- */
- if (match == match_me
- && s->ids->next == NULL)
- match |= match_default;
- }
-
- switch (match)
- {
- case match_me:
- /* if this is an asymmetric (eg. public key) system,
- * allow this-side-only match to count, even if
- * there are other ids in the list.
- */
- if (!asym)
- break;
- /* FALLTHROUGH */
- case match_default: /* default all */
- case match_me | match_default: /* default peer */
- case match_me | match_him: /* explicit */
- if (match == best_match)
- {
- /* two good matches are equally good:
- * do they agree?
- */
- bool same = FALSE;
-
- switch (kind)
- {
- case PPK_PSK:
- same = s->u.preshared_secret.len == best->u.preshared_secret.len
- && memcmp(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len) == 0;
- break;
- case PPK_RSA:
- /* Dirty trick: since we have code to compare
- * RSA public keys, but not private keys, we
- * make the assumption that equal public keys
- * mean equal private keys. This ought to work.
- */
- same = same_RSA_public_key(&s->u.RSA_private_key.pub
- , &best->u.RSA_private_key.pub);
- break;
- default:
- bad_case(kind);
- }
- if (!same)
- {
- loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with distinct secrets match endpoints:"
- " first secret used");
- best = s; /* list is backwards: take latest in list */
- }
- }
- else if (match > best_match)
+ if (his_id_was_instantiated(c))
+ {
+ /* roadwarrior: replace him with 0.0.0.0 */
+ rw_id.kind = c->spd.that.id.kind;
+ rw_id.name = chunk_empty;
+ happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
+ his_id = &rw_id;
+ }
+ else if (kind == PPK_PSK
+ && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK))
+ && ((c->kind == CK_TEMPLATE && c->spd.that.id.kind == ID_ANY) ||
+ (c->kind == CK_INSTANCE && id_is_ipaddr(&c->spd.that.id))))
+ {
+ /* roadwarrior: replace him with 0.0.0.0 */
+ rw_id.kind = ID_IPV4_ADDR;
+ happy(anyaddr(addrtypeof(&c->spd.that.host_addr), &rw_id.ip_addr));
+ his_id = &rw_id;
+ }
+
+ for (s = secrets; s != NULL; s = s->next)
+ {
+ if (s->kind == kind)
{
- /* this is the best match so far */
- best_match = match;
- best = s;
+ unsigned int match = 0;
+
+ if (s->ids == NULL)
+ {
+ /* a default (signified by lack of ids):
+ * accept if no more specific match found
+ */
+ match = match_default;
+ }
+ else
+ {
+ /* check if both ends match ids */
+ id_list_t *i;
+
+ for (i = s->ids; i != NULL; i = i->next)
+ {
+ if (same_id(my_id, &i->id))
+ {
+ match |= match_me;
+ }
+ if (same_id(his_id, &i->id))
+ {
+ match |= match_him;
+ }
+ }
+
+ /* If our end matched the only id in the list,
+ * default to matching any peer.
+ * A more specific match will trump this.
+ */
+ if (match == match_me && s->ids->next == NULL)
+ {
+ match |= match_default;
+ }
+ }
+
+ switch (match)
+ {
+ case match_me:
+ /* if this is an asymmetric (eg. public key) system,
+ * allow this-side-only match to count, even if
+ * there are other ids in the list.
+ */
+ if (!asym)
+ {
+ break;
+ }
+ /* FALLTHROUGH */
+ case match_default: /* default all */
+ case match_me | match_default: /* default peer */
+ case match_me | match_him: /* explicit */
+ if (match == best_match)
+ {
+ /* two good matches are equally good:
+ * do they agree?
+ */
+ bool same = FALSE;
+
+ switch (kind)
+ {
+ case PPK_PSK:
+ same = s->u.preshared_secret.len == best->u.preshared_secret.len
+ && memeq(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len);
+ break;
+ case PPK_PUBKEY:
+ same = s->u.private_key->equals(s->u.private_key, best->u.private_key);
+ break;
+ default:
+ bad_case(kind);
+ }
+ if (!same)
+ {
+ loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with distinct secrets match endpoints:"
+ " first secret used");
+ best = s; /* list is backwards: take latest in list */
+ }
+ }
+ else if (match > best_match)
+ {
+ /* this is the best match so far */
+ best_match = match;
+ best = s;
+ }
+ }
}
- }
}
- }
- return best;
+ return best;
}
/* find the appropriate preshared key (see get_secret).
* Failure is indicated by a NULL pointer.
* Note: the result is not to be freed by the caller.
*/
-const chunk_t *
-get_preshared_secret(const struct connection *c)
+const chunk_t* get_preshared_secret(const struct connection *c)
{
- const secret_t *s = get_secret(c, PPK_PSK, FALSE);
+ const secret_t *s = get_secret(c, PPK_PSK, FALSE);
- DBG(DBG_PRIVATE,
- if (s == NULL)
- DBG_log("no Preshared Key Found");
- else
- DBG_dump_chunk("Preshared Key", s->u.preshared_secret);
- )
- return s == NULL? NULL : &s->u.preshared_secret;
+ DBG(DBG_PRIVATE,
+ if (s == NULL)
+ DBG_log("no Preshared Key Found");
+ else
+ DBG_dump_chunk("Preshared Key", s->u.preshared_secret);
+ )
+ return s == NULL? NULL : &s->u.preshared_secret;
}
-/* check the existence of an RSA private key matching an RSA public
- * key contained in an X.509 or OpenPGP certificate
+/* check the existence of a private key matching a public key contained
+ * in an X.509 or OpenPGP certificate
*/
-bool
-has_private_key(cert_t cert)
+bool has_private_key(cert_t cert)
{
- secret_t *s;
- bool has_key = FALSE;
- pubkey_t *pubkey = allocate_RSA_public_key(cert);
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_RSA &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &pubkey->u.rsa))
+ secret_t *s;
+ bool has_key = FALSE;
+ public_key_t *pub_key = cert_get_public_key(cert);
+
+ for (s = secrets; s != NULL; s = s->next)
{
- has_key = TRUE;
- break;
+ if (s->kind == PPK_PUBKEY &&
+ s->u.private_key->belongs_to(s->u.private_key, pub_key))
+ {
+ has_key = TRUE;
+ break;
+ }
}
- }
- free_public_key(pubkey);
- return has_key;
+ return has_key;
}
/*
- * get the matching RSA private key belonging to a given X.509 certificate
+ * get the matching private key belonging to a given X.509 certificate
*/
-const RSA_private_key_t*
-get_x509_private_key(const x509cert_t *cert)
+private_key_t* get_x509_private_key(const x509cert_t *cert)
{
- secret_t *s;
- const RSA_private_key_t *pri = NULL;
- const cert_t c = {CERT_X509_SIGNATURE, {(x509cert_t*)cert}};
-
- pubkey_t *pubkey = allocate_RSA_public_key(c);
+ secret_t *s;
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_RSA &&
- same_RSA_public_key(&s->u.RSA_private_key.pub, &pubkey->u.rsa))
+ for (s = secrets; s != NULL; s = s->next)
{
- pri = &s->u.RSA_private_key;
- break;
+ if (s->kind == PPK_PUBKEY &&
+ s->u.private_key->belongs_to(s->u.private_key, cert->public_key))
+ {
+ return s->u.private_key;
+ }
}
- }
- free_public_key(pubkey);
- return pri;
+ return NULL;
}
-/* find the appropriate RSA private key (see get_secret).
+/* find the appropriate private key (see get_secret).
* Failure is indicated by a NULL pointer.
*/
-const RSA_private_key_t *
-get_RSA_private_key(const struct connection *c)
+private_key_t* get_private_key(const struct connection *c)
{
- const secret_t *s = get_secret(c, PPK_RSA, TRUE);
+ const secret_t *s = get_secret(c, PPK_PUBKEY, TRUE);
- return s == NULL? NULL : &s->u.RSA_private_key;
+ return s == NULL? NULL : s->u.private_key;
}
/* digest a secrets file
@@ -403,1100 +347,1071 @@ get_RSA_private_key(const struct connection *c)
*/
/* parse PSK from file */
-static err_t
-process_psk_secret(chunk_t *psk)
+static err_t process_psk_secret(chunk_t *psk)
{
- err_t ugh = NULL;
-
- if (*tok == '"' || *tok == '\'')
- {
- clonetochunk(*psk, tok+1, flp->cur - tok - 2, "PSK");
- (void) shift();
- }
- else
- {
- char buf[BUF_LEN]; /* limit on size of binary representation of key */
- size_t sz;
-
- ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
- , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
- if (ugh != NULL)
+ err_t ugh = NULL;
+
+ if (*tok == '"' || *tok == '\'')
{
- /* ttodata didn't like PSK data */
- ugh = builddiag("PSK data malformed (%s): %s", ugh, tok);
+ chunk_t secret = { tok + 1, flp->cur - tok -2 };
+
+ *psk = chunk_clone(secret);
+ (void) shift();
}
else
{
- clonetochunk(*psk, buf, sz, "PSK");
- (void) shift();
+ char buf[BUF_LEN]; /* limit on size of binary representation of key */
+ size_t sz;
+
+ ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
+ , diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
+ if (ugh != NULL)
+ {
+ /* ttodata didn't like PSK data */
+ ugh = builddiag("PSK data malformed (%s): %s", ugh, tok);
+ }
+ else
+ {
+ chunk_t secret = { buf, sz };
+ *psk = chunk_clone(secret);
+ (void) shift();
+ }
}
- }
- return ugh;
+ return ugh;
}
-/* Parse fields of RSA private key.
- * A braced list of keyword and value pairs.
- * At the moment, each field is required, in order.
- * The fields come from BIND 8.2's representation
+typedef enum rsa_private_key_part_t rsa_private_key_part_t;
+
+enum rsa_private_key_part_t {
+ RSA_PART_MODULUS = 0,
+ RSA_PART_PUBLIC_EXPONENT = 1,
+ RSA_PART_PRIVATE_EXPONENT = 2,
+ RSA_PART_PRIME1 = 3,
+ RSA_PART_PRIME2 = 4,
+ RSA_PART_EXPONENT1 = 5,
+ RSA_PART_EXPONENT2 = 6,
+ RSA_PART_COEFFICIENT = 7
+};
+
+const char *rsa_private_key_part_names[] = {
+ "Modulus",
+ "PublicExponent",
+ "PrivateExponent",
+ "Prime1",
+ "Prime2",
+ "Exponent1",
+ "Exponent2",
+ "Coefficient"
+};
+
+/**
+ * Parse fields of an RSA private key in BIND 8.2's representation
+ * consistiong of a braced list of keyword and value pairs in required order.
+ * Conversion into ASN.1 DER encoded PKCS#1 representation.
*/
-static err_t
-process_rsa_secret(RSA_private_key_t *rsak)
+static err_t process_rsa_secret(private_key_t **key)
{
- char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
- const struct fld *p;
-
- /* save bytes of Modulus and PublicExponent for keyid calculation */
- unsigned char ebytes[sizeof(buf)];
- unsigned char *eb_next = ebytes;
- chunk_t pub_bytes[2];
- chunk_t *pb_next = &pub_bytes[0];
-
- for (p = RSA_private_field; p < &RSA_private_field[RSA_PRIVATE_FIELD_ELEMENTS]; p++)
- {
- size_t sz;
+ chunk_t asn1_chunk[countof(rsa_private_key_part_names)];
+ chunk_t pkcs1_chunk;
+ u_char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
+ rsa_private_key_part_t part, p;
+ size_t sz, len = 0;
err_t ugh;
- if (!shift())
+ for (part = RSA_PART_MODULUS; part <= RSA_PART_COEFFICIENT; part++)
{
- return "premature end of RSA key";
+ chunk_t rsa_private_key_part;
+ const char *keyword = rsa_private_key_part_names[part];
+
+ if (!shift())
+ {
+ ugh = "premature end of RSA key";
+ goto end;
+ }
+ if (!tokeqword(keyword))
+ {
+ ugh = builddiag("%s keyword not found where expected in RSA key"
+ , keyword);
+ goto end;
+ }
+ if (!(shift() && (!tokeq(":") || shift()))) /* ignore optional ":" */
+ {
+ ugh = "premature end of RSA key";
+ goto end;
+ }
+ ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz,
+ diag_space, sizeof(diag_space), TTODATAV_SPACECOUNTS);
+ if (ugh)
+ {
+ ugh = builddiag("RSA data malformed (%s): %s", ugh, tok);
+ part++;
+ goto end;
+ }
+ rsa_private_key_part = chunk_create(buf, sz);
+ asn1_chunk[part] = asn1_integer("c", rsa_private_key_part);
+ len += asn1_chunk[part].len;
}
- else if (!tokeqword(p->name))
+
+ /* We require an (indented) '}' and the end of the record.
+ * We break down the test so that the diagnostic will be more helpful.
+ * Some people don't seem to wish to indent the brace!
+ */
+ if (!shift() || !tokeq("}"))
{
- return builddiag("%s keyword not found where expected in RSA key"
- , p->name);
+ ugh = "malformed end of RSA private key -- indented '}' required";
+ goto end;
}
- else if (!(shift()
- && (!tokeq(":") || shift()))) /* ignore optional ":" */
+ if (shift())
{
- return "premature end of RSA key";
+ ugh = "malformed end of RSA private key -- unexpected token after '}'";
+ goto end;
}
- else if (NULL != (ugh = ttodatav(tok, flp->cur - tok
- , 0, buf, sizeof(buf), &sz, diag_space, sizeof(diag_space)
- , TTODATAV_SPACECOUNTS)))
+
+ pkcs1_chunk = asn1_wrap(ASN1_SEQUENCE, "ccccccccc",
+ ASN1_INTEGER_0,
+ asn1_chunk[RSA_PART_MODULUS],
+ asn1_chunk[RSA_PART_PUBLIC_EXPONENT],
+ asn1_chunk[RSA_PART_PRIVATE_EXPONENT],
+ asn1_chunk[RSA_PART_PRIME1],
+ asn1_chunk[RSA_PART_PRIME2],
+ asn1_chunk[RSA_PART_EXPONENT1],
+ asn1_chunk[RSA_PART_EXPONENT2],
+ asn1_chunk[RSA_PART_COEFFICIENT]);
+
+ *key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, pkcs1_chunk,
+ BUILD_END);
+ free(pkcs1_chunk.ptr);
+ if (*key == NULL)
{
- /* in RSA key, ttodata didn't like */
- return builddiag("RSA data malformed (%s): %s", ugh, tok);
+ ugh = "parsing of RSA private key failed";
}
- else
+
+end:
+ /* clean up and return */
+ for (p = RSA_PART_MODULUS ; p < part; p++)
{
- MP_INT *n = (MP_INT *) ((char *)rsak + p->offset);
-
- n_to_mpz(n, buf, sz);
- if (pb_next < &pub_bytes[elemsof(pub_bytes)])
- {
- if (eb_next - ebytes + sz > sizeof(ebytes))
- return "public key takes too many bytes";
-
- setchunk(*pb_next, eb_next, sz);
- memcpy(eb_next, buf, sz);
- eb_next += sz;
- pb_next++;
- }
-#if 0 /* debugging info that compromises security */
- {
- size_t sz = mpz_sizeinbase(n, 16);
- char buf[RSA_MAX_OCTETS * 2 + 2]; /* ought to be big enough */
-
- passert(sz <= sizeof(buf));
- mpz_get_str(buf, 16, n);
-
- loglog(RC_LOG_SERIOUS, "%s: %s", p->name, buf);
- }
-#endif
+ free(asn1_chunk[p].ptr);
}
- }
-
- /* We require an (indented) '}' and the end of the record.
- * We break down the test so that the diagnostic will be
- * more helpful. Some people don't seem to wish to indent
- * the brace!
- */
- if (!shift() || !tokeq("}"))
- {
- return "malformed end of RSA private key -- indented '}' required";
- }
- else if (shift())
- {
- return "malformed end of RSA private key -- unexpected token after '}'";
- }
- else
- {
- unsigned bits = mpz_sizeinbase(&rsak->pub.n, 2);
-
- rsak->pub.k = (bits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
- rsak->pub.keyid[0] = '\0'; /* in case of splitkeytoid failure */
- splitkeytoid(pub_bytes[1].ptr, pub_bytes[1].len
- , pub_bytes[0].ptr, pub_bytes[0].len
- , rsak->pub.keyid, sizeof(rsak->pub.keyid));
- return RSA_private_key_sanity(rsak);
- }
+ return ugh;
}
-/* process rsa key file protected with optional passphrase which can either be
+/**
+ * process a key file protected with optional passphrase which can either be
* read from ipsec.secrets or prompted for by using whack
*/
-static err_t
-process_rsa_keyfile(RSA_private_key_t *rsak, int whackfd)
+static err_t process_keyfile(private_key_t **key, key_type_t type, int whackfd)
{
- char filename[BUF_LEN];
- prompt_pass_t pass;
-
- memset(filename,'\0', BUF_LEN);
- memset(pass.secret,'\0', sizeof(pass.secret));
- pass.prompt = FALSE;
- pass.fd = whackfd;
+ char filename[BUF_LEN];
+ prompt_pass_t pass;
- /* we expect the filename of a PKCS#1 private key file */
+ memset(filename,'\0', BUF_LEN);
+ memset(pass.secret,'\0', sizeof(pass.secret));
+ pass.prompt = FALSE;
+ pass.fd = whackfd;
- if (*tok == '"' || *tok == '\'') /* quoted filename */
- memcpy(filename, tok+1, flp->cur - tok - 2);
- else
- memcpy(filename, tok, flp->cur - tok);
+ /* we expect the filename of a PKCS#1 private key file */
- if (shift())
- {
- /* we expect an appended passphrase or passphrase prompt*/
- if (tokeqword("%prompt"))
- {
- if (pass.fd == NULL_FD)
- return "RSA private key file -- enter passphrase using 'ipsec secrets'";
- pass.prompt = TRUE;
- }
+ if (*tok == '"' || *tok == '\'') /* quoted filename */
+ memcpy(filename, tok+1, flp->cur - tok - 2);
else
+ memcpy(filename, tok, flp->cur - tok);
+
+ if (shift())
{
- char *passphrase = tok;
- size_t len = flp->cur - passphrase;
-
- if (*tok == '"' || *tok == '\'') /* quoted passphrase */
- {
- passphrase++;
- len -= 2;
- }
- if (len > PROMPT_PASS_LEN)
- return "RSA private key file -- passphrase exceeds 64 characters";
-
- memcpy(pass.secret, passphrase, len);
+ /* we expect an appended passphrase or passphrase prompt*/
+ if (tokeqword("%prompt"))
+ {
+ if (pass.fd == NULL_FD)
+ {
+ return "Private key file -- enter passphrase using 'ipsec secrets'";
+ }
+ pass.prompt = TRUE;
+ }
+ else
+ {
+ char *passphrase = tok;
+ size_t len = flp->cur - passphrase;
+
+ if (*tok == '"' || *tok == '\'') /* quoted passphrase */
+ {
+ passphrase++;
+ len -= 2;
+ }
+ if (len > PROMPT_PASS_LEN)
+ {
+ return "Private key file -- passphrase exceeds 64 characters";
+ }
+ memcpy(pass.secret, passphrase, len);
+ }
+ if (shift())
+ {
+ return "Private key file -- unexpected token after passphrase";
+ }
}
- if (shift())
- return "RSA private key file -- unexpected token after passphrase";
- }
- return load_rsa_private_key(filename, &pass, rsak);
+ *key = load_private_key(filename, &pass, type);
+
+ return key ? NULL : "Private key file -- could not be loaded";
}
-/*
- * process xauth secret read from ipsec.secrets
+/**
+ * Process xauth secret read from ipsec.secrets
*/
-static err_t
-process_xauth(secret_t *s)
+static err_t process_xauth(secret_t *s)
{
- chunk_t user_name;
-
- s->kind = PPK_XAUTH;
-
- if (!shift())
- return "missing xauth user name";
- if (*tok == '"' || *tok == '\'') /* quoted user name */
- {
- user_name.ptr = tok + 1;
- user_name.len = flp->cur - tok - 2;
- }
- else
- {
- user_name.ptr = tok;
- user_name.len = flp->cur - tok;
- }
- plog(" loaded xauth credentials of user '%.*s'"
- , user_name.len
- , user_name.ptr);
- clonetochunk(s->u.xauth_secret.user_name
- , user_name.ptr, user_name.len, "xauth user name");
-
- if (!shift())
- return "missing xauth user password";
- return process_psk_secret(&s->u.xauth_secret.user_password);
+ chunk_t user_name;
+
+ s->kind = PPK_XAUTH;
+
+ if (!shift())
+ return "missing xauth user name";
+ if (*tok == '"' || *tok == '\'') /* quoted user name */
+ {
+ user_name.ptr = tok + 1;
+ user_name.len = flp->cur - tok - 2;
+ }
+ else
+ {
+ user_name.ptr = tok;
+ user_name.len = flp->cur - tok;
+ }
+ plog(" loaded xauth credentials of user '%.*s'"
+ , user_name.len
+ , user_name.ptr);
+ s->u.xauth_secret.user_name = chunk_clone(user_name);
+
+ if (!shift())
+ return "missing xauth user password";
+ return process_psk_secret(&s->u.xauth_secret.user_password);
}
-/* get XAUTH secret from chained secrets lists
+/**
+ * Get XAUTH secret from chained secrets lists
* only one entry is currently supported
*/
-static bool
-xauth_get_secret(xauth_t *xauth_secret)
+static bool xauth_get_secret(xauth_t *xauth_secret)
{
- secret_t *s;
- bool found = FALSE;
+ secret_t *s;
+ bool found = FALSE;
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
+ for (s = secrets; s != NULL; s = s->next)
{
- if (found)
- {
- plog("found multiple xauth secrets - first selected");
- }
- else
- {
- found = TRUE;
- *xauth_secret = s->u.xauth_secret;
- }
+ if (s->kind == PPK_XAUTH)
+ {
+ if (found)
+ {
+ plog("found multiple xauth secrets - first selected");
+ }
+ else
+ {
+ found = TRUE;
+ *xauth_secret = s->u.xauth_secret;
+ }
+ }
}
- }
- return found;
+ return found;
}
-/*
+/**
* find a matching secret
*/
-static bool
-xauth_verify_secret(const xauth_peer_t *peer, const xauth_t *xauth_secret)
+static bool xauth_verify_secret(const xauth_peer_t *peer,
+ const xauth_t *xauth_secret)
{
- bool found = FALSE;
- secret_t *s;
+ bool found = FALSE;
+ secret_t *s;
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
+ for (s = secrets; s != NULL; s = s->next)
{
- if (!same_chunk(xauth_secret->user_name, s->u.xauth_secret.user_name))
- continue;
- found = TRUE;
- if (same_chunk(xauth_secret->user_password, s->u.xauth_secret.user_password))
- return TRUE;
+ if (s->kind == PPK_XAUTH)
+ {
+ if (!chunk_equals(xauth_secret->user_name, s->u.xauth_secret.user_name))
+ {
+ continue;
+ }
+ found = TRUE;
+ if (chunk_equals(xauth_secret->user_password, s->u.xauth_secret.user_password))
+ {
+ return TRUE;
+ }
+ }
}
- }
- plog("xauth user '%.*s' %s"
- , xauth_secret->user_name.len, xauth_secret->user_name.ptr
- , found? "sent wrong password":"not found");
- return FALSE;
+ plog("xauth user '%.*s' %s"
+ , xauth_secret->user_name.len, xauth_secret->user_name.ptr
+ , found? "sent wrong password":"not found");
+ return FALSE;
}
-/*
+/**
* the global xauth_module struct is defined here
*/
xauth_module_t xauth_module;
-/*
- * assign the default xauth functions to any null function pointers
+/**
+ * Assign the default xauth functions to any null function pointers
*/
-void
-xauth_defaults(void)
+void xauth_defaults(void)
{
- if (xauth_module.get_secret == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module: using default get_secret() function")
- )
- xauth_module.get_secret = xauth_get_secret;
- }
- if (xauth_module.verify_secret == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module: using default verify_secret() function")
- )
- xauth_module.verify_secret = xauth_verify_secret;
- }
+ if (xauth_module.get_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module: using default get_secret() function")
+ )
+ xauth_module.get_secret = xauth_get_secret;
+ }
+ if (xauth_module.verify_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module: using default verify_secret() function")
+ )
+ xauth_module.verify_secret = xauth_verify_secret;
+ }
};
-/*
- * process pin read from ipsec.secrets or prompted for it using whack
+/**
+ * Process pin read from ipsec.secrets or prompted for it using whack
*/
-static err_t
-process_pin(secret_t *s, int whackfd)
+static err_t process_pin(secret_t *s, int whackfd)
{
- smartcard_t *sc;
- const char *pin_status = "no pin";
-
- s->kind = PPK_PIN;
-
- /* looking for the smartcard keyword */
- if (!shift() || strncmp(tok, SCX_TOKEN, strlen(SCX_TOKEN)) != 0)
- return "PIN keyword must be followed by %smartcard<reader>:<id>";
-
- sc = scx_add(scx_parse_number_slot_id(tok + strlen(SCX_TOKEN)));
- s->u.smartcard = sc;
- scx_share(sc);
- if (sc->pin.ptr != NULL)
- {
- scx_release_context(sc);
- scx_free_pin(&sc->pin);
- }
- sc->valid = FALSE;
-
- if (!shift())
- return "PIN statement must be terminated either by <pin code>, %pinpad or %prompt";
-
- if (tokeqword("%prompt"))
- {
- shift();
- /* if whackfd exists, whack will be used to prompt for a pin */
- if (whackfd != NULL_FD)
- pin_status = scx_get_pin(sc, whackfd) ? "valid pin" : "invalid pin";
+ smartcard_t *sc;
+ const char *pin_status = "no pin";
+
+ s->kind = PPK_PIN;
+
+ /* looking for the smartcard keyword */
+ if (!shift() || strncmp(tok, SCX_TOKEN, strlen(SCX_TOKEN)) != 0)
+ return "PIN keyword must be followed by %smartcard<reader>:<id>";
+
+ sc = scx_add(scx_parse_number_slot_id(tok + strlen(SCX_TOKEN)));
+ s->u.smartcard = sc;
+ scx_share(sc);
+ if (sc->pin.ptr != NULL)
+ {
+ scx_release_context(sc);
+ scx_free_pin(&sc->pin);
+ }
+ sc->valid = FALSE;
+
+ if (!shift())
+ return "PIN statement must be terminated either by <pin code>, %pinpad or %prompt";
+
+ if (tokeqword("%prompt"))
+ {
+ shift();
+ /* if whackfd exists, whack will be used to prompt for a pin */
+ if (whackfd != NULL_FD)
+ pin_status = scx_get_pin(sc, whackfd) ? "valid pin" : "invalid pin";
+ else
+ pin_status = "pin entry via prompt";
+ }
+ else if (tokeqword("%pinpad"))
+ {
+ chunk_t empty_pin = { "", 0 };
+
+ shift();
+
+ /* pin will be entered via pin pad during verification */
+ sc->pin = chunk_clone(empty_pin);
+ sc->pinpad = TRUE;
+ sc->valid = TRUE;
+ pin_status = "pin entry via pad";
+ if (pkcs11_keep_state)
+ {
+ scx_verify_pin(sc);
+ }
+ }
else
- pin_status = "pin entry via prompt";
- }
- else if (tokeqword("%pinpad"))
- {
- shift();
- /* pin will be entered via pin pad during verification */
- clonetochunk(sc->pin, "", 0, "empty pin");
- sc->pinpad = TRUE;
- sc->valid = TRUE;
- pin_status = "pin entry via pad";
- if (pkcs11_keep_state)
- scx_verify_pin(sc);
- }
- else
- {
- /* we read the pin directly from ipsec.secrets */
- err_t ugh = process_psk_secret(&sc->pin);
- if (ugh != NULL)
- return ugh;
- /* verify the pin */
- pin_status = scx_verify_pin(sc) ? "valid PIN" : "invalid PIN";
- }
+ {
+ /* we read the pin directly from ipsec.secrets */
+ err_t ugh = process_psk_secret(&sc->pin);
+ if (ugh != NULL)
+ return ugh;
+ /* verify the pin */
+ pin_status = scx_verify_pin(sc) ? "valid PIN" : "invalid PIN";
+ }
#ifdef SMARTCARD
- {
- char buf[BUF_LEN];
+ {
+ char buf[BUF_LEN];
- if (sc->any_slot)
- snprintf(buf, BUF_LEN, "any slot");
- else
- snprintf(buf, BUF_LEN, "slot: %lu", sc->slot);
+ if (sc->any_slot)
+ snprintf(buf, BUF_LEN, "any slot");
+ else
+ snprintf(buf, BUF_LEN, "slot: %lu", sc->slot);
- plog(" %s for #%d (%s, id: %s)"
- , pin_status, sc->number, scx_print_slot(sc, ""), sc->id);
- }
+ plog(" %s for #%d (%s, id: %s)"
+ , pin_status, sc->number, scx_print_slot(sc, ""), sc->id);
+ }
#else
- plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
+ plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
#endif
- return NULL;
+ return NULL;
}
-static void
-log_psk(secret_t *s)
+static void log_psk(secret_t *s)
{
- int n = 0;
- char buf[BUF_LEN];
- id_list_t *id_list = s->ids;
-
- if (id_list == NULL)
- {
- n = snprintf(buf, BUF_LEN, "%%any");
- }
- else
- {
- do
+ int n = 0;
+ char buf[BUF_LEN];
+ id_list_t *id_list = s->ids;
+
+ if (id_list == NULL)
{
- n += idtoa(&id_list->id, buf + n, BUF_LEN - n);
- if (n >= BUF_LEN)
- {
- n = BUF_LEN - 1;
- break;
- }
- else if (n < BUF_LEN - 1)
- {
- n += snprintf(buf + n, BUF_LEN - n, " ");
- }
- id_list = id_list->next;
+ n = snprintf(buf, BUF_LEN, "%%any");
}
- while (id_list);
- }
- plog(" loaded shared key for %.*s", n, buf);
+ else
+ {
+ do
+ {
+ n += idtoa(&id_list->id, buf + n, BUF_LEN - n);
+ if (n >= BUF_LEN)
+ {
+ n = BUF_LEN - 1;
+ break;
+ }
+ else if (n < BUF_LEN - 1)
+ {
+ n += snprintf(buf + n, BUF_LEN - n, " ");
+ }
+ id_list = id_list->next;
+ }
+ while (id_list);
+ }
+ plog(" loaded shared key for %.*s", n, buf);
}
-static void
-process_secret(secret_t *s, int whackfd)
+static void process_secret(secret_t *s, int whackfd)
{
- err_t ugh = NULL;
-
- s->kind = PPK_PSK; /* default */
- if (*tok == '"' || *tok == '\'')
- {
- /* old PSK format: just a string */
- log_psk(s);
- ugh = process_psk_secret(&s->u.preshared_secret);
- }
- else if (tokeqword("psk"))
- {
- /* preshared key: quoted string or ttodata format */
- log_psk(s);
- ugh = !shift()? "unexpected end of record in PSK"
- : process_psk_secret(&s->u.preshared_secret);
- }
- else if (tokeqword("rsa"))
- {
- /* RSA key: the fun begins.
- * A braced list of keyword and value pairs.
- */
- s->kind = PPK_RSA;
- if (!shift())
+ err_t ugh = NULL;
+
+ s->kind = PPK_PSK; /* default */
+ if (*tok == '"' || *tok == '\'')
+ {
+ /* old PSK format: just a string */
+ log_psk(s);
+ ugh = process_psk_secret(&s->u.preshared_secret);
+ }
+ else if (tokeqword("psk"))
+ {
+ /* preshared key: quoted string or ttodata format */
+ log_psk(s);
+ ugh = !shift()? "unexpected end of record in PSK"
+ : process_psk_secret(&s->u.preshared_secret);
+ }
+ else if (tokeqword("rsa"))
+ {
+ /* RSA key: the fun begins.
+ * A braced list of keyword and value pairs.
+ */
+ s->kind = PPK_PUBKEY;
+ if (!shift())
+ {
+ ugh = "bad RSA key syntax";
+ }
+ else if (tokeq("{"))
+ {
+ ugh = process_rsa_secret(&s->u.private_key);
+ }
+ else
+ {
+ ugh = process_keyfile(&s->u.private_key, KEY_RSA, whackfd);
+ }
+ }
+ else if (tokeqword("ecdsa"))
+ {
+ s->kind = PPK_PUBKEY;
+ if (!shift())
+ {
+ ugh = "bad ECDSA key syntax";
+ }
+ else
+ {
+ ugh = process_keyfile(&s->u.private_key, KEY_ECDSA, whackfd);
+ }
+ }
+ else if (tokeqword("xauth"))
{
- ugh = "bad RSA key syntax";
+ ugh = process_xauth(s);
}
- else if (tokeq("{"))
+ else if (tokeqword("pin"))
{
- ugh = process_rsa_secret(&s->u.RSA_private_key);
+ ugh = process_pin(s, whackfd);
}
else
{
- ugh = process_rsa_keyfile(&s->u.RSA_private_key, whackfd);
+ ugh = builddiag("unrecognized key format: %s", tok);
}
- }
- else if (tokeqword("xauth"))
- {
- ugh = process_xauth(s);
- }
- else if (tokeqword("pin"))
- {
- ugh = process_pin(s, whackfd);
- }
- else
- {
- ugh = builddiag("unrecognized key format: %s", tok);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s"
- , flp->filename, flp->lino, ugh);
- pfree(s);
- }
- else if (flushline("expected record boundary in key"))
- {
- /* gauntlet has been run: install new secret */
- lock_certs_and_keys("process_secret");
- s->next = secrets;
- secrets = s;
- unlock_certs_and_keys("process_secrets");
- }
-}
-
-static void process_secrets_file(const char *file_pat, int whackfd); /* forward declaration */
-
-static void
-process_secret_records(int whackfd)
-{
- /* read records from ipsec.secrets and load them into our table */
- for (;;)
- {
- (void)flushline(NULL); /* silently ditch leftovers, if any */
- if (flp->bdry == B_file)
- break;
-
- flp->bdry = B_none; /* eat the Record Boundary */
- (void)shift(); /* get real first token */
- if (tokeqword("include"))
+ if (ugh != NULL)
{
- /* an include directive */
- char fn[MAX_TOK_LEN]; /* space for filename (I hope) */
- char *p = fn;
- char *end_prefix = strrchr(flp->filename, '/');
-
- if (!shift())
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of include directive"
- , flp->filename, flp->lino);
- continue; /* abandon this record */
- }
-
- /* if path is relative and including file's pathname has
- * a non-empty dirname, prefix this path with that dirname.
- */
- if (tok[0] != '/' && end_prefix != NULL)
- {
- size_t pl = end_prefix - flp->filename + 1;
-
- /* "clamp" length to prevent problems now;
- * will be rediscovered and reported later.
- */
- if (pl > sizeof(fn))
- pl = sizeof(fn);
- memcpy(fn, flp->filename, pl);
- p += pl;
- }
- if (flp->cur - tok >= &fn[sizeof(fn)] - p)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: include pathname too long"
- , flp->filename, flp->lino);
- continue; /* abandon this record */
- }
- strcpy(p, tok);
- (void) shift(); /* move to Record Boundary, we hope */
- if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename"))
- {
- process_secrets_file(fn, whackfd);
- tok = NULL; /* correct, but probably redundant */
- }
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s"
+ , flp->filename, flp->lino, ugh);
+ free(s);
}
- else
+ else if (flushline("expected record boundary in key"))
{
- /* expecting a list of indices and then the key info */
- secret_t *s = alloc_thing(secret_t, "secret");
+ /* gauntlet has been run: install new secret */
+ lock_certs_and_keys("process_secret");
+ s->next = secrets;
+ secrets = s;
+ unlock_certs_and_keys("process_secrets");
+ }
+}
- s->ids = NULL;
- s->kind = PPK_PSK; /* default */
- setchunk(s->u.preshared_secret, NULL, 0);
- s->next = NULL;
+static void process_secrets_file(const char *file_pat, int whackfd); /* forward declaration */
- for (;;)
- {
- if (tok[0] == '"' || tok[0] == '\'')
+static void process_secret_records(int whackfd)
+{
+ /* read records from ipsec.secrets and load them into our table */
+ for (;;)
+ {
+ (void)flushline(NULL); /* silently ditch leftovers, if any */
+ if (flp->bdry == B_file)
{
- /* found key part */
- process_secret(s, whackfd);
- break;
+ break;
}
- else if (tokeq(":"))
+ flp->bdry = B_none; /* eat the Record Boundary */
+ (void)shift(); /* get real first token */
+
+ if (tokeqword("include"))
{
- /* found key part */
- shift(); /* discard explicit separator */
- process_secret(s, whackfd);
- break;
+ /* an include directive */
+ char fn[MAX_TOK_LEN]; /* space for filename (I hope) */
+ char *p = fn;
+ char *end_prefix = strrchr(flp->filename, '/');
+
+ if (!shift())
+ {
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of include directive"
+ , flp->filename, flp->lino);
+ continue; /* abandon this record */
+ }
+
+ /* if path is relative and including file's pathname has
+ * a non-empty dirname, prefix this path with that dirname.
+ */
+ if (tok[0] != '/' && end_prefix != NULL)
+ {
+ size_t pl = end_prefix - flp->filename + 1;
+
+ /* "clamp" length to prevent problems now;
+ * will be rediscovered and reported later.
+ */
+ if (pl > sizeof(fn))
+ {
+ pl = sizeof(fn);
+ }
+ memcpy(fn, flp->filename, pl);
+ p += pl;
+ }
+ if (flp->cur - tok >= &fn[sizeof(fn)] - p)
+ {
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: include pathname too long"
+ , flp->filename, flp->lino);
+ continue; /* abandon this record */
+ }
+ strcpy(p, tok);
+ (void) shift(); /* move to Record Boundary, we hope */
+ if (flushline("ignoring malformed INCLUDE -- expected Record Boundary after filename"))
+ {
+ process_secrets_file(fn, whackfd);
+ tok = NULL; /* correct, but probably redundant */
+ }
}
else
{
- /* an id
- * See RFC2407 IPsec Domain of Interpretation 4.6.2
- */
- struct id id;
- err_t ugh;
-
- if (tokeq("%any"))
- {
- id = empty_id;
- id.kind = ID_IPV4_ADDR;
- ugh = anyaddr(AF_INET, &id.ip_addr);
- }
- else if (tokeq("%any6"))
- {
- id = empty_id;
- id.kind = ID_IPV6_ADDR;
- ugh = anyaddr(AF_INET6, &id.ip_addr);
- }
- else
- {
- ugh = atoid(tok, &id, FALSE);
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS
- , "ERROR \"%s\" line %d: index \"%s\" %s"
- , flp->filename, flp->lino, tok, ugh);
- }
- else
- {
- id_list_t *i = alloc_thing(id_list_t
- , "id_list");
-
- i->id = id;
- unshare_id_content(&i->id);
- i->next = s->ids;
- s->ids = i;
- /* DBG_log("id type %d: %s %.*s", i->kind, ip_str(&i->ip_addr), (int)i->name.len, i->name.ptr); */
- }
- if (!shift())
- {
- /* unexpected Record Boundary or EOF */
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of id list"
- , flp->filename, flp->lino);
- break;
- }
+ /* expecting a list of indices and then the key info */
+ secret_t *s = malloc_thing(secret_t);
+
+ zero(s);
+ s->ids = NULL;
+ s->kind = PPK_PSK; /* default */
+ s->u.preshared_secret = chunk_empty;
+ s->next = NULL;
+
+ for (;;)
+ {
+ if (tok[0] == '"' || tok[0] == '\'')
+ {
+ /* found key part */
+ process_secret(s, whackfd);
+ break;
+ }
+ else if (tokeq(":"))
+ {
+ /* found key part */
+ shift(); /* discard explicit separator */
+ process_secret(s, whackfd);
+ break;
+ }
+ else
+ {
+ /* an id
+ * See RFC2407 IPsec Domain of Interpretation 4.6.2
+ */
+ struct id id;
+ err_t ugh;
+
+ if (tokeq("%any"))
+ {
+ id = empty_id;
+ id.kind = ID_IPV4_ADDR;
+ ugh = anyaddr(AF_INET, &id.ip_addr);
+ }
+ else if (tokeq("%any6"))
+ {
+ id = empty_id;
+ id.kind = ID_IPV6_ADDR;
+ ugh = anyaddr(AF_INET6, &id.ip_addr);
+ }
+ else
+ {
+ ugh = atoid(tok, &id, FALSE);
+ }
+
+ if (ugh != NULL)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ERROR \"%s\" line %d: index \"%s\" %s"
+ , flp->filename, flp->lino, tok, ugh);
+ }
+ else
+ {
+ id_list_t *i = malloc_thing(id_list_t);
+
+ i->id = id;
+ unshare_id_content(&i->id);
+ i->next = s->ids;
+ s->ids = i;
+ /* DBG_log("id type %d: %s %.*s", i->kind, ip_str(&i->ip_addr), (int)i->name.len, i->name.ptr); */
+ }
+ if (!shift())
+ {
+ /* unexpected Record Boundary or EOF */
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unexpected end of id list"
+ , flp->filename, flp->lino);
+ break;
+ }
+ }
+ }
}
- }
}
- }
}
-static int
-globugh(const char *epath, int eerrno)
+static int globugh(const char *epath, int eerrno)
{
- log_errno_routine(eerrno, "problem with secrets file \"%s\"", epath);
- return 1; /* stop glob */
+ log_errno_routine(eerrno, "problem with secrets file \"%s\"", epath);
+ return 1; /* stop glob */
}
-static void
-process_secrets_file(const char *file_pat, int whackfd)
+static void process_secrets_file(const char *file_pat, int whackfd)
{
- struct file_lex_position pos;
- char **fnp;
- glob_t globbuf;
-
- pos.depth = flp == NULL? 0 : flp->depth + 1;
+ struct file_lex_position pos;
+ char **fnp;
+ glob_t globbuf;
- if (pos.depth > 10)
- {
- loglog(RC_LOG_SERIOUS, "preshared secrets file \"%s\" nested too deeply", file_pat);
- return;
- }
+ pos.depth = flp == NULL? 0 : flp->depth + 1;
- /* do globbing */
- {
- int r = glob(file_pat, GLOB_ERR, globugh, &globbuf);
+ if (pos.depth > 10)
+ {
+ loglog(RC_LOG_SERIOUS, "preshared secrets file \"%s\" nested too deeply", file_pat);
+ return;
+ }
- if (r != 0)
+ /* do globbing */
{
- switch (r)
- {
- case GLOB_NOSPACE:
- loglog(RC_LOG_SERIOUS, "out of space processing secrets filename \"%s\"", file_pat);
- break;
- case GLOB_ABORTED:
- break; /* already logged */
- case GLOB_NOMATCH:
- loglog(RC_LOG_SERIOUS, "no secrets filename matched \"%s\"", file_pat);
- break;
- default:
- loglog(RC_LOG_SERIOUS, "unknown glob error %d", r);
- break;
- }
- globfree(&globbuf);
- return;
+ int r = glob(file_pat, GLOB_ERR, globugh, &globbuf);
+
+ if (r != 0)
+ {
+ switch (r)
+ {
+ case GLOB_NOSPACE:
+ loglog(RC_LOG_SERIOUS, "out of space processing secrets filename \"%s\"", file_pat);
+ break;
+ case GLOB_ABORTED:
+ break; /* already logged */
+ case GLOB_NOMATCH:
+ loglog(RC_LOG_SERIOUS, "no secrets filename matched \"%s\"", file_pat);
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "unknown glob error %d", r);
+ break;
+ }
+ globfree(&globbuf);
+ return;
+ }
}
- }
- /* for each file... */
- for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
- {
- if (lexopen(&pos, *fnp, FALSE))
+ /* for each file... */
+ for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
{
- plog("loading secrets from \"%s\"", *fnp);
- (void) flushline("file starts with indentation (continuation notation)");
- process_secret_records(whackfd);
- lexclose();
+ if (lexopen(&pos, *fnp, FALSE))
+ {
+ plog("loading secrets from \"%s\"", *fnp);
+ (void) flushline("file starts with indentation (continuation notation)");
+ process_secret_records(whackfd);
+ lexclose();
+ }
}
- }
- globfree(&globbuf);
+ globfree(&globbuf);
}
-void
-free_preshared_secrets(void)
+void free_preshared_secrets(void)
{
- lock_certs_and_keys("free_preshared_secrets");
+ lock_certs_and_keys("free_preshared_secrets");
- if (secrets != NULL)
- {
- secret_t *s, *ns;
+ if (secrets != NULL)
+ {
+ secret_t *s, *ns;
- plog("forgetting secrets");
+ plog("forgetting secrets");
- for (s = secrets; s != NULL; s = ns)
- {
- id_list_t *i, *ni;
-
- ns = s->next; /* grab before freeing s */
- for (i = s->ids; i != NULL; i = ni)
- {
- ni = i->next; /* grab before freeing i */
- free_id_content(&i->id);
- pfree(i);
- }
- switch (s->kind)
- {
- case PPK_PSK:
- pfree(s->u.preshared_secret.ptr);
- break;
- case PPK_RSA:
- free_RSA_private_content(&s->u.RSA_private_key);
- break;
- case PPK_XAUTH:
- pfree(s->u.xauth_secret.user_name.ptr);
- pfree(s->u.xauth_secret.user_password.ptr);
- break;
- case PPK_PIN:
- scx_release(s->u.smartcard);
- break;
- default:
- bad_case(s->kind);
- }
- pfree(s);
+ for (s = secrets; s != NULL; s = ns)
+ {
+ id_list_t *i, *ni;
+
+ ns = s->next; /* grab before freeing s */
+ for (i = s->ids; i != NULL; i = ni)
+ {
+ ni = i->next; /* grab before freeing i */
+ free_id_content(&i->id);
+ free(i);
+ }
+ switch (s->kind)
+ {
+ case PPK_PSK:
+ free(s->u.preshared_secret.ptr);
+ break;
+ case PPK_PUBKEY:
+ DESTROY_IF(s->u.private_key);
+ break;
+ case PPK_XAUTH:
+ free(s->u.xauth_secret.user_name.ptr);
+ free(s->u.xauth_secret.user_password.ptr);
+ break;
+ case PPK_PIN:
+ scx_release(s->u.smartcard);
+ break;
+ default:
+ bad_case(s->kind);
+ }
+ free(s);
+ }
+ secrets = NULL;
}
- secrets = NULL;
- }
- unlock_certs_and_keys("free_preshard_secrets");
+ unlock_certs_and_keys("free_preshard_secrets");
}
-void
-load_preshared_secrets(int whackfd)
+void load_preshared_secrets(int whackfd)
{
- free_preshared_secrets();
- (void) process_secrets_file(shared_secrets_file, whackfd);
+ free_preshared_secrets();
+ (void) process_secrets_file(shared_secrets_file, whackfd);
}
/* public key machinery
* Note: caller must set dns_auth_level.
*/
-pubkey_t *
-public_key_from_rsa(const RSA_public_key_t *k)
+pubkey_t* public_key_from_rsa(public_key_t *key)
{
- pubkey_t *p = alloc_thing(pubkey_t, "pubkey");
-
- p->id = empty_id; /* don't know, doesn't matter */
- p->issuer = empty_chunk;
- p->serial = empty_chunk;
- p->alg = PUBKEY_ALG_RSA;
-
- memcpy(p->u.rsa.keyid, k->keyid, sizeof(p->u.rsa.keyid));
- p->u.rsa.k = k->k;
- mpz_init_set(&p->u.rsa.e, &k->e);
- mpz_init_set(&p->u.rsa.n, &k->n);
-
- /* note that we return a 1 reference count upon creation:
- * invariant: recount > 0.
- */
- p->refcnt = 1;
- time(&p->installed_time);
- return p;
+ pubkey_t *p = malloc_thing(pubkey_t);
+
+ zero(p);
+ p->id = empty_id; /* don't know, doesn't matter */
+ p->issuer = chunk_empty;
+ p->serial = chunk_empty;
+ p->public_key = key;
+
+ /* note that we return a 1 reference count upon creation:
+ * invariant: recount > 0.
+ */
+ p->refcnt = 1;
+ time(&p->installed_time);
+ return p;
}
/* Free a public key record.
* As a convenience, this returns a pointer to next.
*/
-pubkey_list_t *
-free_public_keyentry(pubkey_list_t *p)
+pubkey_list_t* free_public_keyentry(pubkey_list_t *p)
{
- pubkey_list_t *nxt = p->next;
+ pubkey_list_t *nxt = p->next;
- if (p->key != NULL)
- unreference_key(&p->key);
- pfree(p);
- return nxt;
+ if (p->key != NULL)
+ {
+ unreference_key(&p->key);
+ }
+ free(p);
+ return nxt;
}
-void
-free_public_keys(pubkey_list_t **keys)
+void free_public_keys(pubkey_list_t **keys)
{
- while (*keys != NULL)
- *keys = free_public_keyentry(*keys);
+ while (*keys != NULL)
+ {
+ *keys = free_public_keyentry(*keys);
+ }
}
/* root of chained public key list */
-pubkey_list_t *pubkeys = NULL; /* keys from ipsec.conf */
+pubkey_list_t *pubkeys = NULL; /* keys from ipsec.conf */
-void
-free_remembered_public_keys(void)
+void free_remembered_public_keys(void)
{
- free_public_keys(&pubkeys);
+ free_public_keys(&pubkeys);
}
-/* transfer public keys from *keys list to front of pubkeys list */
-void
-transfer_to_public_keys(struct gw_info *gateways_from_dns
+/**
+ * Transfer public keys from *keys list to front of pubkeys list
+ */
+void transfer_to_public_keys(struct gw_info *gateways_from_dns
#ifdef USE_KEYRR
, pubkey_list_t **keys
#endif /* USE_KEYRR */
)
{
- {
- struct gw_info *gwp;
-
- for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
{
- pubkey_list_t *pl = alloc_thing(pubkey_list_t, "from TXT");
+ struct gw_info *gwp;
- pl->key = gwp->key; /* note: this is a transfer */
- gwp->key = NULL; /* really, it is! */
- pl->next = pubkeys;
- pubkeys = pl;
+ for (gwp = gateways_from_dns; gwp != NULL; gwp = gwp->next)
+ {
+ pubkey_list_t *pl = malloc_thing(pubkey_list_t);
+
+ pl->key = gwp->key; /* note: this is a transfer */
+ gwp->key = NULL; /* really, it is! */
+ pl->next = pubkeys;
+ pubkeys = pl;
+ }
}
- }
#ifdef USE_KEYRR
- {
- pubkey_list_t **pp = keys;
-
- while (*pp != NULL)
- pp = &(*pp)->next;
- *pp = pubkeys;
- pubkeys = *keys;
- *keys = NULL;
- }
+ {
+ pubkey_list_t **pp = keys;
+
+ while (*pp != NULL)
+ {
+ pp = &(*pp)->next;
+ }
+ *pp = pubkeys;
+ pubkeys = *keys;
+ *keys = NULL;
+ }
#endif /* USE_KEYRR */
}
-/* decode of RSA pubkey chunk
- * - format specified in RFC 2537 RSA/MD5 Keys and SIGs in the DNS
- * - exponent length in bytes (1 or 3 octets)
- * + 1 byte if in [1, 255]
- * + otherwise 0x00 followed by 2 bytes of length
- * - exponent
- * - modulus
- */
-err_t
-unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey)
-{
- chunk_t exp;
- chunk_t mod;
-
- if (pubkey->len < 3)
- return "RSA public key blob way to short"; /* not even room for length! */
-
- if (pubkey->ptr[0] != 0x00)
- {
- setchunk(exp, pubkey->ptr + 1, pubkey->ptr[0]);
- }
- else
- {
- setchunk(exp, pubkey->ptr + 3
- , (pubkey->ptr[1] << BITS_PER_BYTE) + pubkey->ptr[2]);
- }
-
- if (pubkey->len - (exp.ptr - pubkey->ptr) < exp.len + RSA_MIN_OCTETS_RFC)
- return "RSA public key blob too short";
-
- mod.ptr = exp.ptr + exp.len;
- mod.len = &pubkey->ptr[pubkey->len] - mod.ptr;
-
- if (mod.len < RSA_MIN_OCTETS)
- return RSA_MIN_OCTETS_UGH;
-
- if (mod.len > RSA_MAX_OCTETS)
- return RSA_MAX_OCTETS_UGH;
-
- init_RSA_public_key(rsa, exp, mod);
- rsa->k = mpz_sizeinbase(&rsa->n, 2); /* size in bits, for a start */
- rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */
- DBG(DBG_RAW,
- RSA_show_public_key(rsa)
- )
-
- if (rsa->k != mod.len)
- {
- mpz_clear(&rsa->e);
- mpz_clear(&rsa->n);
- return "RSA modulus shorter than specified";
- }
-
- return NULL;
-}
-static void
-install_public_key(pubkey_t *pk, pubkey_list_t **head)
+static void install_public_key(pubkey_t *pk, pubkey_list_t **head)
{
- pubkey_list_t *p = alloc_thing(pubkey_list_t, "pubkey entry");
+ pubkey_list_t *p = malloc_thing(pubkey_list_t);
- unshare_id_content(&pk->id);
+ unshare_id_content(&pk->id);
- /* copy issuer dn */
- if (pk->issuer.ptr != NULL)
- pk->issuer.ptr = clone_bytes(pk->issuer.ptr, pk->issuer.len, "issuer dn");
+ /* copy issuer dn */
+ pk->issuer = chunk_clone(pk->issuer);
- /* copy serial number */
- if (pk->serial.ptr != NULL)
- pk->serial.ptr = clone_bytes(pk->serial.ptr, pk->serial.len, "serialNumber");
+ /* copy serial number */
+ pk->serial = chunk_clone(pk->serial);
- /* store the time the public key was installed */
- time(&pk->installed_time);
+ /* store the time the public key was installed */
+ time(&pk->installed_time);
- /* install new key at front */
- p->key = reference_key(pk);
- p->next = *head;
- *head = p;
+ /* install new key at front */
+ p->key = reference_key(pk);
+ p->next = *head;
+ *head = p;
}
-
-void
-delete_public_keys(const struct id *id, enum pubkey_alg alg
-, chunk_t issuer, chunk_t serial)
+void delete_public_keys(const struct id *id, key_type_t type,
+ chunk_t issuer, chunk_t serial)
{
- pubkey_list_t **pp, *p;
- pubkey_t *pk;
-
- for (pp = &pubkeys; (p = *pp) != NULL; )
- {
- pk = p->key;
-
- if (same_id(id, &pk->id) && pk->alg == alg
- && (issuer.ptr == NULL || pk->issuer.ptr == NULL
- || same_dn(issuer, pk->issuer))
- && same_serial(serial, pk->serial))
- *pp = free_public_keyentry(p);
- else
- pp = &p->next;
- }
+ pubkey_list_t **pp, *p;
+ pubkey_t *pk;
+ key_type_t pk_type;
+
+ for (pp = &pubkeys; (p = *pp) != NULL; )
+ {
+ pk = p->key;
+ pk_type = pk->public_key->get_type(pk->public_key);
+
+ if (same_id(id, &pk->id) && pk_type == type
+ && (issuer.ptr == NULL || pk->issuer.ptr == NULL
+ || same_dn(issuer, pk->issuer))
+ && same_serial(serial, pk->serial))
+ {
+ *pp = free_public_keyentry(p);
+ }
+ else
+ {
+ pp = &p->next;
+ }
+ }
}
-pubkey_t *
-reference_key(pubkey_t *pk)
+pubkey_t* reference_key(pubkey_t *pk)
{
- pk->refcnt++;
- return pk;
+ pk->refcnt++;
+ return pk;
}
void
unreference_key(pubkey_t **pkp)
{
- pubkey_t *pk = *pkp;
- char b[BUF_LEN];
+ pubkey_t *pk = *pkp;
+ char b[BUF_LEN];
- if (pk == NULL)
- return;
+ if (pk == NULL)
+ {
+ return;
+ }
- /* print stuff */
- DBG(DBG_CONTROLMORE,
- idtoa(&pk->id, b, sizeof(b));
- DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt)
- )
+ /* print stuff */
+ DBG(DBG_CONTROLMORE,
+ idtoa(&pk->id, b, sizeof(b));
+ DBG_log("unreference key: %p %s cnt %d--", pk, b, pk->refcnt)
+ )
- /* cancel out the pointer */
- *pkp = NULL;
+ /* cancel out the pointer */
+ *pkp = NULL;
- passert(pk->refcnt != 0);
- pk->refcnt--;
- if (pk->refcnt == 0)
- free_public_key(pk);
+ passert(pk->refcnt != 0);
+ pk->refcnt--;
+ if (pk->refcnt == 0)
+ {
+ free_public_key(pk);
+ }
}
-err_t
-add_public_key(const struct id *id
-, enum dns_auth_level dns_auth_level
-, enum pubkey_alg alg
-, const chunk_t *key
-, pubkey_list_t **head)
+bool add_public_key(const struct id *id, enum dns_auth_level dns_auth_level,
+ enum pubkey_alg alg, chunk_t rfc3110_key,
+ pubkey_list_t **head)
{
- pubkey_t *pk = alloc_thing(pubkey_t, "pubkey");
+ public_key_t *key = NULL;
+ pubkey_t *pk;
- /* first: algorithm-specific decoding of key chunk */
- switch (alg)
- {
- case PUBKEY_ALG_RSA:
+ /* first: algorithm-specific decoding of key chunk */
+ switch (alg)
{
- err_t ugh = unpack_RSA_public_key(&pk->u.rsa, key);
-
- if (ugh != NULL)
- {
- pfree(pk);
- return ugh;
- }
+ case PUBKEY_ALG_RSA:
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_RFC_3110, rfc3110_key,
+ BUILD_END);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ break;
+ default:
+ bad_case(alg);
}
- break;
- default:
- bad_case(alg);
- }
-
- pk->id = *id;
- pk->dns_auth_level = dns_auth_level;
- pk->alg = alg;
- pk->until_time = UNDEFINED_TIME;
- pk->issuer = empty_chunk;
- pk->serial = empty_chunk;
-
- install_public_key(pk, head);
- return NULL;
+
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ pk->public_key = key;
+ pk->id = *id;
+ pk->dns_auth_level = dns_auth_level;
+ pk->until_time = UNDEFINED_TIME;
+ pk->issuer = chunk_empty;
+ pk->serial = chunk_empty;
+ install_public_key(pk, head);
+ return TRUE;
}
/* extract id and public key from x.509 certificate and
* insert it into a pubkeyrec
*/
-void
-add_x509_public_key(x509cert_t *cert , time_t until
- , enum dns_auth_level dns_auth_level)
+void add_x509_public_key(x509cert_t *cert , time_t until,
+ enum dns_auth_level dns_auth_level)
{
- generalName_t *gn;
- pubkey_t *pk;
- cert_t c = { CERT_X509_SIGNATURE, {cert} };
-
- /* we support RSA only */
- if (cert->subjectPublicKeyAlgorithm != PUBKEY_ALG_RSA)
- return;
-
- /* ID type: ID_DER_ASN1_DN (X.509 subject field) */
- pk = allocate_RSA_public_key(c);
- pk->id.kind = ID_DER_ASN1_DN;
- pk->id.name = cert->subject;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- pk->issuer = cert->issuer;
- pk->serial = cert->serialNumber;
- delete_public_keys(&pk->id, pk->alg, pk->issuer, pk->serial);
- install_public_key(pk, &pubkeys);
-
- gn = cert->subjectAltName;
-
- while (gn != NULL) /* insert all subjectAltNames */
- {
- struct id id = empty_id;
-
- gntoid(&id, gn);
- if (id.kind != ID_NONE)
+ generalName_t *gn;
+ pubkey_t *pk;
+ key_type_t pk_type;
+
+ /* ID type: ID_DER_ASN1_DN (X.509 subject field) */
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ pk->public_key = cert->public_key->get_ref(cert->public_key);
+ pk->id.kind = ID_DER_ASN1_DN;
+ pk->id.name = cert->subject;
+ pk->dns_auth_level = dns_auth_level;
+ pk->until_time = until;
+ pk->issuer = cert->issuer;
+ pk->serial = cert->serialNumber;
+ pk_type = pk->public_key->get_type(pk->public_key);
+ delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial);
+ install_public_key(pk, &pubkeys);
+
+ gn = cert->subjectAltName;
+
+ while (gn != NULL) /* insert all subjectAltNames */
{
- pk = allocate_RSA_public_key(c);
- pk->id = id;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- pk->issuer = cert->issuer;
- pk->serial = cert->serialNumber;
- delete_public_keys(&pk->id, pk->alg, pk->issuer, pk->serial);
- install_public_key(pk, &pubkeys);
+ struct id id = empty_id;
+
+ gntoid(&id, gn);
+ if (id.kind != ID_ANY)
+ {
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ pk->public_key = cert->public_key->get_ref(cert->public_key);
+ pk->id = id;
+ pk->dns_auth_level = dns_auth_level;
+ pk->until_time = until;
+ pk->issuer = cert->issuer;
+ pk->serial = cert->serialNumber;
+ delete_public_keys(&pk->id, pk_type, pk->issuer, pk->serial);
+ install_public_key(pk, &pubkeys);
+ }
+ gn = gn->next;
}
- gn = gn->next;
- }
}
/* extract id and public key from OpenPGP certificate and
* insert it into a pubkeyrec
*/
-void
-add_pgp_public_key(pgpcert_t *cert , time_t until
- , enum dns_auth_level dns_auth_level)
+void add_pgp_public_key(pgpcert_t *cert , time_t until,
+ enum dns_auth_level dns_auth_level)
{
- pubkey_t *pk;
- cert_t c;
-
- c.type = CERT_PGP;
- c.u.pgp = cert;
-
- /* we support RSA only */
- if (cert->pubkeyAlg != PUBKEY_ALG_RSA)
- {
- plog(" RSA public keys supported only");
- return;
- }
-
- pk = allocate_RSA_public_key(c);
- pk->id.kind = ID_KEY_ID;
- pk->id.name.ptr = cert->fingerprint;
- pk->id.name.len = PGP_FINGERPRINT_SIZE;
- pk->dns_auth_level = dns_auth_level;
- pk->until_time = until;
- delete_public_keys(&pk->id, pk->alg, empty_chunk, empty_chunk);
- install_public_key(pk, &pubkeys);
+ pubkey_t *pk;
+ key_type_t pk_type;
+
+ pk = malloc_thing(pubkey_t);
+ zero(pk);
+ pk->public_key = cert->public_key->get_ref(cert->public_key);
+ pk->id.kind = ID_KEY_ID;
+ pk->id.name = cert->fingerprint->get_encoding(cert->fingerprint);
+ pk->dns_auth_level = dns_auth_level;
+ pk->until_time = until;
+ pk_type = pk->public_key->get_type(pk->public_key);
+ delete_public_keys(&pk->id, pk_type, chunk_empty, chunk_empty);
+ install_public_key(pk, &pubkeys);
}
/* when a X.509 certificate gets revoked, all instances of
* the corresponding public key must be removed
*/
-void
-remove_x509_public_key(const x509cert_t *cert)
+void remove_x509_public_key(const x509cert_t *cert)
{
- const cert_t c = {CERT_X509_SIGNATURE, {(x509cert_t*)cert}};
- pubkey_list_t *p, **pp;
- pubkey_t *revoked_pk;
+ public_key_t *revoked_key = cert->public_key;
+ pubkey_list_t *p, **pp;
- revoked_pk = allocate_RSA_public_key(c);
- p = pubkeys;
- pp = &pubkeys;
+ p = pubkeys;
+ pp = &pubkeys;
- while(p != NULL)
- {
- if (same_RSA_public_key(&p->key->u.rsa, &revoked_pk->u.rsa))
- {
- /* remove p from list and free memory */
- *pp = free_public_keyentry(p);
- loglog(RC_LOG_SERIOUS,
- "invalid RSA public key deleted");
- }
- else
+ while(p != NULL)
{
- pp = &p->next;
+ if (revoked_key->equals(revoked_key, p->key->public_key))
+ {
+ /* remove p from list and free memory */
+ *pp = free_public_keyentry(p);
+ loglog(RC_LOG_SERIOUS, "invalid public key deleted");
+ }
+ else
+ {
+ pp = &p->next;
+ }
+ p =*pp;
}
- p =*pp;
- }
- free_public_key(revoked_pk);
}
/*
@@ -1504,45 +1419,41 @@ remove_x509_public_key(const x509cert_t *cert)
*/
void list_public_keys(bool utc)
{
- pubkey_list_t *p = pubkeys;
-
- if (p != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Public Keys:");
- whack_log(RC_COMMENT, " ");
- }
+ pubkey_list_t *p = pubkeys;
- while (p != NULL)
- {
- pubkey_t *key = p->key;
+ if (p != NULL)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of Public Keys:");
+ whack_log(RC_COMMENT, " ");
+ }
- if (key->alg == PUBKEY_ALG_RSA)
+ while (p != NULL)
{
- char buf[BUF_LEN];
- char expires_buf[TIMETOA_BUF];
-
- idtoa(&key->id, buf, BUF_LEN);
- strcpy(expires_buf, timetoa(&key->until_time, utc));
- whack_log(RC_COMMENT, "%s, %4d RSA Key %s, until %s %s",
-
- timetoa(&key->installed_time, utc), 8*key->u.rsa.k, key->u.rsa.keyid,
- expires_buf,
- check_expiry(key->until_time, PUBKEY_WARNING_INTERVAL, TRUE));
- whack_log(RC_COMMENT," %s '%s'",
- enum_show(&ident_names, key->id.kind), buf);
- if (key->issuer.len > 0)
- {
- dntoa(buf, BUF_LEN, key->issuer);
- whack_log(RC_COMMENT," issuer: '%s'", buf);
- }
- if (key->serial.len > 0)
- {
- datatot(key->serial.ptr, key->serial.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT," serial: %s", buf);
- }
+ pubkey_t *key = p->key;
+ public_key_t *public = key->public_key;
+ identification_t *keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+ char buf[BUF_LEN];
+
+ idtoa(&key->id, buf, BUF_LEN);
+ whack_log(RC_COMMENT,"%T, '%s'", &key->installed_time, utc, buf);
+ whack_log(RC_COMMENT, " pubkey: %N %4d bits, until %T %s",
+ key_type_names, public->get_type(public),
+ public->get_keysize(public) * BITS_PER_BYTE,
+ &key->until_time, utc,
+ check_expiry(key->until_time, PUBKEY_WARNING_INTERVAL, TRUE));
+ whack_log(RC_COMMENT," keyid: %Y", keyid);
+ if (key->issuer.len > 0)
+ {
+ dntoa(buf, BUF_LEN, key->issuer);
+ whack_log(RC_COMMENT," issuer: '%s'", buf);
+ }
+ if (key->serial.len > 0)
+ {
+ datatot(key->serial.ptr, key->serial.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT," serial: %s", buf);
+ }
+ p = p->next;
}
- p = p->next;
- }
}
diff --git a/src/pluto/keys.h b/src/pluto/keys.h
index b06e536a5..8bc94d839 100644
--- a/src/pluto/keys.h
+++ b/src/pluto/keys.h
@@ -1,5 +1,6 @@
/* mechanisms for preshared keys (public, private, and preshared secrets)
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen, Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,16 +11,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: keys.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _KEYS_H
#define _KEYS_H
-#include <gmp.h> /* GNU Multi-Precision library */
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
-#include "pkcs1.h"
#include "certs.h"
#ifndef SHARED_SECRETS_FILE
@@ -32,11 +31,10 @@ extern void load_preshared_secrets(int whackfd);
extern void free_preshared_secrets(void);
enum PrivateKeyKind {
- PPK_PSK,
- /* PPK_DSS, */ /* not implemented */
- PPK_RSA,
- PPK_XAUTH,
- PPK_PIN
+ PPK_PSK,
+ PPK_PUBKEY,
+ PPK_XAUTH,
+ PPK_PIN
};
extern void xauth_defaults(void);
@@ -45,69 +43,64 @@ extern void xauth_defaults(void);
struct connection;
extern const chunk_t *get_preshared_secret(const struct connection *c);
-extern err_t unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey);
-extern const RSA_private_key_t *get_RSA_private_key(const struct connection *c);
-extern const RSA_private_key_t *get_x509_private_key(const x509cert_t *cert);
+extern private_key_t *get_private_key(const struct connection *c);
+extern private_key_t *get_x509_private_key(const x509cert_t *cert);
/* public key machinery */
typedef struct pubkey pubkey_t;
struct pubkey {
- struct id id;
- unsigned refcnt; /* reference counted! */
- enum dns_auth_level dns_auth_level;
- char *dns_sig;
- time_t installed_time
- , last_tried_time
- , last_worked_time
- , until_time;
- chunk_t issuer;
- chunk_t serial;
- enum pubkey_alg alg;
- union {
- RSA_public_key_t rsa;
- } u;
+ struct id id;
+ unsigned refcnt; /* reference counted! */
+ enum dns_auth_level dns_auth_level;
+ char *dns_sig;
+ time_t installed_time
+ , last_tried_time
+ , last_worked_time
+ , until_time;
+ chunk_t issuer;
+ chunk_t serial;
+ public_key_t *public_key;
};
typedef struct pubkey_list pubkey_list_t;
struct pubkey_list {
- pubkey_t *key;
- pubkey_list_t *next;
+ pubkey_t *key;
+ pubkey_list_t *next;
};
-extern pubkey_list_t *pubkeys; /* keys from ipsec.conf or from certs */
+extern pubkey_list_t *pubkeys; /* keys from ipsec.conf or from certs */
-extern pubkey_t *public_key_from_rsa(const RSA_public_key_t *k);
+extern pubkey_t *public_key_from_rsa(public_key_t *key);
extern pubkey_list_t *free_public_keyentry(pubkey_list_t *p);
extern void free_public_keys(pubkey_list_t **keys);
extern void free_remembered_public_keys(void);
-extern void delete_public_keys(const struct id *id, enum pubkey_alg alg
- , chunk_t issuer, chunk_t serial);
-
+extern void delete_public_keys(const struct id *id, key_type_t type,
+ chunk_t issuer, chunk_t serial);
extern pubkey_t *reference_key(pubkey_t *pk);
extern void unreference_key(pubkey_t **pkp);
-extern err_t add_public_key(const struct id *id
- , enum dns_auth_level dns_auth_level
- , enum pubkey_alg alg
- , const chunk_t *key
- , pubkey_list_t **head);
+extern bool add_public_key(const struct id *id,
+ enum dns_auth_level dns_auth_level,
+ enum pubkey_alg alg,
+ chunk_t rfc3110_key,
+ pubkey_list_t **head);
extern bool has_private_key(cert_t cert);
extern void add_x509_public_key(x509cert_t *cert, time_t until
- , enum dns_auth_level dns_auth_level);
+ , enum dns_auth_level dns_auth_level);
extern void add_pgp_public_key(pgpcert_t *cert, time_t until
- , enum dns_auth_level dns_auth_level);
+ , enum dns_auth_level dns_auth_level);
extern void remove_x509_public_key(const x509cert_t *cert);
extern void list_public_keys(bool utc);
-struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
+struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
extern void transfer_to_public_keys(struct gw_info *gateways_from_dns
#ifdef USE_KEYRR
- , pubkey_list_t **keys
+ , pubkey_list_t **keys
#endif /* USE_KEYRR */
- );
+ );
#endif /* _KEYS_H */
diff --git a/src/pluto/lex.c b/src/pluto/lex.c
index 08ab43876..f48d24a54 100644
--- a/src/pluto/lex.c
+++ b/src/pluto/lex.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: lex.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include "lex.h"
struct file_lex_position *flp = NULL;
@@ -39,36 +37,36 @@ struct file_lex_position *flp = NULL;
bool
lexopen(struct file_lex_position *new_flp, const char *name, bool optional)
{
- FILE *f = fopen(name, "r");
-
- if (f == NULL)
- {
- if (!optional || errno != ENOENT)
- log_errno((e, "could not open \"%s\"", name));
- return FALSE;
- }
- else
- {
- new_flp->previous = flp;
- flp = new_flp;
- flp->filename = name;
- flp->fp = f;
- flp->lino = 0;
- flp->bdry = B_none;
-
- flp->cur = flp->buffer; /* nothing loaded yet */
- flp->under = *flp->cur = '\0';
-
- (void) shift(); /* prime tok */
- return TRUE;
- }
+ FILE *f = fopen(name, "r");
+
+ if (f == NULL)
+ {
+ if (!optional || errno != ENOENT)
+ log_errno((e, "could not open \"%s\"", name));
+ return FALSE;
+ }
+ else
+ {
+ new_flp->previous = flp;
+ flp = new_flp;
+ flp->filename = name;
+ flp->fp = f;
+ flp->lino = 0;
+ flp->bdry = B_none;
+
+ flp->cur = flp->buffer; /* nothing loaded yet */
+ flp->under = *flp->cur = '\0';
+
+ (void) shift(); /* prime tok */
+ return TRUE;
+ }
}
void
lexclose(void)
{
- fclose(flp->fp);
- flp = flp->previous;
+ fclose(flp->fp);
+ flp = flp->previous;
}
/* Token decoding: shift() loads the next token into tok.
@@ -88,110 +86,110 @@ char *tok;
bool
shift(void)
{
- char *p = flp->cur;
- char *sor = NULL; /* start of record for any new lines */
+ char *p = flp->cur;
+ char *sor = NULL; /* start of record for any new lines */
- passert(flp->bdry == B_none);
+ passert(flp->bdry == B_none);
- *p = flp->under;
- flp->under = '\0';
+ *p = flp->under;
+ flp->under = '\0';
- for (;;)
- {
- switch (*p)
+ for (;;)
{
- case '\0': /* end of line */
- case '#': /* comment to end of line: treat as end of line */
- /* get the next line */
- if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
- {
- flp->bdry = B_file;
- tok = flp->cur = NULL;
- return FALSE;
- }
- else
- {
- /* strip trailing whitespace, including \n */
-
- for (p = flp->buffer+strlen(flp->buffer)-1
- ; p>flp->buffer && isspace(p[-1]); p--)
- ;
- *p = '\0';
-
- flp->lino++;
- sor = p = flp->buffer;
- }
- break; /* try again for a token */
-
- case ' ': /* whitespace */
- case '\t':
- p++;
- break; /* try again for a token */
-
- case '"': /* quoted token */
- case '\'':
- if (p != sor)
- {
- /* we have a quoted token: note and advance to its end */
- tok = p;
- p = strchr(p+1, *p);
- if (p == NULL)
- {
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
- , flp->filename, flp->lino);
- p = tok + strlen(tok);
- }
- else
- {
- p++; /* include delimiter in token */
- }
-
- /* remember token delimiter and replace with '\0' */
- flp->under = *p;
- *p = '\0';
- flp->cur = p;
- return TRUE;
- }
- /* FALL THROUGH */
- default:
- if (p != sor)
- {
- /* we seem to have a token: note and advance to its end */
- tok = p;
-
- if (p[0] == '0' && p[1] == 't')
+ switch (*p)
{
- /* 0t... token goes to end of line */
- p += strlen(p);
- }
- else
- {
- /* "ordinary" token: up to whitespace or end of line */
- do {
+ case '\0': /* end of line */
+ case '#': /* comment to end of line: treat as end of line */
+ /* get the next line */
+ if (fgets(flp->buffer, sizeof(flp->buffer)-1, flp->fp) == NULL)
+ {
+ flp->bdry = B_file;
+ tok = flp->cur = NULL;
+ return FALSE;
+ }
+ else
+ {
+ /* strip trailing whitespace, including \n */
+
+ for (p = flp->buffer+strlen(flp->buffer)-1
+ ; p>flp->buffer && isspace(p[-1]); p--)
+ ;
+ *p = '\0';
+
+ flp->lino++;
+ sor = p = flp->buffer;
+ }
+ break; /* try again for a token */
+
+ case ' ': /* whitespace */
+ case '\t':
p++;
- } while (*p != '\0' && !isspace(*p))
- ;
-
- /* fudge to separate ':' from a preceding adjacent token */
- if (p-1 > tok && p[-1] == ':')
- p--;
+ break; /* try again for a token */
+
+ case '"': /* quoted token */
+ case '\'':
+ if (p != sor)
+ {
+ /* we have a quoted token: note and advance to its end */
+ tok = p;
+ p = strchr(p+1, *p);
+ if (p == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: unterminated string"
+ , flp->filename, flp->lino);
+ p = tok + strlen(tok);
+ }
+ else
+ {
+ p++; /* include delimiter in token */
+ }
+
+ /* remember token delimiter and replace with '\0' */
+ flp->under = *p;
+ *p = '\0';
+ flp->cur = p;
+ return TRUE;
+ }
+ /* FALL THROUGH */
+ default:
+ if (p != sor)
+ {
+ /* we seem to have a token: note and advance to its end */
+ tok = p;
+
+ if (p[0] == '0' && p[1] == 't')
+ {
+ /* 0t... token goes to end of line */
+ p += strlen(p);
+ }
+ else
+ {
+ /* "ordinary" token: up to whitespace or end of line */
+ do {
+ p++;
+ } while (*p != '\0' && !isspace(*p))
+ ;
+
+ /* fudge to separate ':' from a preceding adjacent token */
+ if (p-1 > tok && p[-1] == ':')
+ p--;
+ }
+
+ /* remember token delimiter and replace with '\0' */
+ flp->under = *p;
+ *p = '\0';
+ flp->cur = p;
+ return TRUE;
+ }
+
+ /* we have a start-of-record: return it, deferring "real" token */
+ flp->bdry = B_record;
+ tok = NULL;
+ flp->under = *p;
+ flp->cur = p;
+ return FALSE;
}
-
- /* remember token delimiter and replace with '\0' */
- flp->under = *p;
- *p = '\0';
- flp->cur = p;
- return TRUE;
- }
-
- /* we have a start-of-record: return it, deferring "real" token */
- flp->bdry = B_record;
- tok = NULL;
- flp->under = *p;
- flp->cur = p;
- return FALSE;
}
- }
}
/* ensures we are at a Record (or File) boundary, optionally warning if not */
@@ -199,15 +197,15 @@ shift(void)
bool
flushline(const char *m)
{
- if (flp->bdry != B_none)
- {
- return TRUE;
- }
- else
- {
- if (m != NULL)
- loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
- do ; while (shift());
- return FALSE;
- }
+ if (flp->bdry != B_none)
+ {
+ return TRUE;
+ }
+ else
+ {
+ if (m != NULL)
+ loglog(RC_LOG_SERIOUS, "\"%s\" line %d: %s", flp->filename, flp->lino, m);
+ do ; while (shift());
+ return FALSE;
+ }
}
diff --git a/src/pluto/lex.h b/src/pluto/lex.h
index 450149c64..f16769144 100644
--- a/src/pluto/lex.h
+++ b/src/pluto/lex.h
@@ -10,22 +10,20 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: lex.h 3252 2007-10-06 21:24:50Z andreas $
*/
#define MAX_TOK_LEN 2048 /* includes terminal '\0' */
struct file_lex_position
{
- int depth; /* how deeply we are nested */
- const char *filename;
- FILE *fp;
- enum { B_none, B_record, B_file } bdry; /* current boundary */
- int lino; /* line number in file */
- char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
- char *cur; /* cursor */
- char under; /* except in shift(): character orignally at *cur */
- struct file_lex_position *previous;
+ int depth; /* how deeply we are nested */
+ const char *filename;
+ FILE *fp;
+ enum { B_none, B_record, B_file } bdry; /* current boundary */
+ int lino; /* line number in file */
+ char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
+ char *cur; /* cursor */
+ char under; /* except in shift(): character orignally at *cur */
+ struct file_lex_position *previous;
};
extern struct file_lex_position *flp;
diff --git a/src/pluto/log.c b/src/pluto/log.c
index b7c1ba8b8..e34409f1c 100644
--- a/src/pluto/log.c
+++ b/src/pluto/log.c
@@ -1,6 +1,7 @@
/* error logging functions
* Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: log.c 4246 2008-08-03 18:01:21Z andreas $
*/
#include <stdio.h>
@@ -23,13 +22,15 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
+#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
#include <sys/queue.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <freeswan.h>
+#include <library.h>
+#include <debug.h>
#include "constants.h"
#include "defs.h"
@@ -38,27 +39,27 @@
#include "state.h"
#include "connections.h"
#include "kernel.h"
-#include "whack.h" /* needs connections.h */
+#include "whack.h" /* needs connections.h */
#include "timer.h"
/* close one per-peer log */
-static void perpeer_logclose(struct connection *c); /* forward */
+static void perpeer_logclose(struct connection *c); /* forward */
bool
- log_to_stderr = TRUE, /* should log go to stderr? */
- log_to_syslog = TRUE, /* should log go to syslog? */
- log_to_perpeer= FALSE; /* should log go to per-IP file? */
+ log_to_stderr = TRUE, /* should log go to stderr? */
+ log_to_syslog = TRUE, /* should log go to syslog? */
+ log_to_perpeer= FALSE; /* should log go to per-IP file? */
bool
- logged_txt_warning = FALSE; /* should we complain about finding KEY? */
+ logged_txt_warning = FALSE; /* should we complain about finding KEY? */
/* should we complain when we find no local id */
bool
- logged_myid_fqdn_txt_warning = FALSE,
- logged_myid_ip_txt_warning = FALSE,
- logged_myid_fqdn_key_warning = FALSE,
- logged_myid_ip_key_warning = FALSE;
+ logged_myid_fqdn_txt_warning = FALSE,
+ logged_myid_ip_txt_warning = FALSE,
+ logged_myid_fqdn_key_warning = FALSE,
+ logged_myid_ip_key_warning = FALSE;
/* may include trailing / */
const char *base_perpeer_logdir = PERPEERLOGDIR;
@@ -74,42 +75,110 @@ static TAILQ_HEAD(perpeer, connection) perpeer_list;
* If the context provides a whack file descriptor, messages
* should be copied to it -- see whack_log()
*/
-int whack_log_fd = NULL_FD; /* only set during whack_handle() */
-struct state *cur_state = NULL; /* current state, for diagnostics */
-struct connection *cur_connection = NULL; /* current connection, for diagnostics */
-const ip_address *cur_from = NULL; /* source of current current message */
-u_int16_t cur_from_port; /* host order */
+int whack_log_fd = NULL_FD; /* only set during whack_handle() */
+struct state *cur_state = NULL; /* current state, for diagnostics */
+struct connection *cur_connection = NULL; /* current connection, for diagnostics */
+const ip_address *cur_from = NULL; /* source of current current message */
+u_int16_t cur_from_port; /* host order */
+
+/**
+ * pluto dbg function for libstrongswan
+ */
+static void pluto_dbg(int level, char *fmt, ...)
+{
+ int priority = LOG_INFO;
+ int debug_level;
+ char buffer[8192];
+ char *current = buffer, *next;
+ va_list args;
+
+ if (cur_debugging & DBG_PRIVATE)
+ {
+ debug_level = 4;
+ }
+ else if (cur_debugging & DBG_RAW)
+ {
+ debug_level = 3;
+ }
+ else if (cur_debugging & DBG_PARSING)
+ {
+ debug_level = 2;
+ }
+ else
+ {
+ debug_level = 1;
+ }
+
+ if (level <= debug_level)
+ {
+ va_start(args, fmt);
+
+ if (log_to_stderr)
+ {
+ if (level > 1)
+ {
+ fprintf(stderr, "| ");
+ }
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ }
+ if (log_to_syslog)
+ {
+ /* write in memory buffer first */
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+
+ /* do a syslog with every line */
+ while (current)
+ {
+ next = strchr(current, '\n');
+ if (next)
+ {
+ *(next++) = '\0';
+ }
+ syslog(priority, "%s%s\n", (level > 1)? "| ":"", current);
+ current = next;
+ }
+ }
+ va_end(args);
+ }
+}
void
init_log(const char *program)
{
- if (log_to_stderr)
- setbuf(stderr, NULL);
- if (log_to_syslog)
- openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
+ /* enable pluto debugging hook for libstrongswan */
+ dbg = pluto_dbg;
- TAILQ_INIT(&perpeer_list);
+ if (log_to_stderr)
+ {
+ setbuf(stderr, NULL);
+ }
+ if (log_to_syslog)
+ {
+ openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
+ }
+ TAILQ_INIT(&perpeer_list);
}
void
close_peerlog(void)
{
- /* exit if the queue has not been initialized */
- if (perpeer_list.tqh_first == NULL)
- return;
+ /* exit if the queue has not been initialized */
+ if (perpeer_list.tqh_first == NULL)
+ return;
- /* end of queue is given by pointer to "HEAD" */
- while (TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list)
- perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
+ /* end of queue is given by pointer to "HEAD" */
+ while (TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list)
+ perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
}
void
close_log(void)
{
- if (log_to_syslog)
- closelog();
+ if (log_to_syslog)
+ closelog();
- close_peerlog();
+ close_peerlog();
}
/* Sanitize character string in situ: turns dangerous characters into \OOO.
@@ -120,50 +189,50 @@ close_log(void)
static size_t
sanitize(char *buf, size_t size)
{
-# define UGLY_WIDTH 4 /* width for ugly character: \OOO */
- size_t len;
- size_t added = 0;
- char *p;
-
- passert(size >= UGLY_WIDTH); /* need room to swing cat */
-
- /* find right side of string to be sanitized and count
- * number of columns to be added. Stop on end of string
- * or lack of room for more result.
- */
- for (p = buf; *p != '\0' && &p[added] < &buf[size - UGLY_WIDTH]; )
- {
- unsigned char c = *p++;
-
- if (c == '\\' || !isprint(c))
- added += UGLY_WIDTH - 1;
- }
-
- /* at this point, p points after last original character to be
- * included. added is how many characters are added to sanitize.
- * so p[added] will point after last sanitized character.
- */
-
- p[added] = '\0';
- len = &p[added] - buf;
-
- /* scan backwards, copying characters to their new home
- * and inserting the expansions for ugly characters.
- * It is finished when no more shifting is required.
- * This is a predecrement loop.
- */
- while (added != 0)
- {
- char fmtd[UGLY_WIDTH + 1];
- unsigned char c;
-
- while ((c = *--p) != '\\' && isprint(c))
- p[added] = c;
- added -= UGLY_WIDTH - 1;
- snprintf(fmtd, sizeof(fmtd), "\\%03o", c);
- memcpy(p + added, fmtd, UGLY_WIDTH);
- }
- return len;
+# define UGLY_WIDTH 4 /* width for ugly character: \OOO */
+ size_t len;
+ size_t added = 0;
+ char *p;
+
+ passert(size >= UGLY_WIDTH); /* need room to swing cat */
+
+ /* find right side of string to be sanitized and count
+ * number of columns to be added. Stop on end of string
+ * or lack of room for more result.
+ */
+ for (p = buf; *p != '\0' && &p[added] < &buf[size - UGLY_WIDTH]; )
+ {
+ unsigned char c = *p++;
+
+ if (c == '\\' || !isprint(c))
+ added += UGLY_WIDTH - 1;
+ }
+
+ /* at this point, p points after last original character to be
+ * included. added is how many characters are added to sanitize.
+ * so p[added] will point after last sanitized character.
+ */
+
+ p[added] = '\0';
+ len = &p[added] - buf;
+
+ /* scan backwards, copying characters to their new home
+ * and inserting the expansions for ugly characters.
+ * It is finished when no more shifting is required.
+ * This is a predecrement loop.
+ */
+ while (added != 0)
+ {
+ char fmtd[UGLY_WIDTH + 1];
+ unsigned char c;
+
+ while ((c = *--p) != '\\' && isprint(c))
+ p[added] = c;
+ added -= UGLY_WIDTH - 1;
+ snprintf(fmtd, sizeof(fmtd), "\\%03o", c);
+ memcpy(p + added, fmtd, UGLY_WIDTH);
+ }
+ return len;
# undef UGLY_WIDTH
}
@@ -174,349 +243,348 @@ sanitize(char *buf, size_t size)
static void
fmt_log(char *buf, size_t buf_len, const char *fmt, va_list ap)
{
- bool reproc = *fmt == '~';
- size_t ps;
- struct connection *c = cur_state != NULL ? cur_state->st_connection
- : cur_connection;
-
- buf[0] = '\0';
- if (reproc)
- fmt++; /* ~ at start of format suppresses this prefix */
- else if (c != NULL)
- {
- /* start with name of connection */
- char *const be = buf + buf_len;
- char *bp = buf;
-
- snprintf(bp, be - bp, "\"%s\"", c->name);
- bp += strlen(bp);
-
- /* if it fits, put in any connection instance information */
- if (be - bp > CONN_INST_BUF)
+ bool reproc = *fmt == '~';
+ size_t ps;
+ struct connection *c = cur_state != NULL ? cur_state->st_connection
+ : cur_connection;
+
+ buf[0] = '\0';
+ if (reproc)
+ fmt++; /* ~ at start of format suppresses this prefix */
+ else if (c != NULL)
{
- fmt_conn_instance(c, bp);
- bp += strlen(bp);
- }
+ /* start with name of connection */
+ char *const be = buf + buf_len;
+ char *bp = buf;
+
+ snprintf(bp, be - bp, "\"%s\"", c->name);
+ bp += strlen(bp);
+
+ /* if it fits, put in any connection instance information */
+ if (be - bp > CONN_INST_BUF)
+ {
+ fmt_conn_instance(c, bp);
+ bp += strlen(bp);
+ }
- if (cur_state != NULL)
+ if (cur_state != NULL)
+ {
+ /* state number */
+ snprintf(bp, be - bp, " #%lu", cur_state->st_serialno);
+ bp += strlen(bp);
+ }
+ snprintf(bp, be - bp, ": ");
+ }
+ else if (cur_from != NULL)
{
- /* state number */
- snprintf(bp, be - bp, " #%lu", cur_state->st_serialno);
- bp += strlen(bp);
+ /* peer's IP address */
+ /* Note: must not use ip_str() because our caller might! */
+ char ab[ADDRTOT_BUF];
+
+ (void) addrtot(cur_from, 0, ab, sizeof(ab));
+ snprintf(buf, buf_len, "packet from %s:%u: "
+ , ab, (unsigned)cur_from_port);
}
- snprintf(bp, be - bp, ": ");
- }
- else if (cur_from != NULL)
- {
- /* peer's IP address */
- /* Note: must not use ip_str() because our caller might! */
- char ab[ADDRTOT_BUF];
-
- (void) addrtot(cur_from, 0, ab, sizeof(ab));
- snprintf(buf, buf_len, "packet from %s:%u: "
- , ab, (unsigned)cur_from_port);
- }
-
- ps = strlen(buf);
- vsnprintf(buf + ps, buf_len - ps, fmt, ap);
- if (!reproc)
- (void)sanitize(buf, buf_len);
+
+ ps = strlen(buf);
+ vsnprintf(buf + ps, buf_len - ps, fmt, ap);
+ if (!reproc)
+ (void)sanitize(buf, buf_len);
}
static void
perpeer_logclose(struct connection *c)
{
- /* only free/close things if we had used them! */
- if (c->log_file != NULL)
- {
- passert(perpeer_count > 0);
-
- TAILQ_REMOVE(&perpeer_list, c, log_link);
- perpeer_count--;
- fclose(c->log_file);
- c->log_file=NULL;
- }
+ /* only free/close things if we had used them! */
+ if (c->log_file != NULL)
+ {
+ passert(perpeer_count > 0);
+
+ TAILQ_REMOVE(&perpeer_list, c, log_link);
+ perpeer_count--;
+ fclose(c->log_file);
+ c->log_file=NULL;
+ }
}
void
perpeer_logfree(struct connection *c)
{
- perpeer_logclose(c);
- if (c->log_file_name != NULL)
- {
- pfree(c->log_file_name);
- c->log_file_name = NULL;
- c->log_file_err = FALSE;
- }
+ perpeer_logclose(c);
+ if (c->log_file_name != NULL)
+ {
+ free(c->log_file_name);
+ c->log_file_name = NULL;
+ c->log_file_err = FALSE;
+ }
}
/* open the per-peer log */
static void
open_peerlog(struct connection *c)
{
- syslog(LOG_INFO, "opening log file for conn %s", c->name);
+ syslog(LOG_INFO, "opening log file for conn %s", c->name);
- if (c->log_file_name == NULL)
- {
- char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];
- int peernamelen, lf_len;
-
- addrtot(&c->spd.that.host_addr, 'Q', peername, sizeof(peername));
- peernamelen = strlen(peername);
-
- /* copy IP address, turning : and . into / */
+ if (c->log_file_name == NULL)
{
- char c, *p, *q;
-
- p = peername;
- q = dname;
- do {
- c = *p++;
- if (c == '.' || c == ':')
- c = '/';
- *q++ = c;
- } while (c != '\0');
- }
-
- lf_len = peernamelen * 2
- + strlen(base_perpeer_logdir)
- + sizeof("//.log")
- + 1;
- c->log_file_name = alloc_bytes(lf_len, "per-peer log file name");
-
- fprintf(stderr, "base dir |%s| dname |%s| peername |%s|"
- , base_perpeer_logdir, dname, peername);
- snprintf(c->log_file_name, lf_len, "%s/%s/%s.log"
- , base_perpeer_logdir, dname, peername);
+ char peername[ADDRTOT_BUF], dname[ADDRTOT_BUF];
+ int peernamelen, lf_len;
- syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name);
- }
+ addrtot(&c->spd.that.host_addr, 'Q', peername, sizeof(peername));
+ peernamelen = strlen(peername);
- /* now open the file, creating directories if necessary */
-
- { /* create the directory */
- char *dname;
- int bpl_len = strlen(base_perpeer_logdir);
- char *slashloc;
-
- dname = clone_str(c->log_file_name, "temp copy of file name");
- dname = dirname(dname);
-
- if (access(dname, W_OK) != 0)
- {
- if (errno != ENOENT)
- {
- if (c->log_file_err)
+ /* copy IP address, turning : and . into / */
{
- syslog(LOG_CRIT, "can not write to %s: %s"
- , dname, strerror(errno));
- c->log_file_err = TRUE;
- pfree(dname);
- return;
+ char c, *p, *q;
+
+ p = peername;
+ q = dname;
+ do {
+ c = *p++;
+ if (c == '.' || c == ':')
+ c = '/';
+ *q++ = c;
+ } while (c != '\0');
}
- }
- /* directory does not exist, walk path creating dirs */
- /* start at base_perpeer_logdir */
- slashloc = dname + bpl_len;
- slashloc++; /* since, by construction there is a slash
- right there */
+ lf_len = peernamelen * 2
+ + strlen(base_perpeer_logdir)
+ + sizeof("//.log")
+ + 1;
+ c->log_file_name = malloc(lf_len);
+
+ fprintf(stderr, "base dir |%s| dname |%s| peername |%s|"
+ , base_perpeer_logdir, dname, peername);
+ snprintf(c->log_file_name, lf_len, "%s/%s/%s.log"
+ , base_perpeer_logdir, dname, peername);
- while (*slashloc != '\0')
- {
- char saveslash;
+ syslog(LOG_DEBUG, "conn %s logfile is %s", c->name, c->log_file_name);
+ }
- /* look for next slash */
- while (*slashloc != '\0' && *slashloc != '/') slashloc++;
+ /* now open the file, creating directories if necessary */
- saveslash = *slashloc;
+ { /* create the directory */
+ char *dname;
+ int bpl_len = strlen(base_perpeer_logdir);
+ char *slashloc;
- *slashloc = '\0';
+ dname = clone_str(c->log_file_name);
+ dname = dirname(dname);
- if (mkdir(dname, 0750) != 0 && errno != EEXIST)
+ if (access(dname, W_OK) != 0)
{
- syslog(LOG_CRIT, "can not create dir %s: %s"
- , dname, strerror(errno));
- c->log_file_err = TRUE;
- pfree(dname);
- return;
+ if (errno != ENOENT)
+ {
+ if (c->log_file_err)
+ {
+ syslog(LOG_CRIT, "can not write to %s: %s"
+ , dname, strerror(errno));
+ c->log_file_err = TRUE;
+ free(dname);
+ return;
+ }
+ }
+
+ /* directory does not exist, walk path creating dirs */
+ /* start at base_perpeer_logdir */
+ slashloc = dname + bpl_len;
+ slashloc++; /* since, by construction there is a slash
+ right there */
+
+ while (*slashloc != '\0')
+ {
+ char saveslash;
+
+ /* look for next slash */
+ while (*slashloc != '\0' && *slashloc != '/') slashloc++;
+
+ saveslash = *slashloc;
+
+ *slashloc = '\0';
+
+ if (mkdir(dname, 0750) != 0 && errno != EEXIST)
+ {
+ syslog(LOG_CRIT, "can not create dir %s: %s"
+ , dname, strerror(errno));
+ c->log_file_err = TRUE;
+ free(dname);
+ return;
+ }
+ syslog(LOG_DEBUG, "created new directory %s", dname);
+ *slashloc = saveslash;
+ slashloc++;
+ }
}
- syslog(LOG_DEBUG, "created new directory %s", dname);
- *slashloc = saveslash;
- slashloc++;
- }
+ free(dname);
}
- pfree(dname);
- }
+ c->log_file = fopen(c->log_file_name, "a");
+ if (c->log_file == NULL)
+ {
+ if (c->log_file_err)
+ {
+ syslog(LOG_CRIT, "logging system can not open %s: %s"
+ , c->log_file_name, strerror(errno));
+ c->log_file_err = TRUE;
+ }
+ return;
+ }
- c->log_file = fopen(c->log_file_name, "a");
- if (c->log_file == NULL)
- {
- if (c->log_file_err)
+ /* look for a connection to close! */
+ while (perpeer_count >= MAX_PEERLOG_COUNT)
{
- syslog(LOG_CRIT, "logging system can not open %s: %s"
- , c->log_file_name, strerror(errno));
- c->log_file_err = TRUE;
+ /* can not be NULL because perpeer_count > 0 */
+ passert(TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list);
+
+ perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
}
- return;
- }
-
- /* look for a connection to close! */
- while (perpeer_count >= MAX_PEERLOG_COUNT)
- {
- /* can not be NULL because perpeer_count > 0 */
- passert(TAILQ_LAST(&perpeer_list, perpeer) != (void *)&perpeer_list);
-
- perpeer_logclose(TAILQ_LAST(&perpeer_list, perpeer));
- }
-
- /* insert this into the list */
- TAILQ_INSERT_HEAD(&perpeer_list, c, log_link);
- passert(c->log_file != NULL);
- perpeer_count++;
+
+ /* insert this into the list */
+ TAILQ_INSERT_HEAD(&perpeer_list, c, log_link);
+ passert(c->log_file != NULL);
+ perpeer_count++;
}
/* log a line to cur_connection's log */
static void
peerlog(const char *prefix, const char *m)
{
- if (cur_connection == NULL)
- {
- /* we can not log it in this case. Oh well. */
- return;
- }
-
- if (cur_connection->log_file == NULL)
- {
- open_peerlog(cur_connection);
- }
-
- /* despite our attempts above, we may not be able to open the file. */
- if (cur_connection->log_file != NULL)
- {
- char datebuf[32];
- time_t n;
- struct tm *t;
-
- time(&n);
- t = localtime(&n);
-
- strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);
- fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);
-
- /* now move it to the front of the list */
- TAILQ_REMOVE(&perpeer_list, cur_connection, log_link);
- TAILQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
- }
+ if (cur_connection == NULL)
+ {
+ /* we can not log it in this case. Oh well. */
+ return;
+ }
+
+ if (cur_connection->log_file == NULL)
+ {
+ open_peerlog(cur_connection);
+ }
+
+ /* despite our attempts above, we may not be able to open the file. */
+ if (cur_connection->log_file != NULL)
+ {
+ char datebuf[32];
+ time_t n;
+ struct tm *t;
+
+ time(&n);
+ t = localtime(&n);
+
+ strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);
+ fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);
+
+ /* now move it to the front of the list */
+ TAILQ_REMOVE(&perpeer_list, cur_connection, log_link);
+ TAILQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
+ }
}
void
plog(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ fmt_log(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
- if (log_to_perpeer)
- peerlog("", m);
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
+ if (log_to_perpeer)
+ peerlog("", m);
- whack_log(RC_LOG, "~%s", m);
+ whack_log(RC_LOG, "~%s", m);
}
void
loglog(int mess_no, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ fmt_log(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
- if (log_to_perpeer)
- peerlog("", m);
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
+ if (log_to_perpeer)
+ peerlog("", m);
- whack_log(mess_no, "~%s", m);
+ whack_log(mess_no, "~%s", m);
}
void
log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
- if (log_to_perpeer)
- {
- peerlog(strerror(e), m);
- }
-
- whack_log(RC_LOG_SERIOUS
- , "~ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ fmt_log(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ if (log_to_perpeer)
+ {
+ peerlog(strerror(e), m);
+ }
+
+ whack_log(RC_LOG_SERIOUS
+ , "~ERROR: %s. Errno %d: %s", m, e, strerror(e));
}
void
exit_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ fmt_log(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s\n", m);
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s", m);
- if (log_to_perpeer)
- peerlog("FATAL ERROR: ", m);
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s", m);
+ if (log_to_perpeer)
+ peerlog("FATAL ERROR: ", m);
- whack_log(RC_LOG_SERIOUS, "~FATAL ERROR: %s", m);
+ whack_log(RC_LOG_SERIOUS, "~FATAL ERROR: %s", m);
- exit_pluto(1);
+ exit_pluto(1);
}
void
exit_log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- fmt_log(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ fmt_log(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- if (log_to_perpeer)
- peerlog(strerror(e), m);
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ if (log_to_perpeer)
+ peerlog(strerror(e), m);
- whack_log(RC_LOG_SERIOUS
- , "~FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ whack_log(RC_LOG_SERIOUS
+ , "~FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- exit_pluto(1);
+ exit_pluto(1);
}
/* emit message to whack.
@@ -531,65 +599,65 @@ static volatile sig_atomic_t dying_breath = FALSE;
void
whack_log(int mess_no, const char *message, ...)
{
- int wfd = whack_log_fd != NULL_FD ? whack_log_fd
- : cur_state != NULL ? cur_state->st_whack_sock
- : NULL_FD;
+ int wfd = whack_log_fd != NULL_FD ? whack_log_fd
+ : cur_state != NULL ? cur_state->st_whack_sock
+ : NULL_FD;
- if (wfd != NULL_FD
+ if (wfd != NULL_FD
#ifdef DEBUG
- || dying_breath
+ || dying_breath
#endif
- )
- {
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
- int prelen = snprintf(m, sizeof(m), "%03d ", mess_no);
+ )
+ {
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+ int prelen = snprintf(m, sizeof(m), "%03d ", mess_no);
- passert(prelen >= 0);
+ passert(prelen >= 0);
- va_start(args, message);
- fmt_log(m+prelen, sizeof(m)-prelen, message, args);
- va_end(args);
+ va_start(args, message);
+ fmt_log(m+prelen, sizeof(m)-prelen, message, args);
+ va_end(args);
#if DEBUG
- if (dying_breath)
- {
- /* status output copied to log */
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m + prelen);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m + prelen);
- if (log_to_perpeer)
- peerlog("", m);
- }
+ if (dying_breath)
+ {
+ /* status output copied to log */
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m + prelen);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m + prelen);
+ if (log_to_perpeer)
+ peerlog("", m);
+ }
#endif
- if (wfd != NULL_FD)
- {
- /* write to whack socket, but suppress possible SIGPIPE */
- size_t len = strlen(m);
-#ifdef MSG_NOSIGNAL /* depends on version of glibc??? */
- m[len] = '\n'; /* don't need NUL, do need NL */
- (void) send(wfd, m, len + 1, MSG_NOSIGNAL);
+ if (wfd != NULL_FD)
+ {
+ /* write to whack socket, but suppress possible SIGPIPE */
+ size_t len = strlen(m);
+#ifdef MSG_NOSIGNAL /* depends on version of glibc??? */
+ m[len] = '\n'; /* don't need NUL, do need NL */
+ (void) send(wfd, m, len + 1, MSG_NOSIGNAL);
#else /* !MSG_NOSIGNAL */
- int r;
- struct sigaction act
- , oldact;
+ int r;
+ struct sigaction act
+ , oldact;
- m[len] = '\n'; /* don't need NUL, do need NL */
- act.sa_handler = SIG_IGN;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0; /* no nothing */
- r = sigaction(SIGPIPE, &act, &oldact);
- passert(r == 0);
+ m[len] = '\n'; /* don't need NUL, do need NL */
+ act.sa_handler = SIG_IGN;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0; /* no nothing */
+ r = sigaction(SIGPIPE, &act, &oldact);
+ passert(r == 0);
- (void) write(wfd, m, len + 1);
+ (void) write(wfd, m, len + 1);
- r = sigaction(SIGPIPE, &oldact, NULL);
- passert(r == 0);
+ r = sigaction(SIGPIPE, &oldact, NULL);
+ passert(r == 0);
#endif /* !MSG_NOSIGNAL */
+ }
}
- }
}
/* Build up a diagnostic in a static buffer.
@@ -607,16 +675,16 @@ char diag_space[sizeof(diag_space)];
err_t
builddiag(const char *fmt, ...)
{
- static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
- char t[sizeof(diag_space)]; /* build result here first */
- va_list args;
-
- va_start(args, fmt);
- t[0] = '\0'; /* in case nothing terminates string */
- vsnprintf(t, sizeof(t), fmt, args);
- va_end(args);
- strcpy(diag_space, t);
- return diag_space;
+ static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
+ char t[sizeof(diag_space)]; /* build result here first */
+ va_list args;
+
+ va_start(args, fmt);
+ t[0] = '\0'; /* in case nothing terminates string */
+ vsnprintf(t, sizeof(t), fmt, args);
+ va_end(args);
+ strcpy(diag_space, t);
+ return diag_space;
}
/* Debugging message support */
@@ -626,51 +694,51 @@ builddiag(const char *fmt, ...)
void
switch_fail(int n, const char *file_str, unsigned long line_no)
{
- char buf[30];
+ char buf[30];
- snprintf(buf, sizeof(buf), "case %d unexpected", n);
- passert_fail(buf, file_str, line_no);
+ snprintf(buf, sizeof(buf), "case %d unexpected", n);
+ passert_fail(buf, file_str, line_no);
}
void
passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- if (!dying_breath)
- {
- dying_breath = TRUE;
- show_status(TRUE, NULL);
- }
- abort(); /* exiting correctly doesn't always work */
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ if (!dying_breath)
+ {
+ dying_breath = TRUE;
+ show_status(TRUE, NULL);
+ }
+ abort(); /* exiting correctly doesn't always work */
}
void
pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
}
lset_t
- base_debugging = DBG_NONE, /* default to reporting nothing */
- cur_debugging = DBG_NONE;
+ base_debugging = DBG_NONE, /* default to reporting nothing */
+ cur_debugging = DBG_NONE;
void
extra_debugging(const struct connection *c)
{
- if(c == NULL)
- {
- reset_debugging();
- return;
- }
-
- if (c!= NULL && c->extra_debugging != 0)
- {
- plog("enabling for connection: %s"
- , bitnamesof(debug_bit_names, c->extra_debugging & ~cur_debugging));
- cur_debugging |= c->extra_debugging;
- }
+ if(c == NULL)
+ {
+ reset_debugging();
+ return;
+ }
+
+ if (c!= NULL && c->extra_debugging != 0)
+ {
+ plog("enabling for connection: %s"
+ , bitnamesof(debug_bit_names, c->extra_debugging & ~cur_debugging));
+ cur_debugging |= c->extra_debugging;
+ }
}
/* log a debugging message (prefixed by "| ") */
@@ -678,21 +746,21 @@ extra_debugging(const struct connection *c)
void
DBG_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- (void)sanitize(m, sizeof(m));
+ (void)sanitize(m, sizeof(m));
- if (log_to_stderr)
- fprintf(stderr, "| %s\n", m);
- if (log_to_syslog)
- syslog(LOG_DEBUG, "| %s", m);
- if (log_to_perpeer)
- peerlog("| ", m);
+ if (log_to_stderr)
+ fprintf(stderr, "| %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_DEBUG, "| %s", m);
+ if (log_to_perpeer)
+ peerlog("| ", m);
}
/* dump raw bytes in hex to stderr (for lack of any better destination) */
@@ -700,82 +768,99 @@ DBG_log(const char *message, ...)
void
DBG_dump(const char *label, const void *p, size_t len)
{
-# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
-# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
- char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
- char *bp;
- const unsigned char *cp = p;
-
- bp = buf;
+# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
+# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
+ char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
+ char *bp;
+ const unsigned char *cp = p;
- if (label != NULL && label[0] != '\0')
- {
- /* Handle the label. Care must be taken to avoid buffer overrun. */
- size_t llen = strlen(label);
+ bp = buf;
- if (llen + 1 > sizeof(buf))
+ if (label != NULL && label[0] != '\0')
{
- DBG_log("%s", label);
- }
- else
- {
- strcpy(buf, label);
- if (buf[llen-1] == '\n')
- {
- buf[llen-1] = '\0'; /* get rid of newline */
- DBG_log("%s", buf);
- }
- else if (llen < DUMP_LABEL_WIDTH)
- {
- bp = buf + llen;
- }
- else
- {
- DBG_log("%s", buf);
- }
+ /* Handle the label. Care must be taken to avoid buffer overrun. */
+ size_t llen = strlen(label);
+
+ if (llen + 1 > sizeof(buf))
+ {
+ DBG_log("%s", label);
+ }
+ else
+ {
+ strcpy(buf, label);
+ if (buf[llen-1] == '\n')
+ {
+ buf[llen-1] = '\0'; /* get rid of newline */
+ DBG_log("%s", buf);
+ }
+ else if (llen < DUMP_LABEL_WIDTH)
+ {
+ bp = buf + llen;
+ }
+ else
+ {
+ DBG_log("%s", buf);
+ }
+ }
}
- }
- do {
- int i, j;
+ do {
+ int i, j;
- for (i = 0; len!=0 && i!=4; i++)
- {
- *bp++ = ' ';
- for (j = 0; len!=0 && j!=4; len--, j++)
- {
- static const char hexdig[] = "0123456789abcdef";
-
- *bp++ = ' ';
- *bp++ = hexdig[(*cp >> 4) & 0xF];
- *bp++ = hexdig[*cp & 0xF];
- cp++;
- }
- }
- *bp = '\0';
- DBG_log("%s", buf);
- bp = buf;
- } while (len != 0);
+ for (i = 0; len!=0 && i!=4; i++)
+ {
+ *bp++ = ' ';
+ for (j = 0; len!=0 && j!=4; len--, j++)
+ {
+ static const char hexdig[] = "0123456789abcdef";
+
+ *bp++ = ' ';
+ *bp++ = hexdig[(*cp >> 4) & 0xF];
+ *bp++ = hexdig[*cp & 0xF];
+ cp++;
+ }
+ }
+ *bp = '\0';
+ DBG_log("%s", buf);
+ bp = buf;
+ } while (len != 0);
# undef DUMP_LABEL_WIDTH
# undef DUMP_WIDTH
}
#endif /* DEBUG */
-void
-show_status(bool all, const char *name)
+static void show_loaded_plugins()
{
- if (all)
- {
- show_ifaces_status();
- show_myid_status();
- show_debug_status();
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
- }
- show_connections_status(all, name);
- show_states_status(all, name);
+ char buf[BUF_LEN], *plugin;
+ int len = 0;
+ enumerator_t *enumerator;
+
+ buf[0] = '\0';
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
+ {
+ len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin);
+ }
+ enumerator->destroy(enumerator);
+ whack_log(RC_COMMENT, "loaded plugins: %s", buf);
+}
+
+void show_status(bool all, const char *name)
+{
+ if (all)
+ {
+ whack_log(RC_COMMENT, "Status of IKEv1 pluto daemon (strongSwan "VERSION"):");
+ show_ifaces_status();
+ show_myid_status();
+ show_loaded_plugins();
+ show_debug_status();
+ whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
+ }
+ show_connections_status(all, name);
+ show_states_status(all, name);
#ifdef KLIPS
- show_shunt_status();
+ show_shunt_status();
#endif
}
@@ -788,10 +873,10 @@ show_status(bool all, const char *name)
const char *
ip_str(const ip_address *src)
{
- static char buf[ADDRTOT_BUF];
+ static char buf[ADDRTOT_BUF];
- addrtot(src, 0, buf, sizeof(buf));
- return buf;
+ addrtot(src, 0, buf, sizeof(buf));
+ return buf;
}
/*
@@ -802,35 +887,31 @@ ip_str(const ip_address *src)
void
daily_log_reset(void)
{
- /* now perform actions */
- logged_txt_warning = FALSE;
+ /* now perform actions */
+ logged_txt_warning = FALSE;
- logged_myid_fqdn_txt_warning = FALSE;
- logged_myid_ip_txt_warning = FALSE;
- logged_myid_fqdn_key_warning = FALSE;
- logged_myid_ip_key_warning = FALSE;
+ logged_myid_fqdn_txt_warning = FALSE;
+ logged_myid_ip_txt_warning = FALSE;
+ logged_myid_fqdn_key_warning = FALSE;
+ logged_myid_ip_key_warning = FALSE;
}
void
daily_log_event(void)
{
- struct tm *ltime;
- time_t n, interval;
-
- /* attempt to schedule oneself to midnight, local time
- * do this by getting seconds in the day, and delaying
- * by 86400 - hour*3600+minutes*60+seconds.
- */
- time(&n);
- ltime = localtime(&n);
- interval = (24 * 60 * 60)
- - (ltime->tm_sec
- + ltime->tm_min * 60
- + ltime->tm_hour * 3600);
-
- event_schedule(EVENT_LOG_DAILY, interval, NULL);
-
- daily_log_reset();
+ struct tm lt;
+ time_t t, interval;
+
+ /* attempt to schedule oneself to midnight, local time
+ * do this by getting seconds in the day, and delaying
+ * by 86400 - 3600*hours - 60*minutes - seconds.
+ */
+ time(&t);
+ localtime_r(&t, &lt);
+ interval = 3600 * (24 - lt.tm_hour) - 60 * lt.tm_min - lt.tm_sec;
+
+ event_schedule(EVENT_LOG_DAILY, interval, NULL);
+ daily_log_reset();
}
/*
diff --git a/src/pluto/log.h b/src/pluto/log.h
index db0fb0202..52c01bbd4 100644
--- a/src/pluto/log.h
+++ b/src/pluto/log.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: log.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include <freeswan.h>
@@ -27,49 +25,49 @@
#ifdef DEBUG
extern void passert_fail(const char *pred_str
- , const char *file_str, unsigned long line_no) NEVER_RETURNS;
+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
extern void pexpect_log(const char *pred_str
- , const char *file_str, unsigned long line_no);
+ , const char *file_str, unsigned long line_no);
# define impossible() passert_fail("impossible", __FILE__, __LINE__)
extern void switch_fail(int n
- , const char *file_str, unsigned long line_no) NEVER_RETURNS;
+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
# define passert(pred) { \
- if (!(pred)) \
- passert_fail(#pred, __FILE__, __LINE__); \
- }
+ if (!(pred)) \
+ passert_fail(#pred, __FILE__, __LINE__); \
+ }
# define pexpect(pred) { \
- if (!(pred)) \
- pexpect_log(#pred, __FILE__, __LINE__); \
- }
+ if (!(pred)) \
+ pexpect_log(#pred, __FILE__, __LINE__); \
+ }
/* assert that an err_t is NULL; evaluate exactly once */
# define happy(x) { \
- err_t ugh = x; \
- if (ugh != NULL) \
- passert_fail(ugh, __FILE__, __LINE__); \
- }
+ err_t ugh = x; \
+ if (ugh != NULL) \
+ passert_fail(ugh, __FILE__, __LINE__); \
+ }
#else /*!DEBUG*/
# define impossible() abort()
# define bad_case(n) abort()
-# define passert(pred) { } /* do nothing */
-# define happy(x) { (void) x; } /* evaluate non-judgementally */
+# define passert(pred) { } /* do nothing */
+# define happy(x) { (void) x; } /* evaluate non-judgementally */
#endif /*!DEBUG*/
extern bool
- log_to_stderr, /* should log go to stderr? */
- log_to_syslog, /* should log go to syslog? */
- log_to_perpeer; /* should log go to per-IP file? */
+ log_to_stderr, /* should log go to stderr? */
+ log_to_syslog, /* should log go to syslog? */
+ log_to_perpeer; /* should log go to per-IP file? */
extern const char *base_perpeer_logdir;
@@ -84,25 +82,25 @@ extern const char *base_perpeer_logdir;
* If the context provides a whack file descriptor, messages
* should be copied to it -- see whack_log()
*/
-extern int whack_log_fd; /* only set during whack_handle() */
-extern struct state *cur_state; /* current state, for diagnostics */
-extern struct connection *cur_connection; /* current connection, for diagnostics */
-extern const ip_address *cur_from; /* source of current current message */
-extern u_int16_t cur_from_port; /* host order */
+extern int whack_log_fd; /* only set during whack_handle() */
+extern struct state *cur_state; /* current state, for diagnostics */
+extern struct connection *cur_connection; /* current connection, for diagnostics */
+extern const ip_address *cur_from; /* source of current current message */
+extern u_int16_t cur_from_port; /* host order */
#ifdef DEBUG
- extern lset_t cur_debugging; /* current debugging level */
+ extern lset_t cur_debugging; /* current debugging level */
extern void extra_debugging(const struct connection *c);
# define reset_debugging() { cur_debugging = base_debugging; }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
- && cur_state == NULL \
- && cur_connection == NULL \
- && cur_from == NULL \
- && cur_debugging == base_debugging)
+ && cur_state == NULL \
+ && cur_connection == NULL \
+ && cur_from == NULL \
+ && cur_debugging == base_debugging)
#else /*!DEBUG*/
@@ -111,40 +109,40 @@ extern u_int16_t cur_from_port; /* host order */
# define reset_debugging() { }
# define GLOBALS_ARE_RESET() (whack_log_fd == NULL_FD \
- && cur_state == NULL \
- && cur_connection == NULL \
- && cur_from == NULL)
+ && cur_state == NULL \
+ && cur_connection == NULL \
+ && cur_from == NULL)
#endif /*!DEBUG*/
#define reset_globals() { \
- whack_log_fd = NULL_FD; \
- cur_state = NULL; \
- cur_from = NULL; \
- reset_cur_connection(); \
- }
+ whack_log_fd = NULL_FD; \
+ cur_state = NULL; \
+ cur_from = NULL; \
+ reset_cur_connection(); \
+ }
#define set_cur_connection(c) { \
- cur_connection = (c); \
- extra_debugging(c); \
- }
+ cur_connection = (c); \
+ extra_debugging(c); \
+ }
#define reset_cur_connection() { \
- cur_connection = NULL; \
- reset_debugging(); \
- }
+ cur_connection = NULL; \
+ reset_debugging(); \
+ }
#define set_cur_state(s) { \
- cur_state = (s); \
- extra_debugging((s)->st_connection); \
- }
+ cur_state = (s); \
+ extra_debugging((s)->st_connection); \
+ }
#define reset_cur_state() { \
- cur_state = NULL; \
- reset_debugging(); \
- }
+ cur_state = NULL; \
+ reset_debugging(); \
+ }
extern void init_log(const char *program);
extern void close_log(void);
@@ -188,12 +186,12 @@ extern void show_status(bool all, const char *name);
* restriction is not checked in any way: violators will produce
* confusing results (without crashing!).
*/
-extern char diag_space[LOG_WIDTH]; /* output buffer, but can be occupied at call */
+extern char diag_space[LOG_WIDTH]; /* output buffer, but can be occupied at call */
extern err_t builddiag(const char *fmt, ...) PRINTF_LIKE(1);
#ifdef DEBUG
-extern lset_t base_debugging; /* bits selecting what to report */
+extern lset_t base_debugging; /* bits selecting what to report */
#define DBGP(cond) (cur_debugging & (cond))
#define DBG(cond, action) { if (DBGP(cond)) { action ; } }
@@ -204,7 +202,7 @@ extern void DBG_dump(const char *label, const void *p, size_t len);
#else /*!DEBUG*/
-#define DBG(cond, action) { } /* do nothing */
+#define DBG(cond, action) { } /* do nothing */
#endif /*!DEBUG*/
diff --git a/src/pluto/md2.c b/src/pluto/md2.c
deleted file mode 100644
index d6465477d..000000000
--- a/src/pluto/md2.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
- */
-
-/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
- rights reserved.
-
- License to copy and use this software is granted for
- non-commercial Internet Privacy-Enhanced Mail provided that it is
- identified as the "RSA Data Security, Inc. MD2 Message Digest
- Algorithm" in all material mentioning or referencing this software
- or this function.
-
- RSA Data Security, Inc. makes no representations concerning either
- the merchantability of this software or the suitability of this
- software for any particular purpose. It is provided "as is"
- without express or implied warranty of any kind.
-
- These notices must be retained in any copies of any part of this
- documentation and/or software.
- */
-
-#include "md2.h"
-
-#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
-
-static void MD2Transform PROTO_LIST
- ((unsigned char [16], unsigned char [16], const unsigned char [16]));
-
-#ifdef HAVEMEMCOPY
-#include <memory.h>
-#define MD2_memcpy memcpy
-#define MD2_memset memset
-#else
-#ifdef HAVEBCOPY
-#define MD2_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
-#define MD2_memset(_a,_b,_c) memset((_a), '\0',(_c))
-#else
-static void MD2_memcpy PROTO_LIST ((POINTER, CONST_POINTER, unsigned int));
-static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int));
-#endif
-#endif
-
-/* Permutation of 0..255 constructed from the digits of pi. It gives a
- "random" nonlinear byte substitution operation.
- */
-static unsigned char PI_SUBST[256] = {
- 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
- 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
- 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
- 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
- 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
- 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
- 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
- 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
- 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
- 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
- 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
- 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
- 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
- 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
- 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
- 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
- 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
- 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
-};
-
-static const unsigned char *PADDING[] = {
- (const unsigned char *)"",
- (const unsigned char *)"\001",
- (const unsigned char *)"\002\002",
- (const unsigned char *)"\003\003\003",
- (const unsigned char *)"\004\004\004\004",
- (const unsigned char *)"\005\005\005\005\005",
- (const unsigned char *)"\006\006\006\006\006\006",
- (const unsigned char *)"\007\007\007\007\007\007\007",
- (const unsigned char *)"\010\010\010\010\010\010\010\010",
- (const unsigned char *)"\011\011\011\011\011\011\011\011\011",
- (const unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
- (const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
- (const unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
- (const unsigned char *)
- "\015\015\015\015\015\015\015\015\015\015\015\015\015",
- (const unsigned char *)
- "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
- (const unsigned char *)
- "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
- (const unsigned char *)
- "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
-};
-
-/* MD2 initialization. Begins an MD2 operation, writing a new context.
- */
-void MD2Init (context)
-MD2_CTX *context; /* context */
-{
- context->count = 0;
- MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
- MD2_memset
- ((POINTER)context->checksum, 0, sizeof (context->checksum));
-}
-
-/* MD2 block update operation. Continues an MD2 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD2Update (context, input, inputLen)
-MD2_CTX *context; /* context */
-const unsigned char *input; /* input block */
-unsigned int inputLen; /* length of input block */
-{
- unsigned int i, index, partLen;
-
- /* Update number of bytes mod 16 */
- index = context->count;
- context->count = (index + inputLen) & 0xf;
-
- partLen = 16 - index;
-
- /* Transform as many times as possible.
- */
- if (inputLen >= partLen) {
- MD2_memcpy
- ((POINTER)&context->buffer[index], (CONST_POINTER)input, partLen);
- MD2Transform (context->state, context->checksum, context->buffer);
-
- for (i = partLen; i + 15 < inputLen; i += 16)
- MD2Transform (context->state, context->checksum, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD2_memcpy
- ((POINTER)&context->buffer[index], (CONST_POINTER)&input[i],
- inputLen-i);
-}
-
-/* MD2 finalization. Ends an MD2 message-digest operation, writing the
- message digest and zeroizing the context.
- */
-void MD2Final (digest, context)
-
-unsigned char digest[16]; /* message digest */
-MD2_CTX *context; /* context */
-{
- unsigned int index, padLen;
-
- /* Pad out to multiple of 16.
- */
- index = context->count;
- padLen = 16 - index;
- MD2Update (context, PADDING[padLen], padLen);
-
- /* Extend with checksum */
- MD2Update (context, context->checksum, 16);
-
- /* Store state in digest */
- MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16);
-
- /* Zeroize sensitive information.
- */
- MD2_memset ((POINTER)context, 0, sizeof (*context));
-}
-
-/* MD2 basic transformation. Transforms state and updates checksum
- based on block.
- */
-static void MD2Transform (state, checksum, block)
-unsigned char state[16];
-unsigned char checksum[16];
-const unsigned char block[16];
-{
- unsigned int i, j, t;
- unsigned char x[48];
-
- /* Form encryption block from state, block, state ^ block.
- */
- MD2_memcpy ((POINTER)x, (CONST_POINTER)state, 16);
- MD2_memcpy ((POINTER)x+16, (CONST_POINTER)block, 16);
- for (i = 0; i < 16; i++)
- x[i+32] = state[i] ^ block[i];
-
- /* Encrypt block (18 rounds).
- */
- t = 0;
- for (i = 0; i < 18; i++) {
- for (j = 0; j < 48; j++)
- t = x[j] ^= PI_SUBST[t];
- t = (t + i) & 0xff;
- }
-
- /* Save new state */
- MD2_memcpy ((POINTER)state, (POINTER)x, 16);
-
- /* Update checksum.
- */
- t = checksum[15];
- for (i = 0; i < 16; i++)
- t = checksum[i] ^= PI_SUBST[block[i] ^ t];
-
- /* Zeroize sensitive information.
- */
- MD2_memset ((POINTER)x, 0, sizeof (x));
-}
-
-#ifndef HAVEMEMCOPY
-#ifndef HAVEBCOPY
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-static void MD2_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- output[i] = input[i];
-}
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-static void MD2_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
-#endif
-
diff --git a/src/pluto/md2.h b/src/pluto/md2.h
deleted file mode 100644
index b3b48dd92..000000000
--- a/src/pluto/md2.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
- The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#define PROTOTYPES 1
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-typedef const unsigned char *CONST_POINTER;
-
-/* UINT2 defines a two byte word */
-typedef unsigned short int UINT2;
-
-/* UINT4 defines a four byte word */
-typedef unsigned long int UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-#endif
-
-/* MD2.H - header file for MD2C.C
- */
-
-/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
- rights reserved.
-
- License to copy and use this software is granted for
- non-commercial Internet Privacy-Enhanced Mail provided that it is
- identified as the "RSA Data Security, Inc. MD2 Message Digest
- Algorithm" in all material mentioning or referencing this software
- or this function.
-
- RSA Data Security, Inc. makes no representations concerning either
- the merchantability of this software or the suitability of this
- software for any particular purpose. It is provided "as is"
- without express or implied warranty of any kind.
-
- These notices must be retained in any copies of any part of this
- documentation and/or software.
- */
-
-/* MD2 context. */
-typedef struct {
- unsigned char state[16]; /* state */
- unsigned char checksum[16]; /* checksum */
- unsigned int count; /* number of bytes, modulo 16 */
- unsigned char buffer[16]; /* input buffer */
-} MD2_CTX;
-
-void MD2Init PROTO_LIST ((MD2_CTX *));
-void MD2Update PROTO_LIST
- ((MD2_CTX *, const unsigned char *, unsigned int));
-void MD2Final PROTO_LIST ((unsigned char [16], MD2_CTX *));
-
-#define _MD2_H_
diff --git a/src/pluto/md5.c b/src/pluto/md5.c
deleted file mode 100644
index 5d75e38a4..000000000
--- a/src/pluto/md5.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
- * changes to accomodate it in the kernel by ji.
- * Minor changes to make 64 bit clean by Peter Onion (i.e. using u_int*_t).
- */
-
-/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/*
- * Additions by JI
- *
- * HAVEMEMCOPY is defined if mem* routines are available
- *
- * HAVEHTON is defined if htons() and htonl() can be used
- * for big/little endian conversions
- *
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
-#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
-
-#include "md5.h"
-
-#define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
-
-/* Constants for MD5Transform routine.
- */
-
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-#define MD5Transform _MD5Transform
-
-static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define Encode MD5_memcpy
-#define Decode MD5_memcpy
-#else
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, unsigned char *, unsigned int));
-#endif
-
-#ifdef HAVEMEMCOPY
-#include <memory.h>
-#define MD5_memcpy memcpy
-#define MD5_memset memset
-#else
-#ifdef HAVEBCOPY
-#define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
-#define MD5_memset(_a,_b,_c) memset((_a), '\0',(_c))
-#else
-static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-#endif
-#endif
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context.
- */
-void MD5Init (context)
-MD5_CTX *context; /* context */
-{
- context->count[0] = context->count[1] = 0;
- /* Load magic initialization constants.
-*/
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void MD5Update (context, input, inputLen)
-MD5_CTX *context; /* context */
-const unsigned char *input; /* input block */
-UINT4 inputLen; /* length of input block */
-{
- UINT4 i;
- unsigned int index, partLen;
-
- /* Compute number of bytes mod 64 */
- index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((context->count[0] += (inputLen << 3)) < (inputLen << 3))
- context->count[1]++;
- context->count[1] += (inputLen >> 29);
-
- partLen = 64 - index;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen) {
- MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
- MD5Transform (context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform (context->state, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- MD5_memcpy((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i], inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void MD5Final (digest, context)
-unsigned char digest[16]; /* message digest */
-MD5_CTX *context; /* context */
-{
- unsigned char bits[8];
- unsigned int index, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64.
-*/
- index = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (context, bits, 8);
-
- if (digest != NULL) /* Bill Simpson's padding */
- {
- /* store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information.
- */
- MD5_memset ((POINTER)context, 0, sizeof (*context));
- }
-}
-
-/* MD5 basic transformation. Transforms state based on block.
- */
-static void MD5Transform (state, block)
-UINT4 state[4];
-const unsigned char block[64];
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information.
-*/
- MD5_memset ((POINTER)x, 0, sizeof (x));
-}
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void Encode (output, input, len)
-unsigned char *output;
-UINT4 *input;
-unsigned int len;
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void Decode (output, input, len)
-UINT4 *output;
-unsigned char *input;
-unsigned int len;
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-#endif
-
-#ifndef HAVEMEMCOPY
-#ifndef HAVEBCOPY
-/* Note: Replace "for loop" with standard memcpy if possible.
- */
-
-static void MD5_memcpy (output, input, len)
-POINTER output;
-POINTER input;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
-
- output[i] = input[i];
-}
-
-/* Note: Replace "for loop" with standard memset if possible.
- */
-static void MD5_memset (output, value, len)
-POINTER output;
-int value;
-unsigned int len;
-{
- unsigned int i;
-
- for (i = 0; i < len; i++)
- ((char *)output)[i] = (char)value;
-}
-#endif
-#endif
-
diff --git a/src/pluto/md5.h b/src/pluto/md5.h
deleted file mode 100644
index 9b29bc46e..000000000
--- a/src/pluto/md5.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-/* GLOBAL.H - RSAREF types and constants
- */
-
-/* PROTOTYPES should be set to one if and only if the compiler supports
- function argument prototyping.
- The following makes PROTOTYPES default to 0 if it has not already
- been defined with C compiler flags.
- */
-#ifndef PROTOTYPES
-#define PROTOTYPES 1
-#endif
-
-/* POINTER defines a generic pointer type */
-typedef unsigned char *POINTER;
-typedef const unsigned char *CONSTPOINTER;
-
-/* UINT2 defines a two byte word */
-typedef u_int16_t UINT2;
-
-/* UINT4 defines a four byte word */
-typedef u_int32_t UINT4;
-
-/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
- If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
- returns an empty list.
- */
-
-#if PROTOTYPES
-#define PROTO_LIST(list) list
-#else
-#define PROTO_LIST(list) ()
-#endif
-
-#endif
-
-/* MD5.H - header file for MD5C.C
- */
-
-/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-rights reserved.
-
-License to copy and use this software is granted provided that it
-is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-Algorithm" in all material mentioning or referencing this software
-or this function.
-
-License is also granted to make and use derivative works provided
-that such works are identified as "derived from the RSA Data
-Security, Inc. MD5 Message-Digest Algorithm" in all material
-mentioning or referencing the derived work.
-
-RSA Data Security, Inc. makes no representations concerning either
-the merchantability of this software or the suitability of this
-software for any particular purpose. It is provided "as is"
-without express or implied warranty of any kind.
-
-These notices must be retained in any copies of any part of this
-documentation and/or software.
- */
-
-/* MD5 context. */
-typedef struct {
- UINT4 state[4]; /* state (ABCD) */
- UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
- unsigned char buffer[64]; /* input buffer */
-} MD5_CTX;
-
-void MD5Init PROTO_LIST ((MD5_CTX *));
-void MD5Update PROTO_LIST
- ((MD5_CTX *, const unsigned char *, UINT4));
-void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
-
-#define _MD5_H_
diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c
index 93624588a..228827f2a 100644
--- a/src/pluto/modecfg.c
+++ b/src/pluto/modecfg.c
@@ -2,7 +2,7 @@
* Copyright (C) 2001-2002 Colubris Networks
* Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
* Copyright (C) 2003-2004 Xelerance Corporation
- * Copyright (C) 2006-2007 Andreas Steffen - Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2006-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -14,8 +14,6 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: modecfg.c 3738 2008-04-02 19:04:45Z andreas $
- *
* This code originally written by Colubris Networks, Inc.
* Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
* Porting to 2.x by Sean Mathews
@@ -27,6 +25,9 @@
#include <freeswan.h>
+#include <library.h>
+#include <crypto/prfs/prf.h>
+
#include "constants.h"
#include "defs.h"
#include "state.h"
@@ -34,21 +35,23 @@
#include "timer.h"
#include "ipsec_doi.h"
#include "log.h"
-#include "md5.h"
-#include "sha1.h"
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
#include "xauth.h"
-#define MAX_XAUTH_TRIES 3
+#define MAX_XAUTH_TRIES 3
+#define DNS_SERVER_MAX 2
+#define NBNS_SERVER_MAX 2
#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
- | LELEM(INTERNAL_IP4_NETMASK) \
- | LELEM(INTERNAL_IP4_DNS) \
- | LELEM(INTERNAL_IP4_NBNS) \
- | LELEM(APPLICATION_VERSION) \
- )
+ | LELEM(INTERNAL_IP4_NETMASK) \
+ | LELEM(INTERNAL_IP4_DNS) \
+ | LELEM(INTERNAL_IP4_NBNS) \
+ | LELEM(APPLICATION_VERSION) \
+ | LELEM(INTERNAL_IP6_DNS) \
+ | LELEM(INTERNAL_IP6_NBNS) \
+ )
#define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) )
@@ -61,21 +64,21 @@ typedef struct internal_addr internal_addr_t;
struct internal_addr
{
- lset_t attr_set;
- lset_t xauth_attr_set;
- lset_t unity_attr_set;
+ lset_t attr_set;
+ lset_t xauth_attr_set;
+ lset_t unity_attr_set;
- /* ModeCfg variables */
- ip_address ipaddr;
- ip_address dns[2];
- ip_address wins[2];
+ /* ModeCfg variables */
+ ip_address ipaddr;
+ ip_address dns[DNS_SERVER_MAX];
+ ip_address nbns[NBNS_SERVER_MAX];
- char *unity_banner;
+ char *unity_banner;
- /* XAUTH variables */
- u_int16_t xauth_type;
- xauth_t xauth_secret;
- bool xauth_status;
+ /* XAUTH variables */
+ u_int16_t xauth_type;
+ xauth_t xauth_secret;
+ bool xauth_status;
};
/*
@@ -84,20 +87,30 @@ struct internal_addr
static void
init_internal_addr(internal_addr_t *ia)
{
- ia->attr_set = LEMPTY;
- ia->xauth_attr_set = LEMPTY;
- ia->xauth_secret.user_name = empty_chunk;
- ia->xauth_secret.user_password = empty_chunk;
- ia->xauth_type = XAUTH_TYPE_GENERIC;
- ia->xauth_status = XAUTH_STATUS_FAIL;
- ia->unity_attr_set = LEMPTY;
- ia->unity_banner = NULL;
-
- anyaddr(AF_INET, &ia->ipaddr);
- anyaddr(AF_INET, &ia->dns[0]);
- anyaddr(AF_INET, &ia->dns[1]);
- anyaddr(AF_INET, &ia->wins[0]);
- anyaddr(AF_INET, &ia->wins[1]);
+ int i;
+
+ ia->attr_set = LEMPTY;
+ ia->xauth_attr_set = LEMPTY;
+ ia->xauth_secret.user_name = chunk_empty;
+ ia->xauth_secret.user_password = chunk_empty;
+ ia->xauth_type = XAUTH_TYPE_GENERIC;
+ ia->xauth_status = XAUTH_STATUS_FAIL;
+ ia->unity_attr_set = LEMPTY;
+ ia->unity_banner = NULL;
+
+ anyaddr(AF_INET, &ia->ipaddr);
+
+ /* initialize DNS server information */
+ for (i = 0; i < DNS_SERVER_MAX; i++)
+ {
+ anyaddr(AF_INET, &ia->dns[i]);
+ }
+
+ /* initialize WINS server information */
+ for (i = 0; i < NBNS_SERVER_MAX; i++)
+ {
+ anyaddr(AF_INET, &ia->nbns[i]);
+ }
}
/*
@@ -106,97 +119,152 @@ init_internal_addr(internal_addr_t *ia)
static void
get_internal_addr(struct connection *c, internal_addr_t *ia)
{
- if (isanyaddr(&c->spd.that.host_srcip))
- {
- /* not defined in connection - fetch it from LDAP */
- }
- else
- {
- char srcip[ADDRTOT_BUF];
-
- ia->ipaddr = c->spd.that.host_srcip;
-
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("assigning virtual IP source address %s", srcip);
- }
-
- if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
- {
- c->spd.that.client.addr = ia->ipaddr;
- c->spd.that.client.maskbits = 32;
- c->spd.that.has_client = TRUE;
-
- ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
- }
-
- if (!isanyaddr(&ia->dns[0])) /* We got DNS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
-
- if (!isanyaddr(&ia->wins[0])) /* We got WINS addresses, send them */
- ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+ int i, dns_idx = 0, nbns_idx = 0;
+
+ if (isanyaddr(&c->spd.that.host_srcip))
+ {
+ /* not defined in connection - fetch it from LDAP */
+ }
+ else
+ {
+ char srcip[ADDRTOT_BUF];
+
+ ia->ipaddr = c->spd.that.host_srcip;
+
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("assigning virtual IP source address %s", srcip);
+ }
+
+ if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
+ {
+ c->spd.that.client.addr = ia->ipaddr;
+ c->spd.that.client.maskbits = 32;
+ c->spd.that.has_client = TRUE;
+
+ ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
+ }
+
+ /* assign DNS servers */
+ for (i = 1; i <= DNS_SERVER_MAX; i++)
+ {
+ char dns_key[16], *dns_str;
+
+ snprintf(dns_key, sizeof(dns_key), "pluto.dns%d", i);
+ dns_str = lib->settings->get_str(lib->settings, dns_key, NULL);
+ if (dns_str)
+ {
+ err_t ugh;
+ sa_family_t family = strchr(dns_str, ':') ? AF_INET6 : AF_INET;
+
+ ugh = ttoaddr(dns_str, 0, family, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("error in DNS server address: %s", ugh);
+ continue;
+ }
+ plog("assigning DNS server %s to peer", dns_str);
+
+ /* differentiate between IP4 and IP6 in modecfg_build_msg() */
+ ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
+ dns_idx++;
+ }
+ }
+
+ /* assign WINS servers */
+ for (i = 1; i <= NBNS_SERVER_MAX; i++)
+ {
+ char nbns_key[16], *nbns_str;
+
+ snprintf(nbns_key, sizeof(nbns_key), "pluto.nbns%d", i);
+ nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL);
+ if (nbns_str)
+ {
+ err_t ugh;
+ sa_family_t family = strchr(nbns_str, ':') ? AF_INET6 : AF_INET;
+
+ ugh = ttoaddr(nbns_str, 0, family, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("error in WINS server address: %s", ugh);
+ continue;
+ }
+ plog("assigning NBNS server %s to peer", nbns_str);
+
+ /* differentiate between IP4 and IP6 in modecfg_build_msg() */
+ ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+ nbns_idx++;
+ }
+ }
}
+
/*
* Set srcip and client subnet to internal IP address
*/
static bool
set_internal_addr(struct connection *c, internal_addr_t *ia)
{
- if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
- && !isanyaddr(&ia->ipaddr))
- {
- if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
- || isanyaddr(&c->spd.this.host_srcip)
- || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
+ if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
+ && !isanyaddr(&ia->ipaddr))
{
- char srcip[ADDRTOT_BUF];
+ if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
+ || isanyaddr(&c->spd.this.host_srcip)
+ || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
+ {
+ char srcip[ADDRTOT_BUF];
- addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
- plog("setting virtual IP source address to %s", srcip);
- }
- else
- {
- char old_srcip[ADDRTOT_BUF];
- char new_srcip[ADDRTOT_BUF];
+ addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
+ plog("setting virtual IP source address to %s", srcip);
+ }
+ else
+ {
+ char old_srcip[ADDRTOT_BUF];
+ char new_srcip[ADDRTOT_BUF];
- addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
- addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
- plog("replacing virtual IP source address %s by %s"
- , old_srcip, new_srcip);
+ addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
+ addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
+ plog("replacing virtual IP source address %s by %s"
+ , old_srcip, new_srcip);
+ }
+
+ /* setting srcip */
+ c->spd.this.host_srcip = ia->ipaddr;
+
+ /* setting client subnet to srcip/32 */
+ addrtosubnet(&ia->ipaddr, &c->spd.this.client);
+ setportof(0, &c->spd.this.client.addr);
+ c->spd.this.has_client = TRUE;
+ return TRUE;
}
-
- /* setting srcip */
- c->spd.this.host_srcip = ia->ipaddr;
-
- /* setting client subnet to srcip/32 */
- addrtosubnet(&ia->ipaddr, &c->spd.this.client);
- setportof(0, &c->spd.this.client.addr);
- c->spd.this.has_client = TRUE;
- return TRUE;
- }
- return FALSE;
+ return FALSE;
}
/*
* Compute HASH of Mode Config.
*/
-static size_t
-modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
- , const struct state *st)
+static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
+ const struct state *st)
{
- struct hmac_ctx ctx;
-
- hmac_init_chunk(&ctx, st->st_oakley.hasher, st->st_skeyid_a);
- hmac_update(&ctx, (const u_char *) &st->st_msgid, sizeof(st->st_msgid));
- hmac_update(&ctx, start, roof-start);
- hmac_final(dest, &ctx);
-
- DBG(DBG_CRYPT,
- DBG_log("ModeCfg HASH computed:");
- DBG_dump("", dest, ctx.hmac_digest_size)
- )
- return ctx.hmac_digest_size;
+ chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
+ chunk_t msg_chunk = { start, roof - start };
+ size_t prf_block_size;
+ pseudo_random_function_t prf_alg;
+ prf_t *prf;
+
+ prf_alg = oakley_to_prf(st->st_oakley.hash);
+ prf = lib->crypto->create_prf(lib->crypto, prf_alg);
+ prf->set_key(prf, st->st_skeyid_a);
+ prf->get_bytes(prf, msgid_chunk, NULL);
+ prf->get_bytes(prf, msg_chunk, dest);
+ prf_block_size = prf->get_block_size(prf);
+ prf->destroy(prf);
+
+ DBG(DBG_CRYPT,
+ DBG_log("ModeCfg HASH computed:");
+ DBG_dump("", dest, prf_block_size)
+ )
+ return prf_block_size;
}
@@ -205,202 +273,222 @@ modecfg_hash(u_char *dest, const u_char *start, const u_char *roof
*/
static stf_status
modecfg_build_msg(struct state *st, pb_stream *rbody
- , u_int16_t msg_type
- , internal_addr_t *ia
- , u_int16_t ap_id)
+ , u_int16_t msg_type
+ , internal_addr_t *ia
+ , u_int16_t ap_id)
{
- u_char *r_hash_start, *r_hashval;
+ u_char *r_hash_start, *r_hashval;
- START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
+ START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
- /* ATTR out */
- {
- struct isakmp_mode_attr attrh;
- struct isakmp_attribute attr;
- pb_stream strattr,attrval;
- int attr_type;
- int dns_idx, wins_idx;
- bool dont_advance;
- bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
- bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
- lset_t attr_set = ia->attr_set;
-
- attrh.isama_np = ISAKMP_NEXT_NONE;
- attrh.isama_type = msg_type;
- attrh.isama_identifier = ap_id;
-
- if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
- return STF_INTERNAL_ERROR;
-
- attr_type = 0;
- dns_idx = 0;
- wins_idx = 0;
-
- while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
+ /* ATTR out */
{
- if (attr_set == LEMPTY)
- {
- if (is_xauth_attr_set)
- {
- attr_set = ia->xauth_attr_set;
- attr_type = XAUTH_BASE;
- is_xauth_attr_set = FALSE;
- }
- else
+ struct isakmp_mode_attr attrh;
+ struct isakmp_attribute attr;
+ pb_stream strattr,attrval;
+ int attr_type, dns_attr_type, nbns_attr_type;
+ int dns_idx, nbns_idx;
+ bool dont_advance;
+ bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
+ bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
+ lset_t attr_set = ia->attr_set;
+
+ attrh.isama_np = ISAKMP_NEXT_NONE;
+ attrh.isama_type = msg_type;
+ attrh.isama_identifier = ap_id;
+
+ if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
{
- attr_set = ia->unity_attr_set;
- attr_type = UNITY_BASE;
- is_unity_attr_set = FALSE;
+ return STF_INTERNAL_ERROR;
}
- }
-
- dont_advance = FALSE;
+ attr_type = 0;
+ dns_idx = 0;
+ nbns_idx = 0;
- if (attr_set & 1)
- {
- const u_char *byte_ptr;
- u_int len;
-
- /* ISAKMP attr out */
- if (attr_type == XAUTH_TYPE)
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_type;
- }
- else if (attr_type == XAUTH_STATUS)
+ while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
{
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = ia->xauth_status;
- }
- else
- {
- attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
- }
- out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
-
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (!isanyaddr(&ia->ipaddr))
- {
- len = addrbytesptr(&ia->ipaddr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_addr");
- }
- break;
- case INTERNAL_IP4_NETMASK:
- {
- u_int mask;
-#if 0
- char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t,m=st->st_connection->that.host_addr.maskbit;
- for (t=0; t<4; t++)
+ if (attr_set == LEMPTY)
{
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
+ if (is_xauth_attr_set)
+ {
+ attr_set = ia->xauth_attr_set;
+ attr_type = XAUTH_BASE;
+ is_xauth_attr_set = FALSE;
+ }
+ else
+ {
+ attr_set = ia->unity_attr_set;
+ attr_type = UNITY_BASE;
+ is_unity_attr_set = FALSE;
+ }
}
-#endif
- if (st->st_connection->spd.this.client.maskbits == 0)
- mask = 0;
- else
- mask = 0xffffffff * 1;
- out_raw(&mask, 4, &attrval, "IP4_mask");
- }
- break;
- case INTERNAL_IP4_SUBNET:
- {
- char mask[4];
- char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
- int t;
- int m = st->st_connection->spd.this.client.maskbits;
+
+ dont_advance = FALSE;
- for (t = 0; t < 4; t++)
+ if (attr_set & 1)
{
- if (m < 8)
- mask[t] = bits[m];
- else
- mask[t] = 0xff;
- m -= 8;
- if (m < 0)
- m = 0;
+ const u_char *byte_ptr;
+ u_int len;
+
+ /* ISAKMP attr out */
+ if (attr_type == XAUTH_TYPE)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_type;
+ }
+ else if (attr_type == XAUTH_STATUS)
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = ia->xauth_status;
+ }
+ else if (attr_type == INTERNAL_IP4_DNS && !isanyaddr(&ia->dns[dns_idx]))
+ {
+ dns_attr_type = (addrtypeof(&ia->dns[dns_idx]) == AF_INET) ?
+ INTERNAL_IP4_DNS : INTERNAL_IP6_DNS;
+ attr.isaat_af_type = dns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+ }
+ else if (attr_type == INTERNAL_IP4_NBNS && !isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ nbns_attr_type = (addrtypeof(&ia->nbns[nbns_idx]) == AF_INET) ?
+ INTERNAL_IP4_NBNS : INTERNAL_IP6_NBNS;
+ attr.isaat_af_type = nbns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+ }
+ else
+ {
+ attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
+ }
+ out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
+
+ switch (attr_type)
+ {
+ case INTERNAL_IP4_ADDRESS:
+ if (!isanyaddr(&ia->ipaddr))
+ {
+ len = addrbytesptr(&ia->ipaddr, &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_addr");
+ }
+ break;
+ case INTERNAL_IP4_NETMASK:
+ {
+ u_int mask;
+#if 0
+ char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
+ int t,m=st->st_connection->that.host_addr.maskbit;
+ for (t=0; t<4; t++)
+ {
+ if (m < 8)
+ mask[t] = bits[m];
+ else
+ mask[t] = 0xff;
+ m -= 8;
+ }
+#endif
+ if (st->st_connection->spd.this.client.maskbits == 0)
+ {
+ mask = 0;
+ }
+ else
+ {
+ mask = 0xffffffff * 1;
+ out_raw(&mask, 4, &attrval, "IP4_mask");
+ }
+ }
+ break;
+ case INTERNAL_IP4_SUBNET:
+ {
+ char mask[4];
+ char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
+ int t;
+ int m = st->st_connection->spd.this.client.maskbits;
+
+ for (t = 0; t < 4; t++)
+ {
+ mask[t] = (m < 8) ? bits[m] : 0xff;
+ m -= 8;
+ if (m < 0)
+ {
+ m = 0;
+ }
+ }
+ len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP4_subnet");
+ out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
+ }
+ break;
+ case INTERNAL_IP4_DNS:
+ case INTERNAL_IP6_DNS:
+ if (!isanyaddr(&ia->dns[dns_idx]))
+ {
+ len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP_dns");
+ }
+ if (dns_idx < DNS_SERVER_MAX && !isanyaddr(&ia->dns[dns_idx]))
+ {
+ dont_advance = TRUE;
+ }
+ break;
+ case INTERNAL_IP4_NBNS:
+ case INTERNAL_IP6_NBNS:
+ if (!isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ len = addrbytesptr(&ia->nbns[nbns_idx++], &byte_ptr);
+ out_raw(byte_ptr, len, &attrval, "IP_nbns");
+ }
+ if (nbns_idx < NBNS_SERVER_MAX && !isanyaddr(&ia->nbns[nbns_idx]))
+ {
+ dont_advance = TRUE;
+ }
+ break;
+ case XAUTH_TYPE:
+ break;
+ case XAUTH_USER_NAME:
+ if (ia->xauth_secret.user_name.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_name.ptr
+ , ia->xauth_secret.user_name.len
+ , &attrval, "xauth_user_name");
+ }
+ break;
+ case XAUTH_USER_PASSWORD:
+ if (ia->xauth_secret.user_password.ptr != NULL)
+ {
+ out_raw(ia->xauth_secret.user_password.ptr
+ , ia->xauth_secret.user_password.len
+ , &attrval, "xauth_user_password");
+ }
+ break;
+ case XAUTH_STATUS:
+ break;
+ case UNITY_BANNER:
+ if (ia->unity_banner != NULL)
+ {
+ out_raw(ia->unity_banner
+ , strlen(ia->unity_banner)
+ , &attrval, "UNITY_BANNER");
+ }
+ break;
+ default:
+ plog("attempt to send unsupported mode cfg attribute %s."
+ , enum_show(&modecfg_attr_names, attr_type));
+ break;
+ }
+ close_output_pbs(&attrval);
+ }
+ if (!dont_advance)
+ {
+ attr_type++;
+ attr_set >>= 1;
}
- len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_subnet");
- out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
- }
- break;
- case INTERNAL_IP4_DNS:
- if (!isanyaddr(&ia->dns[dns_idx]))
- {
- len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_dns");
- }
- if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case INTERNAL_IP4_NBNS:
- if (!isanyaddr(&ia->wins[wins_idx]))
- {
- len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
- out_raw(byte_ptr, len, &attrval, "IP4_wins");
- }
- if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
- {
- dont_advance = TRUE;
- }
- break;
- case XAUTH_TYPE:
- break;
- case XAUTH_USER_NAME:
- if (ia->xauth_secret.user_name.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_name.ptr
- , ia->xauth_secret.user_name.len
- , &attrval, "xauth_user_name");
- }
- break;
- case XAUTH_USER_PASSWORD:
- if (ia->xauth_secret.user_password.ptr != NULL)
- {
- out_raw(ia->xauth_secret.user_password.ptr
- , ia->xauth_secret.user_password.len
- , &attrval, "xauth_user_password");
- }
- break;
- case XAUTH_STATUS:
- break;
- case UNITY_BANNER:
- if (ia->unity_banner != NULL)
- {
- out_raw(ia->unity_banner
- , strlen(ia->unity_banner)
- , &attrval, "UNITY_BANNER");
- }
- break;
- default:
- plog("attempt to send unsupported mode cfg attribute %s."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
}
- close_output_pbs(&attrval);
- }
- if (!dont_advance)
- {
- attr_type++;
- attr_set >>= 1;
- }
+ close_message(&strattr);
}
- close_message(&strattr);
- }
- modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
- close_message(rbody);
- encrypt_message(rbody, st);
- return STF_OK;
+ modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
+ close_message(rbody);
+ encrypt_message(rbody, st);
+ return STF_OK;
}
/*
@@ -409,55 +497,56 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
static stf_status
modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
{
- pb_stream msg;
- pb_stream rbody;
- char buf[BUF_LEN];
-
- /* set up attr */
- init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
-
- /* this is the beginning of a new exchange */
- st->st_msgid = generate_msgid(st);
- init_phase2_iv(st, &st->st_msgid);
-
- /* HDR out */
- {
- struct isakmp_hdr hdr;
-
- zero(&hdr); /* default to 0 */
- hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
- hdr.isa_np = ISAKMP_NEXT_HASH;
- hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
- hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
- memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
- hdr.isa_msgid = st->st_msgid;
-
- if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
+ pb_stream msg;
+ pb_stream rbody;
+ char buf[BUF_LEN];
+
+ /* set up attr */
+ init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
+
+ /* this is the beginning of a new exchange */
+ st->st_msgid = generate_msgid(st);
+ init_phase2_iv(st, &st->st_msgid);
+
+ /* HDR out */
{
- return STF_INTERNAL_ERROR;
+ struct isakmp_hdr hdr;
+
+ zero(&hdr); /* default to 0 */
+ hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ hdr.isa_np = ISAKMP_NEXT_HASH;
+ hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
+ hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
+ memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
+ hdr.isa_msgid = st->st_msgid;
+
+ if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
+ {
+ return STF_INTERNAL_ERROR;
+ }
}
- }
-
- /* ATTR out */
- modecfg_build_msg(st, &rbody
- , isama_type
- , ia
- , 0 /* XXX isama_id */
- );
-
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
-
- /* Transmit */
- send_packet(st, "ModeCfg msg");
-
- if (st->st_event->ev_type != EVENT_RETRANSMIT)
- {
- delete_event(st);
- event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
- }
- return STF_OK;
+
+ /* ATTR out */
+ modecfg_build_msg(st, &rbody
+ , isama_type
+ , ia
+ , 0 /* XXX isama_id */
+ );
+
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(msg.start, pbs_offset(&msg));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+
+ /* Transmit */
+ send_packet(st, "ModeCfg msg");
+
+ if (st->st_event->ev_type != EVENT_RETRANSMIT)
+ {
+ delete_event(st);
+ event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
+ }
+ return STF_OK;
}
/*
@@ -466,111 +555,184 @@ modecfg_send_msg(struct state *st, int isama_type, internal_addr_t *ia)
static stf_status
modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
{
- struct isakmp_attribute attr;
- pb_stream strattr;
-
- while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
- {
- u_int16_t attr_type;
- u_int16_t attr_len;
+ struct isakmp_attribute attr;
+ pb_stream strattr;
+ err_t ugh;
+ char buf[BUF_LEN];
+ int dns_idx = 0;
+ int nbns_idx = 0;
- if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
+ while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
{
- return STF_FAIL;
- }
- attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
- attr_len = attr.isaat_lv;
+ u_int16_t attr_type;
+ u_int16_t attr_len;
- switch (attr_type)
- {
- case INTERNAL_IP4_ADDRESS:
- if (attr_len == 4)
- {
- initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
- }
- /* fall through to set attribute flag */
- case INTERNAL_IP4_NETMASK:
- case INTERNAL_IP4_DNS:
- case INTERNAL_IP4_SUBNET:
- case INTERNAL_IP4_NBNS:
- case INTERNAL_ADDRESS_EXPIRY:
- case INTERNAL_IP4_DHCP:
- case INTERNAL_IP6_ADDRESS:
- case INTERNAL_IP6_NETMASK:
- case INTERNAL_IP6_DNS:
- case INTERNAL_IP6_NBNS:
- case INTERNAL_IP6_DHCP:
- case SUPPORTED_ATTRIBUTES:
- case INTERNAL_IP6_SUBNET:
- ia->attr_set |= LELEM(attr_type);
- break;
- case APPLICATION_VERSION:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- ia->attr_set |= LELEM(attr_type);
- break;
- case XAUTH_TYPE:
- ia->xauth_type = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_NAME:
- setchunk(ia->xauth_secret.user_name, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_USER_PASSWORD:
- setchunk(ia->xauth_secret.user_password, strattr.cur, attr_len);
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_STATUS:
- ia->xauth_status = attr.isaat_lv;
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case XAUTH_MESSAGE:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case XAUTH_PASSCODE:
- case XAUTH_CHALLENGE:
- case XAUTH_DOMAIN:
- case XAUTH_NEXT_PIN:
- case XAUTH_ANSWER:
- ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
- break;
- case UNITY_DDNS_HOSTNAME:
- if (attr_len > 0)
- {
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", attr_len, strattr.cur)
- )
- }
- /* fall through to set attribute flag */
- case UNITY_BANNER:
- case UNITY_SAVE_PASSWD:
- case UNITY_DEF_DOMAIN:
- case UNITY_SPLITDNS_NAME:
- case UNITY_SPLIT_INCLUDE:
- case UNITY_NATT_PORT:
- case UNITY_LOCAL_LAN:
- case UNITY_PFS:
- case UNITY_FW_TYPE:
- case UNITY_BACKUP_SERVERS:
- ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
- break;
- default:
- plog("unsupported ModeCfg attribute %s received."
- , enum_show(&modecfg_attr_names, attr_type));
- break;
+ if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
+ {
+ return STF_FAIL;
+ }
+ attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
+ attr_len = attr.isaat_lv;
+
+ switch (attr_type)
+ {
+ case INTERNAL_IP4_ADDRESS:
+ if (attr_len == 4)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
+ if (ugh != NULL)
+ {
+ plog("received invalid virtual IPv4 address: %s", ugh);
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_DNS:
+ if (attr_len == 4 && dns_idx < DNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv4 DNS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
+ plog("received IPv4 DNS server address %s", buf);
+ dns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_NBNS:
+ if (attr_len == 4 && nbns_idx < NBNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv4 WINS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
+ plog("received IPv4 WINS server address %s", buf);
+ nbns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP6_DNS:
+ if (attr_len == 16 && dns_idx < DNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->dns[dns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv6 DNS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
+ plog("received IPv6 DNS server address %s", buf);
+ dns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP6_NBNS:
+ if (attr_len == 16 && nbns_idx < NBNS_SERVER_MAX)
+ {
+ ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->nbns[nbns_idx]);
+ if (ugh != NULL)
+ {
+ plog("received invalid IPv6 WINS server address: %s", ugh);
+ }
+ else
+ {
+ addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
+ plog("received IPv6 WINS server address %s", buf);
+ nbns_idx++;
+ }
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case INTERNAL_IP4_NETMASK:
+ case INTERNAL_IP4_SUBNET:
+ case INTERNAL_ADDRESS_EXPIRY:
+ case INTERNAL_IP4_DHCP:
+ case INTERNAL_IP6_ADDRESS:
+ case INTERNAL_IP6_NETMASK:
+ case INTERNAL_IP6_DHCP:
+ case SUPPORTED_ATTRIBUTES:
+ case INTERNAL_IP6_SUBNET:
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case APPLICATION_VERSION:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ ia->attr_set |= LELEM(attr_type);
+ break;
+ case XAUTH_TYPE:
+ ia->xauth_type = attr.isaat_lv;
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_USER_NAME:
+ ia->xauth_secret.user_name = chunk_create(strattr.cur, attr_len);
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_USER_PASSWORD:
+ ia->xauth_secret.user_password = chunk_create(strattr.cur, attr_len);
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_STATUS:
+ ia->xauth_status = attr.isaat_lv;
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case XAUTH_MESSAGE:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ /* fall through to set attribute flag */
+ case XAUTH_PASSCODE:
+ case XAUTH_CHALLENGE:
+ case XAUTH_DOMAIN:
+ case XAUTH_NEXT_PIN:
+ case XAUTH_ANSWER:
+ ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
+ break;
+ case UNITY_DDNS_HOSTNAME:
+ if (attr_len > 0)
+ {
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", attr_len, strattr.cur)
+ )
+ }
+ /* fall through to set attribute flag */
+ case UNITY_BANNER:
+ case UNITY_SAVE_PASSWD:
+ case UNITY_DEF_DOMAIN:
+ case UNITY_SPLITDNS_NAME:
+ case UNITY_SPLIT_INCLUDE:
+ case UNITY_NATT_PORT:
+ case UNITY_LOCAL_LAN:
+ case UNITY_PFS:
+ case UNITY_FW_TYPE:
+ case UNITY_BACKUP_SERVERS:
+ ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
+ break;
+ default:
+ plog("unsupported ModeCfg attribute %s received."
+ , enum_show(&modecfg_attr_names, attr_type));
+ break;
+ }
}
- }
- return STF_OK;
+ return STF_OK;
}
/*
@@ -578,50 +740,52 @@ modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
*/
static stf_status
modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
- , internal_addr_t *ia)
+ , internal_addr_t *ia)
{
- struct state *const st = md->st;
- struct payload_digest *p;
- stf_status stat;
+ struct state *const st = md->st;
+ struct payload_digest *p;
+ stf_status stat;
- st->st_msgid = md->hdr.isa_msgid;
+ st->st_msgid = md->hdr.isa_msgid;
- CHECK_QUICK_HASH(md, modecfg_hash(hash_val
- , hash_pbs->roof
- , md->message_pbs.roof, st)
- , "MODECFG-HASH", "ISAKMP_CFG_MSG");
+ CHECK_QUICK_HASH(md, modecfg_hash(hash_val
+ , hash_pbs->roof
+ , md->message_pbs.roof, st)
+ , "MODECFG-HASH", "ISAKMP_CFG_MSG");
- /* process the ModeCfg payloads received */
- for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
- {
- internal_addr_t ia_candidate;
+ /* process the ModeCfg payloads received */
+ for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
+ {
+ internal_addr_t ia_candidate;
- init_internal_addr(&ia_candidate);
+ init_internal_addr(&ia_candidate);
- if (p->payload.attribute.isama_type == isama_type)
- {
- *isama_id = p->payload.attribute.isama_identifier;
+ if (p->payload.attribute.isama_type == isama_type)
+ {
+ *isama_id = p->payload.attribute.isama_identifier;
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
- if (stat == STF_OK)
- {
- /* return with a valid set of attributes */
- *ia = ia_candidate;
- return STF_OK;
- }
- }
- else
- {
- plog("expected %s, got %s instead (ignored)"
- , enum_name(&attr_msg_type_names, isama_type)
- , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ if (stat == STF_OK)
+ {
+ /* return with a valid set of attributes */
+ *ia = ia_candidate;
+ return STF_OK;
+ }
+ }
+ else
+ {
+ plog("expected %s, got %s instead (ignored)"
+ , enum_name(&attr_msg_type_names, isama_type)
+ , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
- stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
+ }
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
}
- if (stat != STF_OK)
- return stat;
- }
- return STF_IGNORE;
+ return STF_IGNORE;
}
/*
@@ -630,20 +794,22 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
stf_status
modecfg_send_request(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
+ stf_status stat;
+ internal_addr_t ia;
- init_internal_addr(&ia);
+ init_internal_addr(&ia);
- ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
+ ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
- plog("sending ModeCfg request");
- st->st_state = STATE_MODE_CFG_I1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
+ plog("sending ModeCfg request");
+ st->st_state = STATE_MODE_CFG_I1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_modecfg.started = TRUE;
+ }
+ return stat;
}
/* STATE_MODE_CFG_R0:
@@ -654,38 +820,40 @@ modecfg_send_request(struct state *st)
stf_status
modecfg_inR0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- bool want_unity_banner;
- stf_status stat, stat_build;
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ bool want_unity_banner;
+ stf_status stat, stat_build;
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
- if (want_unity_banner)
- {
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
- }
+ want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
+ init_internal_addr(&ia);
+ get_internal_addr(st->st_connection, &ia);
- plog("sending ModeCfg reply");
+ if (want_unity_banner)
+ {
+ ia.unity_banner = UNITY_BANNER_STR;
+ ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
+ }
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
+ plog("sending ModeCfg reply");
- st->st_msgid = 0;
- return STF_OK;
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/* STATE_MODE_CFG_I1:
@@ -696,20 +864,21 @@ modecfg_inR0(struct msg_digest *md)
stf_status
modecfg_inI1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
-
- plog("parsing ModeCfg reply");
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ plog("parsing ModeCfg reply");
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+ st->st_msgid = 0;
+ return STF_OK;
}
@@ -719,23 +888,25 @@ modecfg_inI1(struct msg_digest *md)
stf_status
modecfg_send_set(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
+ stf_status stat;
+ internal_addr_t ia;
- init_internal_addr(&ia);
- get_internal_addr(st->st_connection, &ia);
+ init_internal_addr(&ia);
+ get_internal_addr(st->st_connection, &ia);
#ifdef CISCO_QUIRKS
- ia.unity_banner = UNITY_BANNER_STR;
- ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
+ ia.unity_banner = UNITY_BANNER_STR;
+ ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
#endif
plog("sending ModeCfg set");
- st->st_state = STATE_MODE_CFG_R3;
- stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
+ st->st_state = STATE_MODE_CFG_R3;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_modecfg.started = TRUE;
+ }
+ return stat;
}
/* STATE_MODE_CFG_I0:
@@ -746,38 +917,40 @@ modecfg_send_set(struct state *st)
stf_status
modecfg_inI0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- lset_t attr_set, unity_attr_set;
- stf_status stat, stat_build;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ lset_t attr_set, unity_attr_set;
+ stf_status stat, stat_build;
- plog("parsing ModeCfg set");
+ plog("parsing ModeCfg set");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
-
- /* prepare ModeCfg ack which sends zero length attributes */
- attr_set = ia.attr_set;
- unity_attr_set = ia.unity_attr_set;
- init_internal_addr(&ia);
- ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
- ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
-
- plog("sending ModeCfg ack");
-
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
+
+ /* prepare ModeCfg ack which sends zero length attributes */
+ attr_set = ia.attr_set;
+ unity_attr_set = ia.unity_attr_set;
+ init_internal_addr(&ia);
+ ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
+ ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
+
+ plog("sending ModeCfg ack");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/* STATE_MODE_CFG_R3:
@@ -788,19 +961,20 @@ modecfg_inI0(struct msg_digest *md)
stf_status
modecfg_inR3(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- plog("parsing ModeCfg ack");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ plog("parsing ModeCfg ack");
- st->st_msgid = 0;
- return STF_OK;
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_msgid = 0;
+ return STF_OK;
}
/*
@@ -809,19 +983,21 @@ modecfg_inR3(struct msg_digest *md)
stf_status
xauth_send_request(struct state *st)
{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
-
- plog("sending XAUTH request");
- st->st_state = STATE_XAUTH_R1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_xauth.started = TRUE;
- return stat;
+ stf_status stat;
+ internal_addr_t ia;
+
+ init_internal_addr(&ia);
+ ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
+
+ plog("sending XAUTH request");
+ st->st_state = STATE_XAUTH_R1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ {
+ st->st_xauth.started = TRUE;
+ }
+ return stat;
}
/* STATE_XAUTH_I0:
@@ -832,97 +1008,102 @@ xauth_send_request(struct state *st)
stf_status
xauth_inI0(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
- bool xauth_type_present;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+ bool xauth_type_present;
- plog("parsing XAUTH request");
+ plog("parsing XAUTH request");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* check XAUTH attributes */
- xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
-
- if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
- {
- plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH request");
- stat = STF_FAIL;
- }
-
- /* prepare XAUTH reply */
- init_internal_addr(&ia);
-
- if (stat == STF_OK)
- {
- /* get user credentials using a plugin function */
- if (!xauth_module.get_secret(&ia.xauth_secret))
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
+ if (stat != STF_OK)
{
- plog("xauth user credentials not found");
- stat = STF_FAIL;
+ return stat;
}
- }
- if (stat == STF_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("my xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("my xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
- if (xauth_type_present)
- ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
- }
- else
- {
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = XAUTH_STATUS_FAIL;
- }
- plog("sending XAUTH reply");
+ /* check XAUTH attributes */
+ xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
+ if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
+ {
+ plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
+ stat = STF_FAIL;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH request");
+ stat = STF_FAIL;
+ }
- if (stat == STF_OK)
- {
- st->st_xauth.started = TRUE;
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH reply msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH reply msg");
- send_packet(st, "XAUTH reply msg");
- delete_state(st);
- return STF_IGNORE;
- }
+ /* prepare XAUTH reply */
+ init_internal_addr(&ia);
+
+ if (stat == STF_OK)
+ {
+ /* get user credentials using a plugin function */
+ if (!xauth_module.get_secret(&ia.xauth_secret))
+ {
+ plog("xauth user credentials not found");
+ stat = STF_FAIL;
+ }
+ }
+ if (stat == STF_OK)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("my xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("my xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
+ if (xauth_type_present)
+ {
+ ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
+ }
+ }
+ else
+ {
+ ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
+ ia.xauth_status = XAUTH_STATUS_FAIL;
+ }
+
+ plog("sending XAUTH reply");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ if (stat == STF_OK)
+ {
+ st->st_xauth.started = TRUE;
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH reply msg and then delete ISAKMP SA */
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+ send_packet(st, "XAUTH reply msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
/* STATE_XAUTH_R1:
@@ -933,72 +1114,76 @@ xauth_inI0(struct msg_digest *md)
stf_status
xauth_inR1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
- plog("parsing XAUTH reply");
+ plog("parsing XAUTH reply");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- /* did the client return an XAUTH FAIL status? */
- if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
- {
- plog("received FAIL status in XAUTH reply");
-
- /* client is not able to do XAUTH, delete ISAKMP SA */
- delete_state(st);
- return STF_IGNORE;
- }
-
- /* check XAUTH reply */
- if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH reply");
- st->st_xauth.status = FALSE;
- }
- else
- {
- xauth_peer_t peer;
-
- peer.conn_name = st->st_connection->name;
- addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
- idtoa(&md->st->st_connection->spd.that.id, peer.id, sizeof(peer.id));
-
- DBG(DBG_CONTROL,
- DBG_log("peer xauth user name is '%.*s'"
- , ia.xauth_secret.user_name.len
- , ia.xauth_secret.user_name.ptr)
- )
- DBG(DBG_PRIVATE,
- DBG_log("peer xauth user password is '%.*s'"
- , ia.xauth_secret.user_password.len
- , ia.xauth_secret.user_password.ptr)
- )
- /* verify the user credentials using a plugin function */
- st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
- }
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+
+ /* did the client return an XAUTH FAIL status? */
+ if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
+ {
+ plog("received FAIL status in XAUTH reply");
+
+ /* client is not able to do XAUTH, delete ISAKMP SA */
+ delete_state(st);
+ return STF_IGNORE;
+ }
+
+ /* check XAUTH reply */
+ if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else
+ {
+ xauth_peer_t peer;
+
+ peer.conn_name = st->st_connection->name;
+ addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
+ idtoa(&md->st->st_connection->spd.that.id, peer.id, sizeof(peer.id));
+
+ DBG(DBG_CONTROL,
+ DBG_log("peer xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("peer xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ /* verify the user credentials using a plugin function */
+ st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+ }
- /* prepare XAUTH set which sends the authentication status */
- init_internal_addr(&ia);
- ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
- ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
+ /* prepare XAUTH set which sends the authentication status */
+ init_internal_addr(&ia);
+ ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
+ ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
- plog("sending XAUTH status:");
+ plog("sending XAUTH status:");
- stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat_build != STF_OK)
- return stat_build;
- return STF_OK;
+ stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ return STF_OK;
}
/* STATE_XAUTH_I1:
@@ -1009,47 +1194,48 @@ xauth_inR1(struct msg_digest *md)
stf_status
xauth_inI1(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat, stat_build;
-
- plog("parsing XAUTH status");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
- return stat;
- }
-
- st->st_xauth.status = ia.xauth_status;
- plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
-
- plog("sending XAUTH ack");
- init_internal_addr(&ia);
- stat_build = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat_build != STF_OK)
- return stat_build;
-
- if (st->st_xauth.status)
- {
- st->st_msgid = 0;
- return STF_OK;
- }
- else
- {
- /* send XAUTH ack msg and then delete ISAKMP SA */
- freeanychunk(st->st_tpacket);
- clonetochunk(st->st_tpacket, md->reply.start
- , pbs_offset(&md->reply), "XAUTH ack msg");
- send_packet(st, "XAUTH ack msg");
- delete_state(st);
- return STF_IGNORE;
- }
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+
+ plog("parsing XAUTH status");
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ /* notification payload - not exactly the right choice, but okay */
+ md->note = ATTRIBUTES_NOT_SUPPORTED;
+ return stat;
+ }
+
+ st->st_xauth.status = ia.xauth_status;
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+
+ plog("sending XAUTH ack");
+ init_internal_addr(&ia);
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ {
+ return stat_build;
+ }
+ if (st->st_xauth.status)
+ {
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH ack msg and then delete ISAKMP SA */
+ free(st->st_tpacket.ptr);
+ st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
+ st->st_tpacket = chunk_clone(st->st_tpacket);
+ send_packet(st, "XAUTH ack msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
/* STATE_XAUTH_R2:
@@ -1060,25 +1246,26 @@ xauth_inI1(struct msg_digest *md)
stf_status
xauth_inR2(struct msg_digest *md)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
- stf_status stat;
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
- plog("parsing XAUTH ack");
+ plog("parsing XAUTH ack");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
-
- st->st_msgid = 0;
- if (st->st_xauth.status)
- {
- return STF_OK;
- }
- else
- {
- delete_state(st);
- return STF_IGNORE;
- }
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ {
+ return stat;
+ }
+ st->st_msgid = 0;
+ if (st->st_xauth.status)
+ {
+ return STF_OK;
+ }
+ else
+ {
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
diff --git a/src/pluto/modecfg.h b/src/pluto/modecfg.h
index 95481de89..86bfc6ed2 100644
--- a/src/pluto/modecfg.h
+++ b/src/pluto/modecfg.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: modecfg.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _MODECFG_H
diff --git a/src/pluto/mp_defs.c b/src/pluto/mp_defs.c
deleted file mode 100644
index cdae8ee79..000000000
--- a/src/pluto/mp_defs.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* some multiprecision utilities
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: mp_defs.c 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-
-/* Convert MP_INT to network form (binary octets, big-endian).
- * We do the malloc; caller must eventually do free.
- */
-chunk_t
-mpz_to_n(const MP_INT *mp, size_t bytes)
-{
- chunk_t r;
- MP_INT temp1, temp2;
- int i;
-
- r.len = bytes;
- r.ptr = alloc_bytes(r.len, "host representation of large integer");
-
- mpz_init(&temp1);
- mpz_init(&temp2);
-
- mpz_set(&temp1, mp);
-
- for (i = r.len-1; i >= 0; i--)
- {
- r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
- mpz_set(&temp1, &temp2);
- }
-
- passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
- mpz_clear(&temp1);
- mpz_clear(&temp2);
-
- return r;
-}
-
-/* Convert network form (binary bytes, big-endian) to MP_INT.
- * The *mp must not be previously mpz_inited.
- */
-void
-n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen)
-{
- size_t i;
-
- mpz_init_set_ui(mp, 0);
-
- for (i = 0; i != nlen; i++)
- {
- mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
- mpz_add_ui(mp, mp, nbytes[i]);
- }
-}
diff --git a/src/pluto/mp_defs.h b/src/pluto/mp_defs.h
deleted file mode 100644
index e0ec74df8..000000000
--- a/src/pluto/mp_defs.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* some multiprecision utilities
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: mp_defs.h 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#ifndef _MP_DEFS_H
-#define _MP_DEFS_H
-
-#include <gmp.h>
-
-#include "defs.h"
-
-extern void n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen);
-extern chunk_t mpz_to_n(const MP_INT *mp, size_t bytes);
-
-/* var := mod(base ** exp, mod), ensuring var is mpz_inited */
-#define mpz_init_powm(flag, var, base, exp, mod) { \
- if (!(flag)) \
- mpz_init(&(var)); \
- (flag) = TRUE; \
- mpz_powm(&(var), &(base), &(exp), (mod)); \
- }
-
-#endif /* _MP_DEFS_H */
diff --git a/src/pluto/nat_traversal.c b/src/pluto/nat_traversal.c
index 95ce9e32e..de3972fe2 100644
--- a/src/pluto/nat_traversal.c
+++ b/src/pluto/nat_traversal.c
@@ -1,5 +1,6 @@
/* FreeS/WAN NAT-Traversal
* Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: nat_traversal.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -26,10 +25,12 @@
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include <pfkeyv2.h>
#include <pfkey.h>
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
#include "constants.h"
#include "defs.h"
#include "log.h"
@@ -42,8 +43,6 @@
#include "whack.h"
#include "timer.h"
#include "cookie.h"
-#include "sha1.h"
-#include "md5.h"
#include "crypto.h"
#include "vendor.h"
#include "ike_alg.h"
@@ -79,81 +78,91 @@ static bool _force_ka = 0;
static const char *natt_version = "0.6c";
void init_nat_traversal (bool activate, unsigned int keep_alive_period,
- bool fka, bool spf)
+ bool fka, bool spf)
{
- nat_traversal_enabled = activate;
- nat_traversal_support_non_ike = activate;
+ nat_traversal_enabled = activate;
+ nat_traversal_support_non_ike = activate;
#ifdef NAT_T_SUPPORT_LAST_DRAFTS
- nat_traversal_support_port_floating = activate ? spf : FALSE;
+ nat_traversal_support_port_floating = activate ? spf : FALSE;
#endif
- _force_ka = fka;
- _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD;
- plog(" including NAT-Traversal patch (Version %s)%s%s%s"
- , natt_version, activate ? "" : " [disabled]"
- , activate & fka ? " [Force KeepAlive]" : ""
- , activate & !spf ? " [Port Floating disabled]" : "");
+ _force_ka = fka;
+ _kap = keep_alive_period ? keep_alive_period : DEFAULT_KEEP_ALIVE_PERIOD;
+ plog(" including NAT-Traversal patch (Version %s)%s%s%s"
+ , natt_version, activate ? "" : " [disabled]"
+ , activate & fka ? " [Force KeepAlive]" : ""
+ , activate & !spf ? " [Port Floating disabled]" : "");
}
static void disable_nat_traversal (int type)
{
- if (type == ESPINUDP_WITH_NON_IKE)
- nat_traversal_support_non_ike = FALSE;
- else
- nat_traversal_support_port_floating = FALSE;
-
- if (!nat_traversal_support_non_ike &&
- !nat_traversal_support_port_floating)
- nat_traversal_enabled = FALSE;
+ if (type == ESPINUDP_WITH_NON_IKE)
+ nat_traversal_support_non_ike = FALSE;
+ else
+ nat_traversal_support_port_floating = FALSE;
+
+ if (!nat_traversal_support_non_ike &&
+ !nat_traversal_support_port_floating)
+ nat_traversal_enabled = FALSE;
}
-static void _natd_hash(const struct hash_desc *hasher, char *hash,
- u_int8_t *icookie, u_int8_t *rcookie,
- const ip_address *ip, u_int16_t port)
+static void _natd_hash(const struct hash_desc *oakley_hasher, char *hash,
+ u_int8_t *icookie, u_int8_t *rcookie,
+ const ip_address *ip, u_int16_t port)
{
- union hash_ctx ctx;
-
- if (is_zero_cookie(icookie))
- DBG_log("_natd_hash: Warning, icookie is zero !!");
- if (is_zero_cookie(rcookie))
- DBG_log("_natd_hash: Warning, rcookie is zero !!");
-
- /**
- * draft-ietf-ipsec-nat-t-ike-01.txt
- *
- * HASH = HASH(CKY-I | CKY-R | IP | Port)
- *
- * All values in network order
- */
- hasher->hash_init(&ctx);
- hasher->hash_update(&ctx, icookie, COOKIE_SIZE);
- hasher->hash_update(&ctx, rcookie, COOKIE_SIZE);
- switch (addrtypeof(ip)) {
- case AF_INET:
- hasher->hash_update(&ctx, (const u_char *)&ip->u.v4.sin_addr.s_addr
- , sizeof(ip->u.v4.sin_addr.s_addr));
- break;
- case AF_INET6:
- hasher->hash_update(&ctx, (const u_char *)&ip->u.v6.sin6_addr.s6_addr
- , sizeof(ip->u.v6.sin6_addr.s6_addr));
- break;
- }
- hasher->hash_update(&ctx, (const u_char *)&port, sizeof(u_int16_t));
- hasher->hash_final(hash, &ctx);
-#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("_natd_hash: hasher=%p(%d)", hasher, (int)hasher->hash_digest_len);
- DBG_dump("_natd_hash: icookie=", icookie, COOKIE_SIZE);
- DBG_dump("_natd_hash: rcookie=", rcookie, COOKIE_SIZE);
- switch (addrtypeof(ip)) {
- case AF_INET:
- DBG_dump("_natd_hash: ip=", &ip->u.v4.sin_addr.s_addr
- , sizeof(ip->u.v4.sin_addr.s_addr));
- break;
+ if (is_zero_cookie(icookie))
+ {
+ DBG_log("_natd_hash: Warning, icookie is zero !!");
}
- DBG_log("_natd_hash: port=%d", port);
- DBG_dump("_natd_hash: hash=", hash, hasher->hash_digest_len);
- );
+ if (is_zero_cookie(rcookie))
+ {
+ DBG_log("_natd_hash: Warning, rcookie is zero !!");
+ }
+
+ /**
+ * draft-ietf-ipsec-nat-t-ike-01.txt
+ *
+ * HASH = HASH(CKY-I | CKY-R | IP | Port)
+ *
+ * All values in network order
+ */
+ {
+ chunk_t icookie_chunk = { icookie, COOKIE_SIZE };
+ chunk_t rcookie_chunk = { rcookie, COOKIE_SIZE };
+ chunk_t port_chunk = chunk_from_thing(port);
+ chunk_t addr_chunk;
+ hash_algorithm_t hash_alg;
+ hasher_t *hasher;
+ size_t hash_size;
+
+ hash_alg = oakley_to_hash_algorithm(oakley_hasher->algo_id);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ hasher->get_hash(hasher, icookie_chunk, NULL);
+ hasher->get_hash(hasher, rcookie_chunk, NULL);
+ switch (addrtypeof(ip))
+ {
+ case AF_INET:
+ addr_chunk = chunk_from_thing(ip->u.v4.sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ addr_chunk = chunk_from_thing(ip->u.v6.sin6_addr.s6_addr);
+ break;
+ default:
+ addr_chunk = chunk_empty; /* should never occur */
+ }
+ hasher->get_hash(hasher, addr_chunk, NULL);
+ hasher->get_hash(hasher, port_chunk, hash);
+ hash_size = hasher->get_hash_size(hasher);
+ hasher->destroy(hasher);
+#ifdef NAT_D_DEBUG
+ DBG(DBG_NATT,
+ DBG_dump_chunk("_natd_hash: icookie=", icookie_chunk);
+ DBG_dump_chunk("_natd_hash: rcookie=", rcookie_chunk);
+ DBG_dump_chunk("_natd_hash: ip=", addr_chunk);
+ DBG_log("_natd_hash: port=%d", port);
+ DBG_dump("_natd_hash: hash=", hash, hash_size);
+ )
#endif
+ }
}
/* Add NAT-Traversal VIDs (supported ones)
@@ -161,180 +170,180 @@ static void _natd_hash(const struct hash_desc *hasher, char *hash,
*/
bool nat_traversal_add_vid(u_int8_t np, pb_stream *outs)
{
- bool r = TRUE;
-
- if (nat_traversal_support_port_floating)
- {
- u_int8_t last_np = nat_traversal_support_non_ike ?
- ISAKMP_NEXT_VID : np;
-
- if (r)
- r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC);
- if (r)
- r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03);
- if (r)
- r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_02);
- if (r)
- r = out_vendorid(last_np, outs, VID_NATT_IETF_02_N);
- }
- if (nat_traversal_support_non_ike)
- {
- if (r)
- r = out_vendorid(np, outs, VID_NATT_IETF_00);
- }
- return r;
+ bool r = TRUE;
+
+ if (nat_traversal_support_port_floating)
+ {
+ u_int8_t last_np = nat_traversal_support_non_ike ?
+ ISAKMP_NEXT_VID : np;
+
+ if (r)
+ r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_RFC);
+ if (r)
+ r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_03);
+ if (r)
+ r = out_vendorid(ISAKMP_NEXT_VID, outs, VID_NATT_IETF_02);
+ if (r)
+ r = out_vendorid(last_np, outs, VID_NATT_IETF_02_N);
+ }
+ if (nat_traversal_support_non_ike)
+ {
+ if (r)
+ r = out_vendorid(np, outs, VID_NATT_IETF_00);
+ }
+ return r;
}
u_int32_t nat_traversal_vid_to_method(unsigned short nat_t_vid)
{
- switch (nat_t_vid)
- {
- case VID_NATT_IETF_00:
- return LELEM(NAT_TRAVERSAL_IETF_00_01);
- case VID_NATT_IETF_02:
- case VID_NATT_IETF_02_N:
- case VID_NATT_IETF_03:
- return LELEM(NAT_TRAVERSAL_IETF_02_03);
- case VID_NATT_RFC:
- return LELEM(NAT_TRAVERSAL_RFC);
- }
- return 0;
+ switch (nat_t_vid)
+ {
+ case VID_NATT_IETF_00:
+ return LELEM(NAT_TRAVERSAL_IETF_00_01);
+ case VID_NATT_IETF_02:
+ case VID_NATT_IETF_02_N:
+ case VID_NATT_IETF_03:
+ return LELEM(NAT_TRAVERSAL_IETF_02_03);
+ case VID_NATT_RFC:
+ return LELEM(NAT_TRAVERSAL_RFC);
+ }
+ return 0;
}
void nat_traversal_natd_lookup(struct msg_digest *md)
{
- char hash[MAX_DIGEST_LEN];
- struct payload_digest *p;
- struct state *st = md->st;
- int i;
-
- if (!st || !md->iface || !st->st_oakley.hasher)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return;
- }
-
- /** Count NAT-D **/
- for (p = md->chain[ISAKMP_NEXT_NATD_RFC], i=0; p != NULL; p = p->next, i++);
-
- /*
- * We need at least 2 NAT-D (1 for us, many for peer)
- */
- if (i < 2)
- {
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negociation", i);
- st->nat_traversal = 0;
- return;
- }
-
- /*
- * First one with my IP & port
- */
- p = md->chain[ISAKMP_NEXT_NATD_RFC];
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
- &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
-
- if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
- memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0))
- {
+ char hash[MAX_DIGEST_LEN];
+ struct payload_digest *p;
+ struct state *st = md->st;
+ int i;
+
+ if (!st || !md->iface || !st->st_oakley.hasher)
+ {
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
+ , __FILE__, __LINE__);
+ return;
+ }
+
+ /** Count NAT-D **/
+ for (p = md->chain[ISAKMP_NEXT_NATD_RFC], i=0; p != NULL; p = p->next, i++);
+
+ /*
+ * We need at least 2 NAT-D (1 for us, many for peer)
+ */
+ if (i < 2)
+ {
+ loglog(RC_LOG_SERIOUS,
+ "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negociation", i);
+ st->nat_traversal = 0;
+ return;
+ }
+
+ /*
+ * First one with my IP & port
+ */
+ p = md->chain[ISAKMP_NEXT_NATD_RFC];
+ _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
+ &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
+
+ if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
+ memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)))
+ {
#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
- DBG_dump("expected NAT-D:", hash
- , st->st_oakley.hasher->hash_digest_len);
- DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
- )
+ DBG(DBG_NATT,
+ DBG_log("NAT_TRAVERSAL_NAT_BHND_ME");
+ DBG_dump("expected NAT-D:", hash
+ , st->st_oakley.hasher->hash_digest_len);
+ DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
+ )
#endif
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
- }
-
- /*
- * The others with sender IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
- &(md->sender), ntohs(md->sender_port));
- for (p = p->next, i=0 ; p != NULL; p = p->next)
- {
- if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
- memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0)
- {
- i++;
- }
- }
- if (!i)
- {
+ st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
+ }
+
+ /*
+ * The others with sender IP & port
+ */
+ _natd_hash(st->st_oakley.hasher, hash, st->st_icookie, st->st_rcookie,
+ &(md->sender), ntohs(md->sender_port));
+ for (p = p->next, i=0 ; p != NULL; p = p->next)
+ {
+ if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
+ memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len))
+ {
+ i++;
+ }
+ }
+ if (!i)
+ {
#ifdef NAT_D_DEBUG
- DBG(DBG_NATT,
- DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
- DBG_dump("expected NAT-D:", hash
- , st->st_oakley.hasher->hash_digest_len);
- p = md->chain[ISAKMP_NEXT_NATD_RFC];
- for (p = p->next, i=0 ; p != NULL; p = p->next)
- {
- DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
- }
- )
+ DBG(DBG_NATT,
+ DBG_log("NAT_TRAVERSAL_NAT_BHND_PEER");
+ DBG_dump("expected NAT-D:", hash
+ , st->st_oakley.hasher->hash_digest_len);
+ p = md->chain[ISAKMP_NEXT_NATD_RFC];
+ for (p = p->next, i=0 ; p != NULL; p = p->next)
+ {
+ DBG_dump("received NAT-D:", p->pbs.cur, pbs_left(&p->pbs));
+ }
+ )
#endif
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
- }
+ st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
+ }
#ifdef FORCE_NAT_TRAVERSAL
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
- st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
+ st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_PEER);
+ st->nat_traversal |= LELEM(NAT_TRAVERSAL_NAT_BHND_ME);
#endif
}
bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
- struct msg_digest *md)
+ struct msg_digest *md)
{
- char hash[MAX_DIGEST_LEN];
- struct state *st = md->st;
-
- if (!st || !st->st_oakley.hasher)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return FALSE;
- }
-
- DBG(DBG_EMITTING,
- DBG_log("sending NATD payloads")
- )
-
- /*
- * First one with sender IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
- is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
- &(md->sender),
+ char hash[MAX_DIGEST_LEN];
+ struct state *st = md->st;
+
+ if (!st || !st->st_oakley.hasher)
+ {
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
+ , __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ DBG(DBG_EMITTING,
+ DBG_log("sending NATD payloads")
+ )
+
+ /*
+ * First one with sender IP & port
+ */
+ _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
+ is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
+ &(md->sender),
#ifdef FORCE_NAT_TRAVERSAL
- 0
+ 0
#else
- ntohs(md->sender_port)
+ ntohs(md->sender_port)
#endif
- );
- if (!out_generic_raw((st->nat_traversal & NAT_T_WITH_RFC_VALUES
- ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS), &isakmp_nat_d, outs,
- hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"))
- {
- return FALSE;
- }
-
- /*
- * Second one with my IP & port
- */
- _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
- is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
- &(md->iface->addr),
+ );
+ if (!out_generic_raw((st->nat_traversal & NAT_T_WITH_RFC_VALUES
+ ? ISAKMP_NEXT_NATD_RFC : ISAKMP_NEXT_NATD_DRAFTS), &isakmp_nat_d, outs,
+ hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Second one with my IP & port
+ */
+ _natd_hash(st->st_oakley.hasher, hash, st->st_icookie,
+ is_zero_cookie(st->st_rcookie) ? md->hdr.isa_rcookie : st->st_rcookie,
+ &(md->iface->addr),
#ifdef FORCE_NAT_TRAVERSAL
- 0
+ 0
#else
- ntohs(st->st_connection->spd.this.host_port)
+ ntohs(st->st_connection->spd.this.host_port)
#endif
- );
- return (out_generic_raw(np, &isakmp_nat_d, outs,
- hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"));
+ );
+ return (out_generic_raw(np, &isakmp_nat_d, outs,
+ hash, st->st_oakley.hasher->hash_digest_len, "NAT-D"));
}
/*
@@ -344,245 +353,245 @@ bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
*/
void nat_traversal_natoa_lookup(struct msg_digest *md)
{
- struct payload_digest *p;
- struct state *st = md->st;
- int i;
- ip_address ip;
-
- if (!st || !md->iface)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return;
- }
-
- /* Initialize NAT-OA */
- anyaddr(AF_INET, &st->nat_oa);
-
- /* Count NAT-OA **/
- for (p = md->chain[ISAKMP_NEXT_NATOA_RFC], i=0; p != NULL; p = p->next, i++);
-
- DBG(DBG_NATT,
- DBG_log("NAT-Traversal: received %d NAT-OA.", i)
- )
-
- if (i == 0)
- return;
-
- if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER)))
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
- "ignored because peer is not NATed", i);
- return;
- }
-
- if (i > 1)
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
- "using first, ignoring others", i);
- }
-
- /* Take first */
- p = md->chain[ISAKMP_NEXT_NATOA_RFC];
-
- DBG(DBG_PARSING,
- DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
- );
-
- switch (p->payload.nat_oa.isanoa_idtype)
- {
- case ID_IPV4_ADDR:
- if (pbs_left(&p->pbs) == sizeof(struct in_addr))
- {
- initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET, &ip);
- }
- else
+ struct payload_digest *p;
+ struct state *st = md->st;
+ int i;
+ ip_address ip;
+
+ if (!st || !md->iface)
{
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv4 NAT-OA "
- "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
- return;
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
+ , __FILE__, __LINE__);
+ return;
}
- break;
- case ID_IPV6_ADDR:
- if (pbs_left(&p->pbs) == sizeof(struct in6_addr))
+
+ /* Initialize NAT-OA */
+ anyaddr(AF_INET, &st->nat_oa);
+
+ /* Count NAT-OA **/
+ for (p = md->chain[ISAKMP_NEXT_NATOA_RFC], i=0; p != NULL; p = p->next, i++);
+
+ DBG(DBG_NATT,
+ DBG_log("NAT-Traversal: received %d NAT-OA.", i)
+ )
+
+ if (i == 0)
+ return;
+
+ if (!(st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER)))
{
- initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET6, &ip);
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
+ "ignored because peer is not NATed", i);
+ return;
}
- else
+
+ if (i > 1)
{
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv6 NAT-OA "
- "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
- return;
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %d NAT-OA. "
+ "using first, ignoring others", i);
}
- break;
- default:
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "invalid ID Type (%d) in NAT-OA - ignored",
- p->payload.nat_oa.isanoa_idtype);
- return;
- }
- DBG(DBG_NATT,
+ /* Take first */
+ p = md->chain[ISAKMP_NEXT_NATOA_RFC];
+
+ DBG(DBG_PARSING,
+ DBG_dump("NAT-OA:", p->pbs.start, pbs_room(&p->pbs));
+ );
+
+ switch (p->payload.nat_oa.isanoa_idtype)
{
- char ip_t[ADDRTOT_BUF];
- addrtot(&ip, 0, ip_t, sizeof(ip_t));
-
- DBG_log("received NAT-OA: %s", ip_t);
+ case ID_IPV4_ADDR:
+ if (pbs_left(&p->pbs) == sizeof(struct in_addr))
+ {
+ initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET, &ip);
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv4 NAT-OA "
+ "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
+ return;
+ }
+ break;
+ case ID_IPV6_ADDR:
+ if (pbs_left(&p->pbs) == sizeof(struct in6_addr))
+ {
+ initaddr(p->pbs.cur, pbs_left(&p->pbs), AF_INET6, &ip);
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: received IPv6 NAT-OA "
+ "with invalid IP size (%d)", (int)pbs_left(&p->pbs));
+ return;
+ }
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
+ "invalid ID Type (%d) in NAT-OA - ignored",
+ p->payload.nat_oa.isanoa_idtype);
+ return;
}
- )
- if (isanyaddr(&ip))
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %%any NAT-OA...");
- else
- st->nat_oa = ip;
+ DBG(DBG_NATT,
+ {
+ char ip_t[ADDRTOT_BUF];
+ addrtot(&ip, 0, ip_t, sizeof(ip_t));
+
+ DBG_log("received NAT-OA: %s", ip_t);
+ }
+ )
+
+ if (isanyaddr(&ip))
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: received %%any NAT-OA...");
+ else
+ st->nat_oa = ip;
}
bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
- struct state *st)
+ struct state *st)
{
- struct isakmp_nat_oa natoa;
- pb_stream pbs;
- unsigned char ip_val[sizeof(struct in6_addr)];
- size_t ip_len = 0;
- ip_address *ip;
-
- if ((!st) || (!st->st_connection))
- {
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
- , __FILE__, __LINE__);
- return FALSE;
- }
- ip = &(st->st_connection->spd.this.host_addr);
-
- memset(&natoa, 0, sizeof(natoa));
- natoa.isanoa_np = np;
-
- switch (addrtypeof(ip))
- {
- case AF_INET:
- ip_len = sizeof(ip->u.v4.sin_addr.s_addr);
- memcpy(ip_val, &ip->u.v4.sin_addr.s_addr, ip_len);
- natoa.isanoa_idtype = ID_IPV4_ADDR;
- break;
- case AF_INET6:
- ip_len = sizeof(ip->u.v6.sin6_addr.s6_addr);
- memcpy(ip_val, &ip->u.v6.sin6_addr.s6_addr, ip_len);
- natoa.isanoa_idtype = ID_IPV6_ADDR;
- break;
- default:
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "invalid addrtypeof()=%d", addrtypeof(ip));
- return FALSE;
- }
-
- if (!out_struct(&natoa, &isakmp_nat_oa, outs, &pbs))
- return FALSE;
-
- if (!out_raw(ip_val, ip_len, &pbs, "NAT-OA"))
- return FALSE;
-
- DBG(DBG_NATT,
- DBG_dump("NAT-OA (S):", ip_val, ip_len)
- )
-
- close_output_pbs(&pbs);
- return TRUE;
+ struct isakmp_nat_oa natoa;
+ pb_stream pbs;
+ unsigned char ip_val[sizeof(struct in6_addr)];
+ size_t ip_len = 0;
+ ip_address *ip;
+
+ if ((!st) || (!st->st_connection))
+ {
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: assert failed %s:%d"
+ , __FILE__, __LINE__);
+ return FALSE;
+ }
+ ip = &(st->st_connection->spd.this.host_addr);
+
+ memset(&natoa, 0, sizeof(natoa));
+ natoa.isanoa_np = np;
+
+ switch (addrtypeof(ip))
+ {
+ case AF_INET:
+ ip_len = sizeof(ip->u.v4.sin_addr.s_addr);
+ memcpy(ip_val, &ip->u.v4.sin_addr.s_addr, ip_len);
+ natoa.isanoa_idtype = ID_IPV4_ADDR;
+ break;
+ case AF_INET6:
+ ip_len = sizeof(ip->u.v6.sin6_addr.s6_addr);
+ memcpy(ip_val, &ip->u.v6.sin6_addr.s6_addr, ip_len);
+ natoa.isanoa_idtype = ID_IPV6_ADDR;
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
+ "invalid addrtypeof()=%d", addrtypeof(ip));
+ return FALSE;
+ }
+
+ if (!out_struct(&natoa, &isakmp_nat_oa, outs, &pbs))
+ return FALSE;
+
+ if (!out_raw(ip_val, ip_len, &pbs, "NAT-OA"))
+ return FALSE;
+
+ DBG(DBG_NATT,
+ DBG_dump("NAT-OA (S):", ip_val, ip_len)
+ )
+
+ close_output_pbs(&pbs);
+ return TRUE;
}
void nat_traversal_show_result (u_int32_t nt, u_int16_t sport)
{
- const char *mth = NULL, *rslt = NULL;
-
- switch (nt & NAT_TRAVERSAL_METHOD)
- {
- case LELEM(NAT_TRAVERSAL_IETF_00_01):
- mth = natt_type_bitnames[0];
- break;
- case LELEM(NAT_TRAVERSAL_IETF_02_03):
- mth = natt_type_bitnames[1];
- break;
- case LELEM(NAT_TRAVERSAL_RFC):
- mth = natt_type_bitnames[2];
- break;
- }
-
- switch (nt & NAT_T_DETECTED)
- {
- case 0:
- rslt = "no NAT detected";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_ME):
- rslt = "i am NATed";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
- rslt = "peer is NATed";
- break;
- case LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
- rslt = "both are NATed";
- break;
- }
-
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: Result using %s: %s",
- mth ? mth : "unknown method",
- rslt ? rslt : "unknown result"
- );
-
- if ((nt & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))
- && (sport == IKE_UDP_PORT)
- && ((nt & NAT_T_WITH_PORT_FLOATING)==0))
- {
+ const char *mth = NULL, *rslt = NULL;
+
+ switch (nt & NAT_TRAVERSAL_METHOD)
+ {
+ case LELEM(NAT_TRAVERSAL_IETF_00_01):
+ mth = natt_type_bitnames[0];
+ break;
+ case LELEM(NAT_TRAVERSAL_IETF_02_03):
+ mth = natt_type_bitnames[1];
+ break;
+ case LELEM(NAT_TRAVERSAL_RFC):
+ mth = natt_type_bitnames[2];
+ break;
+ }
+
+ switch (nt & NAT_T_DETECTED)
+ {
+ case 0:
+ rslt = "no NAT detected";
+ break;
+ case LELEM(NAT_TRAVERSAL_NAT_BHND_ME):
+ rslt = "i am NATed";
+ break;
+ case LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
+ rslt = "peer is NATed";
+ break;
+ case LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER):
+ rslt = "both are NATed";
+ break;
+ }
+
loglog(RC_LOG_SERIOUS,
- "Warning: peer is NATed but source port is still udp/%d. "
- "Ipsec-passthrough NAT device suspected -- NAT-T may not work.",
- IKE_UDP_PORT
+ "NAT-Traversal: Result using %s: %s",
+ mth ? mth : "unknown method",
+ rslt ? rslt : "unknown result"
);
- }
+
+ if ((nt & LELEM(NAT_TRAVERSAL_NAT_BHND_PEER))
+ && (sport == IKE_UDP_PORT)
+ && ((nt & NAT_T_WITH_PORT_FLOATING)==0))
+ {
+ loglog(RC_LOG_SERIOUS,
+ "Warning: peer is NATed but source port is still udp/%d. "
+ "Ipsec-passthrough NAT device suspected -- NAT-T may not work.",
+ IKE_UDP_PORT
+ );
+ }
}
int nat_traversal_espinudp_socket (int sk, u_int32_t type)
{
- int r = setsockopt(sk, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
+ int r = setsockopt(sk, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type));
- if (r < 0 && errno == ENOPROTOOPT)
- {
- loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: ESPINUDP(%d) not supported by kernel -- "
- "NAT-T disabled", type);
- disable_nat_traversal(type);
- }
- return r;
+ if (r < 0 && errno == ENOPROTOOPT)
+ {
+ loglog(RC_LOG_SERIOUS,
+ "NAT-Traversal: ESPINUDP(%d) not supported by kernel -- "
+ "NAT-T disabled", type);
+ disable_nat_traversal(type);
+ }
+ return r;
}
void nat_traversal_new_ka_event (void)
{
- if (_ka_evt)
- return; /* event already scheduled */
+ if (_ka_evt)
+ return; /* event already scheduled */
- event_schedule(EVENT_NAT_T_KEEPALIVE, _kap, NULL);
- _ka_evt = 1;
+ event_schedule(EVENT_NAT_T_KEEPALIVE, _kap, NULL);
+ _ka_evt = 1;
}
static void nat_traversal_send_ka (struct state *st)
{
- static unsigned char ka_payload = 0xff;
- chunk_t sav;
+ static unsigned char ka_payload = 0xff;
+ chunk_t sav;
- DBG(DBG_NATT,
- DBG_log("ka_event: send NAT-KA to %s:%d",
- ip_str(&st->st_connection->spd.that.host_addr),
- st->st_connection->spd.that.host_port);
- )
+ DBG(DBG_NATT,
+ DBG_log("ka_event: send NAT-KA to %s:%d",
+ ip_str(&st->st_connection->spd.that.host_addr),
+ st->st_connection->spd.that.host_port);
+ )
- /* save state chunk */
- setchunk(sav, st->st_tpacket.ptr, st->st_tpacket.len);
+ /* save state chunk */
+ sav = st->st_tpacket;
- /* send keep alive */
- setchunk(st->st_tpacket, &ka_payload, 1);
- send_packet(st, "NAT-T Keep Alive");
+ /* send keep alive */
+ st->st_tpacket = chunk_create(&ka_payload, 1);
+ send_packet(st, "NAT-T Keep Alive");
- /* restore state chunk */
- setchunk(st->st_tpacket, sav.ptr, sav.len);
+ /* restore state chunk */
+ st->st_tpacket = sav;
}
/**
@@ -590,277 +599,277 @@ static void nat_traversal_send_ka (struct state *st)
*/
static void nat_traversal_ka_event_state (struct state *st, void *data)
{
- unsigned int *_kap_st = (unsigned int *)data;
- const struct connection *c = st->st_connection;
-
- if (!c)
- return;
+ unsigned int *_kap_st = (unsigned int *)data;
+ const struct connection *c = st->st_connection;
- if ((st->st_state == STATE_MAIN_R3 || st->st_state == STATE_MAIN_I4)
- && (st->nat_traversal & NAT_T_DETECTED)
- && ((st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
- {
- /*
- * - ISAKMP established
- * - NAT-Traversal detected
- * - NAT-KeepAlive needed (we are NATed)
- */
- if (c->newest_isakmp_sa != st->st_serialno)
- {
- /*
- * if newest is also valid, ignore this one, we will only use
- * newest.
- */
- struct state *st_newest;
-
- st_newest = state_with_serialno(c->newest_isakmp_sa);
- if (st_newest
- && (st_newest->st_state == STATE_MAIN_R3 || st_newest->st_state == STATE_MAIN_I4)
- && (st_newest->nat_traversal & NAT_T_DETECTED)
- && ((st_newest->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
- {
+ if (!c)
return;
- }
+
+ if ((st->st_state == STATE_MAIN_R3 || st->st_state == STATE_MAIN_I4)
+ && (st->nat_traversal & NAT_T_DETECTED)
+ && ((st->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
+ {
+ /*
+ * - ISAKMP established
+ * - NAT-Traversal detected
+ * - NAT-KeepAlive needed (we are NATed)
+ */
+ if (c->newest_isakmp_sa != st->st_serialno)
+ {
+ /*
+ * if newest is also valid, ignore this one, we will only use
+ * newest.
+ */
+ struct state *st_newest;
+
+ st_newest = state_with_serialno(c->newest_isakmp_sa);
+ if (st_newest
+ && (st_newest->st_state == STATE_MAIN_R3 || st_newest->st_state == STATE_MAIN_I4)
+ && (st_newest->nat_traversal & NAT_T_DETECTED)
+ && ((st_newest->nat_traversal & LELEM(NAT_TRAVERSAL_NAT_BHND_ME)) || _force_ka))
+ {
+ return;
+ }
+ }
+ set_cur_state(st);
+ nat_traversal_send_ka(st);
+ reset_cur_state();
+ (*_kap_st)++;
}
- set_cur_state(st);
- nat_traversal_send_ka(st);
- reset_cur_state();
- (*_kap_st)++;
- }
}
void nat_traversal_ka_event (void)
{
- unsigned int _kap_st = 0;
+ unsigned int _kap_st = 0;
- _ka_evt = 0; /* ready to be reschedule */
+ _ka_evt = 0; /* ready to be reschedule */
- for_each_state((void *)nat_traversal_ka_event_state, &_kap_st);
+ for_each_state((void *)nat_traversal_ka_event_state, &_kap_st);
- /* if there are still states who needs Keep-Alive, schedule new event */
- if (_kap_st)
- nat_traversal_new_ka_event();
+ /* if there are still states who needs Keep-Alive, schedule new event */
+ if (_kap_st)
+ nat_traversal_new_ka_event();
}
struct _new_mapp_nfo {
- ip_address addr;
- u_int16_t sport, dport;
+ ip_address addr;
+ u_int16_t sport, dport;
};
static void nat_traversal_find_new_mapp_state (struct state *st, void *data)
{
- struct connection *c = st->st_connection;
- struct _new_mapp_nfo *nfo = (struct _new_mapp_nfo *)data;
-
- if (c != NULL
- && sameaddr(&c->spd.that.host_addr, &(nfo->addr))
- && c->spd.that.host_port == nfo->sport)
- {
+ struct connection *c = st->st_connection;
+ struct _new_mapp_nfo *nfo = (struct _new_mapp_nfo *)data;
- /* change host port */
- c->spd.that.host_port = nfo->dport;
-
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- || IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
+ if (c != NULL
+ && sameaddr(&c->spd.that.host_addr, &(nfo->addr))
+ && c->spd.that.host_port == nfo->sport)
{
- if (!update_ipsec_sa(st))
- {
- /*
- * If ipsec update failed, restore old port or we'll
- * not be able to update anymore.
- */
- c->spd.that.host_port = nfo->sport;
- }
+
+ /* change host port */
+ c->spd.that.host_port = nfo->dport;
+
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
+ || IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
+ {
+ if (!update_ipsec_sa(st))
+ {
+ /*
+ * If ipsec update failed, restore old port or we'll
+ * not be able to update anymore.
+ */
+ c->spd.that.host_port = nfo->sport;
+ }
+ }
}
- }
}
static int nat_traversal_new_mapping(const ip_address *src, u_int16_t sport,
- const ip_address *dst, u_int16_t dport)
+ const ip_address *dst, u_int16_t dport)
{
- char srca[ADDRTOT_BUF], dsta[ADDRTOT_BUF];
- struct _new_mapp_nfo nfo;
-
- addrtot(src, 0, srca, ADDRTOT_BUF);
- addrtot(dst, 0, dsta, ADDRTOT_BUF);
-
- if (!sameaddr(src, dst))
- {
- loglog(RC_LOG_SERIOUS, "nat_traversal_new_mapping: "
- "address change currently not supported [%s:%d,%s:%d]",
- srca, sport, dsta, dport);
- return -1;
- }
-
- if (sport == dport)
- {
- /* no change */
- return 0;
- }
+ char srca[ADDRTOT_BUF], dsta[ADDRTOT_BUF];
+ struct _new_mapp_nfo nfo;
- DBG_log("NAT-T: new mapping %s:%d/%d)", srca, sport, dport);
+ addrtot(src, 0, srca, ADDRTOT_BUF);
+ addrtot(dst, 0, dsta, ADDRTOT_BUF);
- nfo.addr = *src;
- nfo.sport = sport;
- nfo.dport = dport;
+ if (!sameaddr(src, dst))
+ {
+ loglog(RC_LOG_SERIOUS, "nat_traversal_new_mapping: "
+ "address change currently not supported [%s:%d,%s:%d]",
+ srca, sport, dsta, dport);
+ return -1;
+ }
+
+ if (sport == dport)
+ {
+ /* no change */
+ return 0;
+ }
- for_each_state((void *)nat_traversal_find_new_mapp_state, &nfo);
+ DBG_log("NAT-T: new mapping %s:%d/%d)", srca, sport, dport);
- return 0;
+ nfo.addr = *src;
+ nfo.sport = sport;
+ nfo.dport = dport;
+
+ for_each_state((void *)nat_traversal_find_new_mapp_state, &nfo);
+
+ return 0;
}
void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st)
{
- struct connection *c = st ? st->st_connection : NULL;
- struct iface *i = NULL;
+ struct connection *c = st ? st->st_connection : NULL;
+ struct iface *i = NULL;
- if ((st == NULL) || (c == NULL))
- return;
+ if ((st == NULL) || (c == NULL))
+ return;
- if (md)
- {
- /*
- * If source port has changed, update (including other states and
- * established kernel SA)
- */
- if (c->spd.that.host_port != md->sender_port)
+ if (md)
{
- nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
- &c->spd.that.host_addr, md->sender_port);
+ /*
+ * If source port has changed, update (including other states and
+ * established kernel SA)
+ */
+ if (c->spd.that.host_port != md->sender_port)
+ {
+ nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
+ &c->spd.that.host_addr, md->sender_port);
+ }
+
+ /*
+ * If interface type has changed, update local port (500/4500)
+ */
+ if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !md->iface->ike_float)
+ || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && md->iface->ike_float))
+ {
+ c->spd.this.host_port = (md->iface->ike_float)
+ ? NAT_T_IKE_FLOAT_PORT : pluto_port;
+
+ DBG(DBG_NATT,
+ DBG_log("NAT-T: updating local port to %d", c->spd.this.host_port);
+ );
+ }
}
/*
- * If interface type has changed, update local port (500/4500)
- */
- if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !md->iface->ike_float)
- || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && md->iface->ike_float))
- {
- c->spd.this.host_port = (md->iface->ike_float)
- ? NAT_T_IKE_FLOAT_PORT : pluto_port;
-
- DBG(DBG_NATT,
- DBG_log("NAT-T: updating local port to %d", c->spd.this.host_port);
- );
- }
- }
-
- /*
- * If we're initiator and NAT-T (with port floating) is detected, we
- * need to change port (MAIN_I3 or QUICK_I1)
- */
- if ((st->st_state == STATE_MAIN_I3 || st->st_state == STATE_QUICK_I1)
- && (st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
- && (st->nat_traversal & NAT_T_DETECTED)
- && (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT))
- {
- DBG(DBG_NATT,
- DBG_log("NAT-T: floating to port %d", NAT_T_IKE_FLOAT_PORT);
- )
- c->spd.this.host_port = NAT_T_IKE_FLOAT_PORT;
- c->spd.that.host_port = NAT_T_IKE_FLOAT_PORT;
- /*
- * Also update pending connections or they will be deleted if uniqueids
- * option is set.
+ * If we're initiator and NAT-T (with port floating) is detected, we
+ * need to change port (MAIN_I3 or QUICK_I1)
*/
- update_pending(st, st);
- }
-
- /*
- * Find valid interface according to local port (500/4500)
- */
- if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !c->interface->ike_float)
- || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && c->interface->ike_float))
- {
- for (i = interfaces; i != NULL; i = i->next)
- {
- if (sameaddr(&c->interface->addr, &i->addr)
- && i->ike_float != c->interface->ike_float)
- {
+ if ((st->st_state == STATE_MAIN_I3 || st->st_state == STATE_QUICK_I1)
+ && (st->nat_traversal & NAT_T_WITH_PORT_FLOATING)
+ && (st->nat_traversal & NAT_T_DETECTED)
+ && (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT))
+ {
DBG(DBG_NATT,
- DBG_log("NAT-T: using interface %s:%d", i->rname,
- i->ike_float ? NAT_T_IKE_FLOAT_PORT : pluto_port);
+ DBG_log("NAT-T: floating to port %d", NAT_T_IKE_FLOAT_PORT);
)
- c->interface = i;
- break;
- }
+ c->spd.this.host_port = NAT_T_IKE_FLOAT_PORT;
+ c->spd.that.host_port = NAT_T_IKE_FLOAT_PORT;
+ /*
+ * Also update pending connections or they will be deleted if uniqueids
+ * option is set.
+ */
+ update_pending(st, st);
+ }
+
+ /*
+ * Find valid interface according to local port (500/4500)
+ */
+ if ((c->spd.this.host_port == NAT_T_IKE_FLOAT_PORT && !c->interface->ike_float)
+ || (c->spd.this.host_port != NAT_T_IKE_FLOAT_PORT && c->interface->ike_float))
+ {
+ for (i = interfaces; i != NULL; i = i->next)
+ {
+ if (sameaddr(&c->interface->addr, &i->addr)
+ && i->ike_float != c->interface->ike_float)
+ {
+ DBG(DBG_NATT,
+ DBG_log("NAT-T: using interface %s:%d", i->rname,
+ i->ike_float ? NAT_T_IKE_FLOAT_PORT : pluto_port);
+ )
+ c->interface = i;
+ break;
+ }
+ }
}
- }
}
struct _new_klips_mapp_nfo {
- struct sadb_sa *sa;
- ip_address src, dst;
- u_int16_t sport, dport;
+ struct sadb_sa *sa;
+ ip_address src, dst;
+ u_int16_t sport, dport;
};
static void nat_t_new_klips_mapp (struct state *st, void *data)
{
- struct connection *c = st->st_connection;
- struct _new_klips_mapp_nfo *nfo = (struct _new_klips_mapp_nfo *)data;
-
- if (c != NULL && st->st_esp.present
- && sameaddr(&c->spd.that.host_addr, &(nfo->src))
- && st->st_esp.our_spi == nfo->sa->sadb_sa_spi)
- {
- nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
- &(nfo->dst), nfo->dport);
- }
+ struct connection *c = st->st_connection;
+ struct _new_klips_mapp_nfo *nfo = (struct _new_klips_mapp_nfo *)data;
+
+ if (c != NULL && st->st_esp.present
+ && sameaddr(&c->spd.that.host_addr, &(nfo->src))
+ && st->st_esp.our_spi == nfo->sa->sadb_sa_spi)
+ {
+ nat_traversal_new_mapping(&c->spd.that.host_addr, c->spd.that.host_port,
+ &(nfo->dst), nfo->dport);
+ }
}
void process_pfkey_nat_t_new_mapping(
- struct sadb_msg *msg __attribute__ ((unused)),
- struct sadb_ext *extensions[SADB_EXT_MAX + 1])
+ struct sadb_msg *msg __attribute__ ((unused)),
+ struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
- struct _new_klips_mapp_nfo nfo;
- struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
- struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
- struct sockaddr *srca, *dsta;
- err_t ugh = NULL;
-
- nfo.sa = (void *) extensions[SADB_EXT_SA];
-
- if (!nfo.sa || !srcx || !dstx)
- {
- plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: "
- "got NULL params");
- return;
- }
-
- srca = ((struct sockaddr *)(void *)&srcx[1]);
- dsta = ((struct sockaddr *)(void *)&dstx[1]);
-
- if (srca->sa_family != AF_INET || dsta->sa_family != AF_INET)
- {
- ugh = "only AF_INET supported";
- }
- else
- {
- char text_said[SATOT_BUF];
- char _srca[ADDRTOT_BUF], _dsta[ADDRTOT_BUF];
- ip_said said;
-
- initaddr((const void *) &((const struct sockaddr_in *)srca)->sin_addr,
- sizeof(((const struct sockaddr_in *)srca)->sin_addr),
- srca->sa_family, &(nfo.src));
- nfo.sport = ntohs(((const struct sockaddr_in *)srca)->sin_port);
- initaddr((const void *) &((const struct sockaddr_in *)dsta)->sin_addr,
- sizeof(((const struct sockaddr_in *)dsta)->sin_addr),
- dsta->sa_family, &(nfo.dst));
- nfo.dport = ntohs(((const struct sockaddr_in *)dsta)->sin_port);
+ struct _new_klips_mapp_nfo nfo;
+ struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
+ struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
+ struct sockaddr *srca, *dsta;
+ err_t ugh = NULL;
- DBG(DBG_NATT,
- initsaid(&nfo.src, nfo.sa->sadb_sa_spi, SA_ESP, &said);
- satot(&said, 0, text_said, SATOT_BUF);
- addrtot(&nfo.src, 0, _srca, ADDRTOT_BUF);
- addrtot(&nfo.dst, 0, _dsta, ADDRTOT_BUF);
- DBG_log("new klips mapping %s %s:%d %s:%d",
- text_said, _srca, nfo.sport, _dsta, nfo.dport);
- )
+ nfo.sa = (void *) extensions[SADB_EXT_SA];
- for_each_state((void *)nat_t_new_klips_mapp, &nfo);
- }
+ if (!nfo.sa || !srcx || !dstx)
+ {
+ plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: "
+ "got NULL params");
+ return;
+ }
+
+ srca = ((struct sockaddr *)(void *)&srcx[1]);
+ dsta = ((struct sockaddr *)(void *)&dstx[1]);
+
+ if (srca->sa_family != AF_INET || dsta->sa_family != AF_INET)
+ {
+ ugh = "only AF_INET supported";
+ }
+ else
+ {
+ char text_said[SATOT_BUF];
+ char _srca[ADDRTOT_BUF], _dsta[ADDRTOT_BUF];
+ ip_said said;
+
+ initaddr((const void *) &((const struct sockaddr_in *)srca)->sin_addr,
+ sizeof(((const struct sockaddr_in *)srca)->sin_addr),
+ srca->sa_family, &(nfo.src));
+ nfo.sport = ntohs(((const struct sockaddr_in *)srca)->sin_port);
+ initaddr((const void *) &((const struct sockaddr_in *)dsta)->sin_addr,
+ sizeof(((const struct sockaddr_in *)dsta)->sin_addr),
+ dsta->sa_family, &(nfo.dst));
+ nfo.dport = ntohs(((const struct sockaddr_in *)dsta)->sin_port);
+
+ DBG(DBG_NATT,
+ initsaid(&nfo.src, nfo.sa->sadb_sa_spi, SA_ESP, &said);
+ satot(&said, 0, text_said, SATOT_BUF);
+ addrtot(&nfo.src, 0, _srca, ADDRTOT_BUF);
+ addrtot(&nfo.dst, 0, _dsta, ADDRTOT_BUF);
+ DBG_log("new klips mapping %s %s:%d %s:%d",
+ text_said, _srca, nfo.sport, _dsta, nfo.dport);
+ )
+
+ for_each_state((void *)nat_t_new_klips_mapp, &nfo);
+ }
- if (ugh != NULL)
- plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: %s", ugh);
+ if (ugh != NULL)
+ plog("SADB_X_NAT_T_NEW_MAPPING message from KLIPS malformed: %s", ugh);
}
diff --git a/src/pluto/nat_traversal.h b/src/pluto/nat_traversal.h
index 9041d84de..98b0a2bc0 100644
--- a/src/pluto/nat_traversal.h
+++ b/src/pluto/nat_traversal.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: nat_traversal.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _NAT_TRAVERSAL_H
@@ -32,37 +30,37 @@
* NAT-Traversal methods which need NAT-D
*/
#define NAT_T_WITH_NATD \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
+ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
+ LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which need NAT-OA
*/
#define NAT_T_WITH_NATOA \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
+ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
+ LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which use NAT-KeepAlive
*/
#define NAT_T_WITH_KA \
- ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
- LELEM(NAT_TRAVERSAL_RFC) )
+ ( LELEM(NAT_TRAVERSAL_IETF_00_01) | LELEM(NAT_TRAVERSAL_IETF_02_03) | \
+ LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which use floating port
*/
#define NAT_T_WITH_PORT_FLOATING \
- ( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
+ ( LELEM(NAT_TRAVERSAL_IETF_02_03) | LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal methods which use officials values (RFC)
*/
#define NAT_T_WITH_RFC_VALUES \
- ( LELEM(NAT_TRAVERSAL_RFC) )
+ ( LELEM(NAT_TRAVERSAL_RFC) )
/**
* NAT-Traversal detected
*/
#define NAT_T_DETECTED \
- ( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) )
+ ( LELEM(NAT_TRAVERSAL_NAT_BHND_ME) | LELEM(NAT_TRAVERSAL_NAT_BHND_PEER) )
/**
* NAT-T Port Floating
@@ -70,7 +68,7 @@
#define NAT_T_IKE_FLOAT_PORT 4500
void init_nat_traversal (bool activate, unsigned int keep_alive_period,
- bool fka, bool spf);
+ bool fka, bool spf);
extern bool nat_traversal_enabled;
extern bool nat_traversal_support_non_ike;
@@ -82,7 +80,7 @@ extern bool nat_traversal_support_port_floating;
void nat_traversal_natd_lookup(struct msg_digest *md);
#ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
- struct msg_digest *md);
+ struct msg_digest *md);
#endif
/**
@@ -91,7 +89,7 @@ bool nat_traversal_add_natd(u_int8_t np, pb_stream *outs,
void nat_traversal_natoa_lookup(struct msg_digest *md);
#ifndef PB_STREAM_UNDEFINED
bool nat_traversal_add_natoa(u_int8_t np, pb_stream *outs,
- struct state *st);
+ struct state *st);
#endif
/**
@@ -119,8 +117,8 @@ void nat_traversal_change_port_lookup(struct msg_digest *md, struct state *st);
*/
#ifdef __PFKEY_V2_H
void process_pfkey_nat_t_new_mapping(
- struct sadb_msg *,
- struct sadb_ext *[SADB_EXT_MAX + 1]);
+ struct sadb_msg *,
+ struct sadb_ext *[SADB_EXT_MAX + 1]);
#endif
/**
@@ -133,22 +131,22 @@ nat_traversal_port_float(struct state *st, struct msg_digest *md, bool in);
* Encapsulation mode macro (see demux.c)
*/
#define NAT_T_ENCAPSULATION_MODE(st,nat_t_policy) ( \
- ((st)->nat_traversal & NAT_T_DETECTED) \
- ? ( ((nat_t_policy) & POLICY_TUNNEL) \
- ? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
- ? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
- : (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
- ) \
- : ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
- ? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
- : (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
- ) \
- ) \
- : ( ((st)->st_policy & POLICY_TUNNEL) \
- ? (ENCAPSULATION_MODE_TUNNEL) \
- : (ENCAPSULATION_MODE_TRANSPORT) \
- ) \
- )
+ ((st)->nat_traversal & NAT_T_DETECTED) \
+ ? ( ((nat_t_policy) & POLICY_TUNNEL) \
+ ? ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
+ ? (ENCAPSULATION_MODE_UDP_TUNNEL_RFC) \
+ : (ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS) \
+ ) \
+ : ( ((st)->nat_traversal & NAT_T_WITH_RFC_VALUES) \
+ ? (ENCAPSULATION_MODE_UDP_TRANSPORT_RFC) \
+ : (ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS) \
+ ) \
+ ) \
+ : ( ((st)->st_policy & POLICY_TUNNEL) \
+ ? (ENCAPSULATION_MODE_TUNNEL) \
+ : (ENCAPSULATION_MODE_TRANSPORT) \
+ ) \
+ )
#endif /* _NAT_TRAVERSAL_H */
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
index 74b86bf19..80164fa1d 100644
--- a/src/pluto/ocsp.c
+++ b/src/pluto/ocsp.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ocsp.c 4827 2009-01-09 01:36:13Z andreas $
*/
#include <unistd.h>
@@ -24,7 +22,13 @@
#include <fcntl.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <library.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+#include <crypto/rngs/rng.h>
+#include <crypto/hashers/hasher.h>
#include "constants.h"
#include "defs.h"
@@ -32,120 +36,116 @@
#include "x509.h"
#include "crl.h"
#include "ca.h"
-#include "rnd.h"
-#include "asn1.h"
#include "certs.h"
#include "smartcard.h"
-#include <asn1/oid.h>
#include "whack.h"
-#include "pkcs1.h"
#include "keys.h"
#include "fetch.h"
#include "ocsp.h"
-#define NONCE_LENGTH 16
+#define NONCE_LENGTH 16
static const char *const cert_status_names[] = {
- "good",
- "revoked",
- "unknown",
- "undefined"
+ "good",
+ "revoked",
+ "unknown",
+ "undefined"
};
static const char *const response_status_names[] = {
- "successful",
- "malformed request",
- "internal error",
- "try later",
- "status #4",
- "signature required",
- "unauthorized"
+ "successful",
+ "malformed request",
+ "internal error",
+ "try later",
+ "status #4",
+ "signature required",
+ "unauthorized"
};
/* response container */
typedef struct response response_t;
struct response {
- chunk_t tbs;
- chunk_t responder_id_name;
- chunk_t responder_id_key;
- time_t produced_at;
- chunk_t responses;
- chunk_t nonce;
- int algorithm;
- chunk_t signature;
+ chunk_t tbs;
+ chunk_t responder_id_name;
+ chunk_t responder_id_key;
+ time_t produced_at;
+ chunk_t responses;
+ chunk_t nonce;
+ int algorithm;
+ chunk_t signature;
};
const response_t empty_response = {
- { NULL, 0 } , /* tbs */
- { NULL, 0 } , /* responder_id_name */
- { NULL, 0 } , /* responder_id_key */
- UNDEFINED_TIME, /* produced_at */
- { NULL, 0 } , /* single_response */
- { NULL, 0 } , /* nonce */
- OID_UNKNOWN , /* signature_algorithm */
- { NULL, 0 } /* signature */
+ { NULL, 0 } , /* tbs */
+ { NULL, 0 } , /* responder_id_name */
+ { NULL, 0 } , /* responder_id_key */
+ UNDEFINED_TIME, /* produced_at */
+ { NULL, 0 } , /* single_response */
+ { NULL, 0 } , /* nonce */
+ OID_UNKNOWN , /* signature_algorithm */
+ { NULL, 0 } /* signature */
};
/* single response container */
typedef struct single_response single_response_t;
struct single_response {
- single_response_t *next;
- int hash_algorithm;
- chunk_t issuer_name_hash;
- chunk_t issuer_key_hash;
- chunk_t serialNumber;
- cert_status_t status;
- time_t revocationTime;
- crl_reason_t revocationReason;
- time_t thisUpdate;
- time_t nextUpdate;
+ single_response_t *next;
+ int hash_algorithm;
+ chunk_t issuer_name_hash;
+ chunk_t issuer_key_hash;
+ chunk_t serialNumber;
+ cert_status_t status;
+ time_t revocationTime;
+ crl_reason_t revocationReason;
+ time_t thisUpdate;
+ time_t nextUpdate;
};
const single_response_t empty_single_response = {
- NULL , /* *next */
- OID_UNKNOWN , /* hash_algorithm */
- { NULL, 0 } , /* issuer_name_hash */
- { NULL, 0 } , /* issuer_key_hash */
- { NULL, 0 } , /* serial_number */
- CERT_UNDEFINED , /* status */
- UNDEFINED_TIME , /* revocationTime */
- REASON_UNSPECIFIED, /* revocationReason */
- UNDEFINED_TIME , /* this_update */
- UNDEFINED_TIME /* next_update */
+ NULL , /* *next */
+ OID_UNKNOWN , /* hash_algorithm */
+ { NULL, 0 } , /* issuer_name_hash */
+ { NULL, 0 } , /* issuer_key_hash */
+ { NULL, 0 } , /* serial_number */
+ CERT_UNDEFINED , /* status */
+ UNDEFINED_TIME , /* revocationTime */
+ REASON_UNSPECIFIED, /* revocationReason */
+ UNDEFINED_TIME , /* this_update */
+ UNDEFINED_TIME /* next_update */
};
/* list of single requests */
typedef struct request_list request_list_t;
struct request_list {
- chunk_t request;
- request_list_t *next;
+ chunk_t request;
+ request_list_t *next;
};
/* some OCSP specific prefabricated ASN.1 constants */
static u_char ASN1_nonce_oid_str[] = {
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+ 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
};
-static const chunk_t ASN1_nonce_oid = strchunk(ASN1_nonce_oid_str);
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
static u_char ASN1_response_oid_str[] = {
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+ 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
};
-static const chunk_t ASN1_response_oid = strchunk(ASN1_response_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
static u_char ASN1_response_content_str[] = {
- 0x04, 0x0D,
- 0x30, 0x0B,
- 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+ 0x04, 0x0D,
+ 0x30, 0x0B,
+ 0x06, 0x09, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
};
-static const chunk_t ASN1_response_content = strchunk(ASN1_response_content_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
/* default OCSP uri */
static chunk_t ocsp_default_uri;
@@ -158,57 +158,60 @@ static x509cert_t *ocsp_requestor_cert = NULL;
static smartcard_t *ocsp_requestor_sc = NULL;
-static const struct RSA_private_key *ocsp_requestor_pri = NULL;
-
-/* asn.1 definitions for parsing */
+static private_key_t *ocsp_requestor_key = NULL;
+/**
+ * ASN.1 definition of ocspResponse
+ */
static const asn1Object_t ocspResponseObjects[] = {
- { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
- { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
- { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
- { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
+ { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
+ { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
+ { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
+ { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define OCSP_RESPONSE_STATUS 1
-#define OCSP_RESPONSE_TYPE 4
-#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_ROOF 7
+#define OCSP_RESPONSE_TYPE 4
+#define OCSP_RESPONSE 5
+/**
+ * ASN.1 definition of basicResponse
+ */
static const asn1Object_t basicResponseObjects[] = {
- { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
- ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
- { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
- { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
- { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
- { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 16 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
- { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
- { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
- { 3, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 24 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
+ { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
+ ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
+ { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
+ { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
+ { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
+ { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 16 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
+ { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
+ { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
+ { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
+ { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define BASIC_RESPONSE_TBS_DATA 1
#define BASIC_RESPONSE_VERSION 3
#define BASIC_RESPONSE_ID_BY_NAME 5
@@ -221,1349 +224,1326 @@ static const asn1Object_t basicResponseObjects[] = {
#define BASIC_RESPONSE_ALGORITHM 20
#define BASIC_RESPONSE_SIGNATURE 21
#define BASIC_RESPONSE_CERTIFICATE 24
-#define BASIC_RESPONSE_ROOF 27
+/**
+ * ASN.1 definition of responses
+ */
static const asn1Object_t responsesObjects[] = {
- { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
+ { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_ROOF 3
-
+/**
+ * ASN.1 definition of singleResponse
+ */
static const asn1Object_t singleResponseObjects[] = {
- { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
- { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
- { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
- { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
- { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
- { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
- { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
- { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
- { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
- { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
- { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
- { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 24 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
+ { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
+ { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
+ { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
+ { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
+ { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
+ { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
+ { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
+ { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
+ { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 24 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
-#define SINGLE_RESPONSE_ALGORITHM 2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER 5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
+#define SINGLE_RESPONSE_ALGORITHM 2
+#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
+#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
+#define SINGLE_RESPONSE_SERIAL_NUMBER 5
+#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
+#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
-#define SINGLE_RESPONSE_THIS_UPDATE 16
-#define SINGLE_RESPONSE_NEXT_UPDATE 18
-#define SINGLE_RESPONSE_EXT_ID 23
-#define SINGLE_RESPONSE_CRITICAL 24
-#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ROOF 28
-
-/* build an ocsp location from certificate information
+#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
+#define SINGLE_RESPONSE_THIS_UPDATE 16
+#define SINGLE_RESPONSE_NEXT_UPDATE 18
+#define SINGLE_RESPONSE_EXT_ID 23
+#define SINGLE_RESPONSE_CRITICAL 24
+#define SINGLE_RESPONSE_EXT_VALUE 25
+
+/*
+ * Build an ocsp location from certificate information
* without unsharing its contents
*/
-static bool
-build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
+static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
{
- static u_char digest[SHA1_DIGEST_SIZE]; /* temporary storage */
+ hasher_t *hasher;
+ static u_char digest[HASH_SIZE_SHA1]; /* temporary storage */
+
+ location->uri = cert->accessLocation;
- location->uri = cert->accessLocation;
+ if (location->uri.ptr == NULL)
+ {
+ ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID);
+ if (ca != NULL && ca->ocspuri != NULL)
+ {
+ location->uri = chunk_create(ca->ocspuri, strlen(ca->ocspuri));
+ }
+ else
+ { /* abort if no ocsp location uri is defined */
+ return FALSE;
+ }
+ }
+
+ /* compute authNameID from as SHA-1 hash of issuer DN */
+ location->authNameID = chunk_create(digest, HASH_SIZE_SHA1);
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ return FALSE;
+ }
+ hasher->get_hash(hasher, cert->issuer, digest);
+ hasher->destroy(hasher);
- if (location->uri.ptr == NULL)
- {
- ca_info_t *ca = get_ca_info(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID);
- if (ca != NULL && ca->ocspuri != NULL)
- setchunk(location->uri, ca->ocspuri, strlen(ca->ocspuri))
- else
- /* abort if no ocsp location uri is defined */
- return FALSE;
- }
-
- setchunk(location->authNameID, digest, SHA1_DIGEST_SIZE);
- compute_digest(cert->issuer, OID_SHA1, &location->authNameID);
-
- location->next = NULL;
- location->issuer = cert->issuer;
- location->authKeyID = cert->authKeyID;
- location->authKeySerialNumber = cert->authKeySerialNumber;
-
- if (cert->authKeyID.ptr == NULL)
- {
- x509cert_t *authcert = get_authcert(cert->issuer
- , cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);
-
- if (authcert != NULL)
+ location->next = NULL;
+ location->issuer = cert->issuer;
+ location->authKeyID = cert->authKeyID;
+ location->authKeySerialNumber = cert->authKeySerialNumber;
+
+ if (cert->authKeyID.ptr == NULL)
{
- location->authKeyID = authcert->subjectKeyID;
- location->authKeySerialNumber = authcert->serialNumber;
+ x509cert_t *authcert = get_authcert(cert->issuer
+ , cert->authKeySerialNumber, cert->authKeyID, AUTH_CA);
+
+ if (authcert != NULL)
+ {
+ location->authKeyID = authcert->subjectKeyID;
+ location->authKeySerialNumber = authcert->serialNumber;
+ }
}
- }
- location->nonce = empty_chunk;
- location->certinfo = NULL;
+ location->nonce = chunk_empty;
+ location->certinfo = NULL;
- return TRUE;
+ return TRUE;
}
-/*
- * compare two ocsp locations for equality
+/**
+ * Compare two ocsp locations for equality
*/
-static bool
-same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
+static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
{
- return ((a->authKeyID.ptr != NULL)
- ? same_keyid(a->authKeyID, b->authKeyID)
- : (same_dn(a->issuer, b->issuer)
- && same_serial(a->authKeySerialNumber, b->authKeySerialNumber)))
- && same_chunk(a->uri, b->uri);
+ return ((a->authKeyID.ptr != NULL)
+ ? same_keyid(a->authKeyID, b->authKeyID)
+ : (same_dn(a->issuer, b->issuer)
+ && same_serial(a->authKeySerialNumber, b->authKeySerialNumber)))
+ && chunk_equals(a->uri, b->uri);
}
-/*
- * find an existing ocsp location in a chained list
+/**
+ * Find an existing ocsp location in a chained list
*/
-ocsp_location_t*
-get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
+ocsp_location_t* get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
{
- while (chain != NULL)
- {
- if (same_ocsp_location(loc, chain))
- return chain;
- chain = chain->next;
- }
- return NULL;
+ while (chain != NULL)
+ {
+ if (same_ocsp_location(loc, chain))
+ return chain;
+ chain = chain->next;
+ }
+ return NULL;
}
-
-/* retrieves the status of a cert from the ocsp cache
+
+/**
+ * Retrieves the status of a cert from the ocsp cache
* returns CERT_UNDEFINED if no status is found
*/
-static cert_status_t
-get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
- ,time_t *nextUpdate, time_t *revocationTime, crl_reason_t *revocationReason)
+static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
+ chunk_t serialNumber,
+ time_t *nextUpdate, time_t *revocationTime,
+ crl_reason_t *revocationReason)
{
- ocsp_certinfo_t *certinfo, **certinfop;
- int cmp = -1;
+ ocsp_certinfo_t *certinfo, **certinfop;
+ int cmp = -1;
- /* find location */
- ocsp_location_t *location = get_ocsp_location(loc, ocsp_cache);
+ /* find location */
+ ocsp_location_t *location = get_ocsp_location(loc, ocsp_cache);
- if (location == NULL)
- return CERT_UNDEFINED;
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
+ if (location == NULL)
+ return CERT_UNDEFINED;
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
+ /* traverse list of certinfos in increasing order */
+ certinfop = &location->certinfo;
certinfo = *certinfop;
- }
- if (cmp == 0)
- {
- *nextUpdate = certinfo->nextUpdate;
- *revocationTime = certinfo->revocationTime;
- *revocationReason = certinfo->revocationReason;
- return certinfo->status;
- }
+ while (certinfo != NULL)
+ {
+ cmp = chunk_compare(serialNumber, certinfo->serialNumber);
+ if (cmp <= 0)
+ break;
+ certinfop = &certinfo->next;
+ certinfo = *certinfop;
+ }
+
+ if (cmp == 0)
+ {
+ *nextUpdate = certinfo->nextUpdate;
+ *revocationTime = certinfo->revocationTime;
+ *revocationReason = certinfo->revocationReason;
+ return certinfo->status;
+ }
- return CERT_UNDEFINED;
+ return CERT_UNDEFINED;
}
-/*
- * verify the ocsp status of a certificate
+/**
+ * Verify the ocsp status of a certificate
*/
-cert_status_t
-verify_by_ocsp(const x509cert_t *cert, time_t *until
-, time_t *revocationDate, crl_reason_t *revocationReason)
+cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
+ time_t *revocationDate,
+ crl_reason_t *revocationReason)
{
- cert_status_t status;
- ocsp_location_t location;
- time_t nextUpdate = 0;
-
- *revocationDate = UNDEFINED_TIME;
- *revocationReason = REASON_UNSPECIFIED;
-
- /* is an ocsp location defined? */
- if (!build_ocsp_location(cert, &location))
- return CERT_UNDEFINED;
+ cert_status_t status;
+ ocsp_location_t location;
+ time_t nextUpdate = 0;
+
+ *revocationDate = UNDEFINED_TIME;
+ *revocationReason = REASON_UNSPECIFIED;
+
+ /* is an ocsp location defined? */
+ if (!build_ocsp_location(cert, &location))
+ return CERT_UNDEFINED;
+
+ lock_ocsp_cache("verify_by_ocsp");
+ status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate
+ , revocationDate, revocationReason);
+ unlock_ocsp_cache("verify_by_ocsp");
+
+ if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
+ {
+ plog("ocsp status is stale or not in cache");
+ add_ocsp_fetch_request(&location, cert->serialNumber);
- lock_ocsp_cache("verify_by_ocsp");
- status = get_ocsp_status(&location, cert->serialNumber, &nextUpdate
- , revocationDate, revocationReason);
- unlock_ocsp_cache("verify_by_ocsp");
-
- if (status == CERT_UNDEFINED || nextUpdate < time(NULL))
- {
- plog("ocsp status is stale or not in cache");
- add_ocsp_fetch_request(&location, cert->serialNumber);
-
- /* inititate fetching of ocsp status */
- wake_fetch_thread("verify_by_ocsp");
- }
- *until = nextUpdate;
- return status;
+ /* inititate fetching of ocsp status */
+ wake_fetch_thread("verify_by_ocsp");
+ }
+ *until = nextUpdate;
+ return status;
}
-/*
- * check if an ocsp status is about to expire
+/**
+ * Check if an ocsp status is about to expire
*/
-void
-check_ocsp(void)
+void check_ocsp(void)
{
- ocsp_location_t *location;
-
- lock_ocsp_cache("check_ocsp");
- location = ocsp_cache;
-
- while (location != NULL)
- {
- char buf[BUF_LEN];
- bool first = TRUE;
- ocsp_certinfo_t *certinfo = location->certinfo;
+ ocsp_location_t *location;
- while (certinfo != NULL)
+ lock_ocsp_cache("check_ocsp");
+ location = ocsp_cache;
+
+ while (location != NULL)
{
- if (!certinfo->once)
- {
- time_t time_left = certinfo->nextUpdate - time(NULL);
+ char buf[BUF_LEN];
+ bool first = TRUE;
+ ocsp_certinfo_t *certinfo = location->certinfo;
- DBG(DBG_CONTROL,
- if (first)
- {
- dntoa(buf, BUF_LEN, location->issuer);
- DBG_log("issuer: '%s'", buf);
- if (location->authKeyID.ptr != NULL)
+ while (certinfo != NULL)
+ {
+ if (!certinfo->once)
{
- datatot(location->authKeyID.ptr, location->authKeyID.len
- , ':', buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
+ time_t time_left = certinfo->nextUpdate - time(NULL);
+
+ DBG(DBG_CONTROL,
+ if (first)
+ {
+ dntoa(buf, BUF_LEN, location->issuer);
+ DBG_log("issuer: '%s'", buf);
+ if (location->authKeyID.ptr != NULL)
+ {
+ datatot(location->authKeyID.ptr, location->authKeyID.len
+ , ':', buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
+ first = FALSE;
+ }
+ datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
+ , ':', buf, BUF_LEN);
+ DBG_log("serial: %s, %ld seconds left", buf, time_left)
+ )
+
+ if (time_left < 2*crl_check_interval)
+ add_ocsp_fetch_request(location, certinfo->serialNumber);
}
- first = FALSE;
- }
- datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
- , ':', buf, BUF_LEN);
- DBG_log("serial: %s, %ld seconds left", buf, time_left)
- )
-
- if (time_left < 2*crl_check_interval)
- add_ocsp_fetch_request(location, certinfo->serialNumber);
- }
- certinfo = certinfo->next;
+ certinfo = certinfo->next;
+ }
+ location = location->next;
}
- location = location->next;
- }
- unlock_ocsp_cache("check_ocsp");
+ unlock_ocsp_cache("check_ocsp");
}
-/*
+/**
* frees the allocated memory of a certinfo struct
*/
-static void
-free_certinfo(ocsp_certinfo_t *certinfo)
+static void free_certinfo(ocsp_certinfo_t *certinfo)
{
- freeanychunk(certinfo->serialNumber);
- pfree(certinfo);
+ free(certinfo->serialNumber.ptr);
+ free(certinfo);
}
-/*
+/**
* frees all certinfos in a chained list
*/
-static void
-free_certinfos(ocsp_certinfo_t *chain)
+static void free_certinfos(ocsp_certinfo_t *chain)
{
- ocsp_certinfo_t *certinfo;
+ ocsp_certinfo_t *certinfo;
- while (chain != NULL)
- {
- certinfo = chain;
- chain = chain->next;
- free_certinfo(certinfo);
- }
+ while (chain != NULL)
+ {
+ certinfo = chain;
+ chain = chain->next;
+ free_certinfo(certinfo);
+ }
}
-/*
- * frees the memory allocated to an ocsp location including all certinfos
+/**
+ * Frees the memory allocated to an ocsp location including all certinfos
*/
-static void
-free_ocsp_location(ocsp_location_t* location)
+static void free_ocsp_location(ocsp_location_t* location)
{
- freeanychunk(location->issuer);
- freeanychunk(location->authNameID);
- freeanychunk(location->authKeyID);
- freeanychunk(location->authKeySerialNumber);
- freeanychunk(location->uri);
- free_certinfos(location->certinfo);
- pfree(location);
+ free(location->issuer.ptr);
+ free(location->authNameID.ptr);
+ free(location->authKeyID.ptr);
+ free(location->authKeySerialNumber.ptr);
+ free(location->uri.ptr);
+ free_certinfos(location->certinfo);
+ free(location);
}
/*
- * free a chained list of ocsp locations
+ * Free a chained list of ocsp locations
*/
-void
-free_ocsp_locations(ocsp_location_t **chain)
+void free_ocsp_locations(ocsp_location_t **chain)
{
- while (*chain != NULL)
- {
- ocsp_location_t *location = *chain;
- *chain = location->next;
- free_ocsp_location(location);
- }
+ while (*chain != NULL)
+ {
+ ocsp_location_t *location = *chain;
+ *chain = location->next;
+ free_ocsp_location(location);
+ }
}
-/*
- * free the ocsp cache
+/**
+ * Free the ocsp cache
*/
-void
-free_ocsp_cache(void)
+void free_ocsp_cache(void)
{
- lock_ocsp_cache("free_ocsp_cache");
- free_ocsp_locations(&ocsp_cache);
- unlock_ocsp_cache("free_ocsp_cache");
+ lock_ocsp_cache("free_ocsp_cache");
+ free_ocsp_locations(&ocsp_cache);
+ unlock_ocsp_cache("free_ocsp_cache");
}
-/*
- * frees the ocsp cache and global variables
+/**
+ * Frees the ocsp cache and global variables
*/
-void
-free_ocsp(void)
+void free_ocsp(void)
{
- pfreeany(ocsp_default_uri.ptr);
- free_ocsp_cache();
+ free(ocsp_default_uri.ptr);
+ free_ocsp_cache();
}
-/*
- * list a chained list of ocsp_locations
+/**
+ * List a chained list of ocsp_locations
*/
-void
-list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
-, bool strict)
+void list_ocsp_locations(ocsp_location_t *location, bool requests,
+ bool utc, bool strict)
{
- bool first = TRUE;
-
- while (location != NULL)
- {
- ocsp_certinfo_t *certinfo = location->certinfo;
+ bool first = TRUE;
- if (certinfo != NULL)
+ while (location != NULL)
{
- u_char buf[BUF_LEN];
-
- if (first)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of OCSP %s:", requests?
- "fetch requests":"responses");
- first = FALSE;
- }
- whack_log(RC_COMMENT, " ");
- if (location->issuer.ptr != NULL)
- {
- dntoa(buf, BUF_LEN, location->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- }
- whack_log(RC_COMMENT, " uri: '%.*s'", (int)location->uri.len
- , location->uri.ptr);
- if (location->authNameID.ptr != NULL)
- {
- datatot(location->authNameID.ptr, location->authNameID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authname: %s", buf);
- }
- if (location->authKeyID.ptr != NULL)
- {
- datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (location->authKeySerialNumber.ptr != NULL)
- {
- datatot(location->authKeySerialNumber.ptr
- , location->authKeySerialNumber.len, ':', buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
- while (certinfo != NULL)
- {
- char thisUpdate[TIMETOA_BUF];
-
- strcpy(thisUpdate, timetoa(&certinfo->thisUpdate, utc));
-
- if (requests)
- {
- whack_log(RC_COMMENT, "%s, trials: %d", thisUpdate
- , certinfo->trials);
- }
- else if (certinfo->once)
- {
- whack_log(RC_COMMENT, "%s, onetime use%s", thisUpdate
- , (certinfo->nextUpdate < time(NULL))? " (expired)": "");
- }
- else
+ ocsp_certinfo_t *certinfo = location->certinfo;
+
+ if (certinfo != NULL)
{
- whack_log(RC_COMMENT, "%s, until %s %s", thisUpdate
- , timetoa(&certinfo->nextUpdate, utc)
- , check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
+ u_char buf[BUF_LEN];
+
+ if (first)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of OCSP %s:", requests?
+ "fetch requests":"responses");
+ first = FALSE;
+ }
+ whack_log(RC_COMMENT, " ");
+ if (location->issuer.ptr != NULL)
+ {
+ dntoa(buf, BUF_LEN, location->issuer);
+ whack_log(RC_COMMENT, " issuer: '%s'", buf);
+ }
+ whack_log(RC_COMMENT, " uri: '%.*s'", (int)location->uri.len
+ , location->uri.ptr);
+ if (location->authNameID.ptr != NULL)
+ {
+ datatot(location->authNameID.ptr, location->authNameID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authname: %s", buf);
+ }
+ if (location->authKeyID.ptr != NULL)
+ {
+ datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (location->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(location->authKeySerialNumber.ptr
+ , location->authKeySerialNumber.len, ':', buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
+ while (certinfo != NULL)
+ {
+ char thisUpdate[BUF_LEN];
+
+ snprintf(thisUpdate, BUF_LEN, "%T", &certinfo->thisUpdate, utc);
+
+ if (requests)
+ {
+ whack_log(RC_COMMENT, "%s, trials: %d", thisUpdate
+ , certinfo->trials);
+ }
+ else if (certinfo->once)
+ {
+ whack_log(RC_COMMENT, "%s, onetime use%s", thisUpdate
+ , (certinfo->nextUpdate < time(NULL))? " (expired)": "");
+ }
+ else
+ {
+ whack_log(RC_COMMENT, "%s, until %T %s", thisUpdate
+ , &certinfo->nextUpdate, utc
+ , check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
+ }
+ datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len, ':'
+ , buf, BUF_LEN);
+ whack_log(RC_COMMENT, " serial: %s, %s", buf
+ , cert_status_names[certinfo->status]);
+ certinfo = certinfo->next;
+ }
}
- datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s, %s", buf
- , cert_status_names[certinfo->status]);
- certinfo = certinfo->next;
- }
+ location = location->next;
}
- location = location->next;
- }
}
-/*
- * list the ocsp cache
+/**
+ * List the ocsp cache
*/
-void
-list_ocsp_cache(bool utc, bool strict)
+void list_ocsp_cache(bool utc, bool strict)
{
- lock_ocsp_cache("list_ocsp_cache");
- list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
- unlock_ocsp_cache("list_ocsp_cache");
+ lock_ocsp_cache("list_ocsp_cache");
+ list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
+ unlock_ocsp_cache("list_ocsp_cache");
}
-static bool
-get_ocsp_requestor_cert(ocsp_location_t *location)
+static bool get_ocsp_requestor_cert(ocsp_location_t *location)
{
- x509cert_t *cert = NULL;
+ x509cert_t *cert = NULL;
- /* initialize temporary static storage */
- ocsp_requestor_cert = NULL;
- ocsp_requestor_sc = NULL;
- ocsp_requestor_pri = NULL;
+ /* initialize temporary static storage */
+ ocsp_requestor_cert = NULL;
+ ocsp_requestor_sc = NULL;
+ ocsp_requestor_key = NULL;
- for (;;)
- {
- char buf[BUF_LEN];
-
- /* looking for a certificate from the same issuer */
- cert = get_x509cert(location->issuer, location->authKeySerialNumber
- ,location->authKeyID, cert);
- if (cert == NULL)
- break;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("candidate: '%s'", buf);
- )
-
- if (cert->smartcard)
+ for (;;)
{
- /* look for a matching private key on a smartcard */
- smartcard_t *sc = scx_get(cert);
+ char buf[BUF_LEN];
+
+ /* looking for a certificate from the same issuer */
+ cert = get_x509cert(location->issuer, location->authKeySerialNumber
+ ,location->authKeyID, cert);
+ if (cert == NULL)
+ break;
- if (sc != NULL)
- {
DBG(DBG_CONTROL,
- DBG_log("matching smartcard found")
+ dntoa(buf, BUF_LEN, cert->subject);
+ DBG_log("candidate: '%s'", buf);
)
- if (sc->valid)
+
+ if (cert->smartcard)
{
- ocsp_requestor_cert = cert;
- ocsp_requestor_sc = sc;
- return TRUE;
+ /* look for a matching private key on a smartcard */
+ smartcard_t *sc = scx_get(cert);
+
+ if (sc != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("matching smartcard found")
+ )
+ if (sc->valid)
+ {
+ ocsp_requestor_cert = cert;
+ ocsp_requestor_sc = sc;
+ return TRUE;
+ }
+ plog("unable to sign ocsp request without PIN");
+ }
}
- plog("unable to sign ocsp request without PIN");
- }
- }
- else
- {
- /* look for a matching private key in the chained list */
- const struct RSA_private_key *pri = get_x509_private_key(cert);
+ else
+ {
+ /* look for a matching private key in the chained list */
+ private_key_t *private = get_x509_private_key(cert);
- if (pri != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("matching private key found")
- )
- ocsp_requestor_cert = cert;
- ocsp_requestor_pri = pri;
- return TRUE;
- }
+ if (private != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("matching private key found")
+ )
+ ocsp_requestor_cert = cert;
+ ocsp_requestor_key = private;
+ return TRUE;
+ }
+ }
}
- }
- return FALSE;
+ return FALSE;
}
-static chunk_t
-generate_signature(chunk_t digest, smartcard_t *sc
- , const RSA_private_key_t *pri)
+static chunk_t sc_build_sha1_signature(chunk_t tbs, smartcard_t *sc)
{
- chunk_t sigdata;
- u_char *pos;
- size_t siglen = 0;
-
- if (sc != NULL)
- {
- /* RSA signature is done on smartcard */
+ hasher_t *hasher;
+ u_char *pos;
+ u_char digest_buf[HASH_SIZE_SHA1];
+ chunk_t digest = chunk_from_buf(digest_buf);
+ chunk_t digest_info, sigdata;
+ size_t siglen = 0;
if (!scx_establish_context(sc) || !scx_login(sc))
{
- scx_release_context(sc);
- return empty_chunk;
+ scx_release_context(sc);
+ return chunk_empty;
}
siglen = scx_get_keylength(sc);
if (siglen == 0)
{
- plog("failed to get keylength from smartcard");
- scx_release_context(sc);
- return empty_chunk;
+ plog("failed to get keylength from smartcard");
+ scx_release_context(sc);
+ return chunk_empty;
}
DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
+ DBG_log("signing hash with RSA key from smartcard (slot: %d, id: %s)"
+ , (int)sc->slot, sc->id)
)
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (hasher == NULL)
+ {
+ return chunk_empty;
+ }
+ hasher->get_hash(hasher, tbs, digest_buf);
+ hasher->destroy(hasher);
+
+ /* according to PKCS#1 v2.1 digest must be packaged into
+ * an ASN.1 structure for encryption
+ */
+ digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
+ , asn1_algorithmIdentifier(OID_SHA1)
+ , asn1_simple_object(ASN1_OCTET_STRING, digest));
+
+ pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
*pos++ = 0x00;
- scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);
+ scx_sign_hash(sc, digest_info.ptr, digest_info.len, pos, siglen);
+ free(digest_info.ptr);
+
if (!pkcs11_keep_state)
- scx_release_context(sc);
- }
- else
- {
- /* RSA signature is done in software */
- siglen = pri->pub.k;
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
- *pos++ = 0x00;
- sign_hash(pri, digest.ptr, digest.len, pos, siglen);
- }
- return sigdata;
+ {
+ scx_release_context(sc);
+ }
+ return sigdata;
}
-/*
- * build signature into ocsp request
- * gets built only if a request cert with
- * a corresponding private key is found
+/**
+ * build signature into ocsp request gets built only if a request cert
+ * with a corresponding private key is found
*/
-static chunk_t
-build_signature(chunk_t tbsRequest)
+static chunk_t build_signature(chunk_t tbsRequest)
{
- chunk_t sigdata, certs;
- chunk_t digest_info;
-
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest_raw = { digest_buf, MAX_DIGEST_LEN };
-
- if (!compute_digest(tbsRequest, OID_SHA1, &digest_raw))
- return empty_chunk;
-
- /* according to PKCS#1 v2.1 digest must be packaged into
- * an ASN.1 structure for encryption
- */
- digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_sha1_id
- , asn1_simple_object(ASN1_OCTET_STRING, digest_raw));
-
- /* generate the RSA signature */
- sigdata = generate_signature(digest_info
- , ocsp_requestor_sc
- , ocsp_requestor_pri);
- freeanychunk(digest_info);
-
- /* has the RSA signature generation been successful? */
- if (sigdata.ptr == NULL)
- return empty_chunk;
-
- /* include our certificate */
- certs = asn1_wrap(ASN1_CONTEXT_C_0, "m"
- , asn1_simple_object(ASN1_SEQUENCE
- , ocsp_requestor_cert->certificate
- )
- );
-
- /* build signature comprising algorithm, signature and cert */
- return asn1_wrap(ASN1_CONTEXT_C_0, "m"
- , asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_sha1WithRSA_id
- , sigdata
- , certs
- )
- );
+ chunk_t sigdata, certs;
+
+ if (ocsp_requestor_sc != NULL)
+ {
+ /* RSA signature is done on smartcard */
+ sigdata = sc_build_sha1_signature(tbsRequest, ocsp_requestor_sc);
+ }
+ else
+ {
+ /* RSA signature is done in software */
+ sigdata = x509_build_signature(tbsRequest, OID_SHA1, ocsp_requestor_key,
+ TRUE);
+ }
+ if (sigdata.ptr == NULL)
+ {
+ return chunk_empty;
+ }
+
+ /* include our certificate */
+ certs = asn1_wrap(ASN1_CONTEXT_C_0, "m"
+ , asn1_simple_object(ASN1_SEQUENCE
+ , ocsp_requestor_cert->certificate
+ )
+ );
+
+ /* build signature comprising algorithm, signature and cert */
+ return asn1_wrap(ASN1_CONTEXT_C_0, "m"
+ , asn1_wrap(ASN1_SEQUENCE, "cmm"
+ , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA)
+ , sigdata
+ , certs
+ )
+ );
}
-/* build request (into requestList)
+/**
+ * Build request (into requestList)
* no singleRequestExtensions used
*/
-static chunk_t
-build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
+static chunk_t build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
{
- chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
- , ASN1_sha1_id
- , asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
- , asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
- , asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
+ chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
+ , asn1_algorithmIdentifier(OID_SHA1)
+ , asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
+ , asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
+ , asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
- return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
+ return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
}
-/*
+/**
* build requestList (into TBSRequest)
*/
-static chunk_t
-build_request_list(ocsp_location_t *location)
+static chunk_t build_request_list(ocsp_location_t *location)
{
- chunk_t requestList;
- request_list_t *reqs = NULL;
- ocsp_certinfo_t *certinfo = location->certinfo;
- u_char *pos;
-
- size_t datalen = 0;
-
- /* build content */
- while (certinfo != NULL)
- {
- /* build request for every certificate in list
- * and store them in a chained list
- */
- request_list_t *req = alloc_thing(request_list_t, "ocsp request");
+ chunk_t requestList;
+ request_list_t *reqs = NULL;
+ ocsp_certinfo_t *certinfo = location->certinfo;
+ u_char *pos;
- req->request = build_request(location, certinfo);
- req->next = reqs;
- reqs = req;
+ size_t datalen = 0;
- datalen += req->request.len;
- certinfo = certinfo->next;
- }
+ /* build content */
+ while (certinfo != NULL)
+ {
+ /* build request for every certificate in list
+ * and store them in a chained list
+ */
+ request_list_t *req = malloc_thing(request_list_t);
+
+ req->request = build_request(location, certinfo);
+ req->next = reqs;
+ reqs = req;
+
+ datalen += req->request.len;
+ certinfo = certinfo->next;
+ }
- pos = build_asn1_object(&requestList, ASN1_SEQUENCE
- , datalen);
+ pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen);
- /* copy all in chained list, free list afterwards */
- while (reqs != NULL)
- {
- request_list_t *req = reqs;
+ /* copy all in chained list, free list afterwards */
+ while (reqs != NULL)
+ {
+ request_list_t *req = reqs;
- mv_chunk(&pos, req->request);
- reqs = reqs->next;
- pfree(req);
- }
+ mv_chunk(&pos, req->request);
+ reqs = reqs->next;
+ free(req);
+ }
- return requestList;
+ return requestList;
}
-/*
- * build requestorName (into TBSRequest)
+/**
+ * Build requestorName (into TBSRequest)
*/
-static chunk_t
-build_requestor_name(void)
+static chunk_t build_requestor_name(void)
{
- return asn1_wrap(ASN1_CONTEXT_C_1, "m"
- , asn1_simple_object(ASN1_CONTEXT_C_4
- , ocsp_requestor_cert->subject));
+ return asn1_wrap(ASN1_CONTEXT_C_1, "m"
+ , asn1_simple_object(ASN1_CONTEXT_C_4
+ , ocsp_requestor_cert->subject));
}
-/*
+/**
* build nonce extension (into requestExtensions)
*/
-static chunk_t
-build_nonce_extension(ocsp_location_t *location)
+static chunk_t build_nonce_extension(ocsp_location_t *location)
{
- /* generate a random nonce */
- location->nonce.ptr = alloc_bytes(NONCE_LENGTH, "ocsp nonce"),
- location->nonce.len = NONCE_LENGTH;
- get_rnd_bytes(location->nonce.ptr, NONCE_LENGTH);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_nonce_oid
- , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
+ rng_t *rng;
+
+ /* generate a random nonce */
+ location->nonce.ptr = malloc(NONCE_LENGTH),
+ location->nonce.len = NONCE_LENGTH;
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ rng->get_bytes(rng, location->nonce.len, location->nonce.ptr);
+ rng->destroy(rng);
+
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_nonce_oid
+ , asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
}
-/*
- * build requestExtensions (into TBSRequest)
+/**
+ * Build requestExtensions (into TBSRequest)
*/
-static chunk_t
-build_request_ext(ocsp_location_t *location)
+static chunk_t build_request_ext(ocsp_location_t *location)
{
- return asn1_wrap(ASN1_CONTEXT_C_2, "m"
- , asn1_wrap(ASN1_SEQUENCE, "mm"
- , build_nonce_extension(location)
- , asn1_wrap(ASN1_SEQUENCE, "cc"
- , ASN1_response_oid
- , ASN1_response_content
- )
- )
- );
+ return asn1_wrap(ASN1_CONTEXT_C_2, "m"
+ , asn1_wrap(ASN1_SEQUENCE, "mm"
+ , build_nonce_extension(location)
+ , asn1_wrap(ASN1_SEQUENCE, "cc"
+ , ASN1_response_oid
+ , ASN1_response_content
+ )
+ )
+ );
}
-/*
- * build TBSRequest (into OCSPRequest)
+/**
+ * Build TBSRequest (into OCSPRequest)
*/
-static chunk_t
-build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
+static chunk_t build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
{
- /* version is skipped since the default is ok */
- return asn1_wrap(ASN1_SEQUENCE, "mmm"
- , (has_requestor_cert)
- ? build_requestor_name()
- : empty_chunk
- , build_request_list(location)
- , build_request_ext(location));
+ /* version is skipped since the default is ok */
+ return asn1_wrap(ASN1_SEQUENCE, "mmm"
+ , (has_requestor_cert)
+ ? build_requestor_name()
+ : chunk_empty
+ , build_request_list(location)
+ , build_request_ext(location));
}
-/* assembles an ocsp request to given location
+/**
+ * Assembles an ocsp request to given location
* and sets nonce field in location to the sent nonce
*/
-chunk_t
-build_ocsp_request(ocsp_location_t *location)
+chunk_t build_ocsp_request(ocsp_location_t *location)
{
- bool has_requestor_cert;
- chunk_t tbsRequest, signature;
- char buf[BUF_LEN];
-
- DBG(DBG_CONTROL,
- DBG_log("assembling ocsp request");
- dntoa(buf, BUF_LEN, location->issuer);
- DBG_log("issuer: '%s'", buf);
- if (location->authKeyID.ptr != NULL)
- {
- datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
- lock_certs_and_keys("build_ocsp_request");
+ bool has_requestor_cert;
+ chunk_t tbsRequest, signature;
+ char buf[BUF_LEN];
- /* looks for requestor cert and matching private key */
- has_requestor_cert = get_ocsp_requestor_cert(location);
+ DBG(DBG_CONTROL,
+ DBG_log("assembling ocsp request");
+ dntoa(buf, BUF_LEN, location->issuer);
+ DBG_log("issuer: '%s'", buf);
+ if (location->authKeyID.ptr != NULL)
+ {
+ datatot(location->authKeyID.ptr, location->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
+ )
+ lock_certs_and_keys("build_ocsp_request");
+
+ /* looks for requestor cert and matching private key */
+ has_requestor_cert = get_ocsp_requestor_cert(location);
- /* build content */
- tbsRequest = build_tbs_request(location, has_requestor_cert);
+ /* build content */
+ tbsRequest = build_tbs_request(location, has_requestor_cert);
- /* sign tbsReuqest */
- signature = (has_requestor_cert)? build_signature(tbsRequest)
- : empty_chunk;
+ /* sign tbsReuqest */
+ signature = (has_requestor_cert)? build_signature(tbsRequest)
+ : chunk_empty;
- unlock_certs_and_keys("build_ocsp_request");
+ unlock_certs_and_keys("build_ocsp_request");
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , tbsRequest
- , signature);
+ return asn1_wrap(ASN1_SEQUENCE, "mm"
+ , tbsRequest
+ , signature);
}
-/*
- * check if the OCSP response has a valid signature
+/**
+ * Check if the OCSP response has a valid signature
*/
-static bool
-valid_ocsp_response(response_t *res)
+static bool valid_ocsp_response(response_t *res)
{
- int pathlen;
- x509cert_t *authcert;
+ int pathlen;
+ x509cert_t *authcert;
- lock_authcert_list("valid_ocsp_response");
+ lock_authcert_list("valid_ocsp_response");
- authcert = get_authcert(res->responder_id_name, empty_chunk
- , res->responder_id_key, AUTH_OCSP | AUTH_CA);
-
- if (authcert == NULL)
- {
- plog("no matching ocsp signer cert found");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("ocsp signer cert found")
- )
-
- if (!check_signature(res->tbs, res->signature, res->algorithm
- , res->algorithm, authcert))
- {
- plog("signature of ocsp response is invalid");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("signature of ocsp response is valid")
- )
-
-
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- u_char buf[BUF_LEN];
- err_t ugh = NULL;
- time_t until;
-
- x509cert_t *cert = authcert;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
-
- ugh = check_validity(authcert, &until);
-
- if (ugh != NULL)
- {
- plog("%s", ugh);
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
-
- authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
+ authcert = get_authcert(res->responder_id_name, chunk_empty
+ , res->responder_id_key, AUTH_OCSP | AUTH_CA);
if (authcert == NULL)
{
- plog("issuer cacert not found");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
+ plog("no matching ocsp signer cert found");
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
}
DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
+ DBG_log("ocsp signer cert found")
)
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, authcert))
+ if (!x509_check_signature(res->tbs, res->signature, res->algorithm, authcert))
{
- plog("certificate signature is invalid");
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
+ plog("signature of ocsp response is invalid");
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
}
DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
+ DBG_log("signature of ocsp response is valid")
)
- /* check if cert is self-signed */
- if (same_dn(cert->issuer, cert->subject))
+
+ for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
{
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- unlock_authcert_list("valid_ocsp_response");
- return TRUE;
+ u_char buf[BUF_LEN];
+ err_t ugh = NULL;
+ time_t until;
+
+ x509cert_t *cert = authcert;
+
+ DBG(DBG_CONTROL,
+ dntoa(buf, BUF_LEN, cert->subject);
+ DBG_log("subject: '%s'",buf);
+ dntoa(buf, BUF_LEN, cert->issuer);
+ DBG_log("issuer: '%s'",buf);
+ if (cert->authKeyID.ptr != NULL)
+ {
+ datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
+ )
+
+ ugh = check_validity(authcert, &until);
+
+ if (ugh != NULL)
+ {
+ plog("%s", ugh);
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
+ }
+
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is valid")
+ )
+
+ authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID, AUTH_CA);
+
+ if (authcert == NULL)
+ {
+ plog("issuer cacert not found");
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("issuer cacert found")
+ )
+
+ if (!x509_check_signature(cert->tbsCertificate, cert->signature,
+ cert->algorithm, authcert))
+ {
+ plog("certificate signature is invalid");
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("certificate signature is valid")
+ )
+
+ /* check if cert is self-signed */
+ if (same_dn(cert->issuer, cert->subject))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("reached self-signed root ca")
+ )
+ unlock_authcert_list("valid_ocsp_response");
+ return TRUE;
+ }
}
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- unlock_authcert_list("valid_ocsp_response");
- return FALSE;
+ plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
+ unlock_authcert_list("valid_ocsp_response");
+ return FALSE;
}
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
*/
-static bool
-parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
+static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level, version;
- u_char buf[BUF_LEN];
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < BASIC_RESPONSE_ROOF)
- {
- if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
+ asn1_parser_t *parser;
+ chunk_t object;
+ u_int version;
+ u_char buf[BUF_LEN];
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
+
+ parser = asn1_parser_create(basicResponseObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
{
- case BASIC_RESPONSE_TBS_DATA:
- res->tbs = object;
- break;
- case BASIC_RESPONSE_VERSION:
- version = (object.len)? (1 + (u_int)*object.ptr) : 1;
- if (version != OCSP_BASIC_RESPONSE_VERSION)
- {
- plog("wrong ocsp basic response version (version= %i)", version);
- return FALSE;
- }
- break;
- case BASIC_RESPONSE_ID_BY_NAME:
- res->responder_id_name = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case BASIC_RESPONSE_ID_BY_KEY:
- res->responder_id_key = object;
- break;
- case BASIC_RESPONSE_PRODUCED_AT:
- res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case BASIC_RESPONSE_RESPONSES:
- res->responses = object;
- break;
- case BASIC_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case BASIC_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case BASIC_RESPONSE_EXT_VALUE:
- if (extn_oid == OID_NONCE)
- res->nonce = object;
- break;
- case BASIC_RESPONSE_ALGORITHM:
- res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case BASIC_RESPONSE_SIGNATURE:
- res->signature = object;
- break;
- case BASIC_RESPONSE_CERTIFICATE:
- {
- chunk_t blob;
- x509cert_t *cert = alloc_thing(x509cert_t, "ocspcert");
-
- clonetochunk(blob, object.ptr, object.len, "ocspcert blob");
- *cert = empty_x509cert;
-
- if (parse_x509cert(blob, level+1, cert)
- && cert->isOcspSigner
- && trust_authcert_candidate(cert, NULL))
+ switch (objectID)
{
- add_authcert(cert, AUTH_OCSP);
- }
- else
- {
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("embedded ocsp certificate rejected")
- )
- free_x509cert(cert);
+ case BASIC_RESPONSE_TBS_DATA:
+ res->tbs = object;
+ break;
+ case BASIC_RESPONSE_VERSION:
+ version = (object.len)? (1 + (u_int)*object.ptr) : 1;
+ if (version != OCSP_BASIC_RESPONSE_VERSION)
+ {
+ plog("wrong ocsp basic response version (version= %i)", version);
+ goto end;
+ }
+ break;
+ case BASIC_RESPONSE_ID_BY_NAME:
+ res->responder_id_name = object;
+ DBG(DBG_PARSING,
+ dntoa(buf, BUF_LEN, object);
+ DBG_log(" '%s'",buf)
+ )
+ break;
+ case BASIC_RESPONSE_ID_BY_KEY:
+ res->responder_id_key = object;
+ break;
+ case BASIC_RESPONSE_PRODUCED_AT:
+ res->produced_at = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case BASIC_RESPONSE_RESPONSES:
+ res->responses = object;
+ break;
+ case BASIC_RESPONSE_EXT_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case BASIC_RESPONSE_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(critical)?"TRUE":"FALSE");
+ )
+ break;
+ case BASIC_RESPONSE_EXT_VALUE:
+ if (extn_oid == OID_NONCE)
+ res->nonce = object;
+ break;
+ case BASIC_RESPONSE_ALGORITHM:
+ res->algorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case BASIC_RESPONSE_SIGNATURE:
+ res->signature = object;
+ break;
+ case BASIC_RESPONSE_CERTIFICATE:
+ {
+ chunk_t blob = chunk_clone(object);
+ x509cert_t *cert = malloc_thing(x509cert_t);
+
+ *cert = empty_x509cert;
+
+ if (parse_x509cert(blob, parser->get_level(parser)+1, cert)
+ && cert->isOcspSigner
+ && trust_authcert_candidate(cert, NULL))
+ {
+ add_authcert(cert, AUTH_OCSP);
+ }
+ else
+ {
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log("embedded ocsp certificate rejected")
+ )
+ free_x509cert(cert);
+ }
+ }
+ break;
}
- }
- break;
}
- objectID++;
- }
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+
}
-/*
- * parse an ocsp response and return the result as a response_t struct
+/**
+ * Parse an ocsp response and return the result as a response_t struct
*/
-static response_status
-parse_ocsp_response(chunk_t blob, response_t * res)
+static response_status parse_ocsp_response(chunk_t blob, response_t * res)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int ocspResponseType = OID_UNKNOWN;
- response_status rStatus = STATUS_INTERNALERROR;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
- while (objectID < OCSP_RESPONSE_ROOF)
- {
- if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
- return STATUS_INTERNALERROR;
-
- switch (objectID) {
- case OCSP_RESPONSE_STATUS:
- rStatus = (response_status) *object.ptr;
-
- switch (rStatus)
- {
- case STATUS_SUCCESSFUL:
- break;
- case STATUS_MALFORMEDREQUEST:
- case STATUS_INTERNALERROR:
- case STATUS_TRYLATER:
- case STATUS_SIGREQUIRED:
- case STATUS_UNAUTHORIZED:
- plog("ocsp response: server said '%s'"
- , response_status_names[rStatus]);
- return rStatus;
- default:
- return STATUS_INTERNALERROR;
- }
- break;
- case OCSP_RESPONSE_TYPE:
- ocspResponseType = known_oid(object);
- break;
- case OCSP_RESPONSE:
- {
- switch (ocspResponseType) {
- case OID_BASIC:
- if (!parse_basic_ocsp_response(object, level+1, res))
- return STATUS_INTERNALERROR;
- break;
- default:
- DBG(DBG_CONTROL,
- DBG_log("ocsp response is not of type BASIC");
- DBG_dump_chunk("ocsp response OID: ", object);
- )
- return STATUS_INTERNALERROR;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int ocspResponseType = OID_UNKNOWN;
+ bool success = FALSE;
+ response_status rStatus = STATUS_INTERNALERROR;
+
+ parser = asn1_parser_create(ocspResponseObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID) {
+ case OCSP_RESPONSE_STATUS:
+ rStatus = (response_status) *object.ptr;
+
+ switch (rStatus)
+ {
+ case STATUS_SUCCESSFUL:
+ break;
+ case STATUS_MALFORMEDREQUEST:
+ case STATUS_INTERNALERROR:
+ case STATUS_TRYLATER:
+ case STATUS_SIGREQUIRED:
+ case STATUS_UNAUTHORIZED:
+ plog("ocsp response: server said '%s'"
+ , response_status_names[rStatus]);
+ goto end;
+ default:
+ goto end;
+ }
+ break;
+ case OCSP_RESPONSE_TYPE:
+ ocspResponseType = asn1_known_oid(object);
+ break;
+ case OCSP_RESPONSE:
+ {
+ switch (ocspResponseType) {
+ case OID_BASIC:
+ success = parse_basic_ocsp_response(object,
+ parser->get_level(parser)+1, res);
+ break;
+ default:
+ DBG(DBG_CONTROL,
+ DBG_log("ocsp response is not of type BASIC");
+ DBG_dump_chunk("ocsp response OID: ", object);
+ )
+ goto end;
+ }
+ }
+ break;
}
- }
- break;
}
- objectID++;
- }
- return rStatus;
+ success &= parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return rStatus;
}
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
*/
-static bool
-parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
+static bool parse_ocsp_single_response(chunk_t blob, int level0,
+ single_response_t *sres)
{
- u_int level, extn_oid;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ asn1_parser_t *parser;
+ chunk_t object;
+ u_int extn_oid;
+ int objectID;
+ bool critical;
+ bool success = FALSE;
- while (objectID < SINGLE_RESPONSE_ROOF)
- {
- if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
+ parser = asn1_parser_create(singleResponseObjects, blob);
+ parser->set_top_level(parser, level0);
- switch (objectID)
+ while (parser->iterate(parser, &objectID, &object))
{
- case SINGLE_RESPONSE_ALGORITHM:
- sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case SINGLE_RESPONSE_ISSUER_NAME_HASH:
- sres->issuer_name_hash = object;
- break;
- case SINGLE_RESPONSE_ISSUER_KEY_HASH:
- sres->issuer_key_hash = object;
- break;
- case SINGLE_RESPONSE_SERIAL_NUMBER:
- sres->serialNumber = object;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_GOOD:
- sres->status = CERT_GOOD;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
- sres->status = CERT_REVOKED;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
- sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
- sres->revocationReason = (object.len == 1)
- ? *object.ptr : REASON_UNSPECIFIED;
- break;
- case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
- sres->status = CERT_UNKNOWN;
- break;
- case SINGLE_RESPONSE_THIS_UPDATE:
- sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_NEXT_UPDATE:
- sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case SINGLE_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case SINGLE_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- case SINGLE_RESPONSE_EXT_VALUE:
- break;
+ switch (objectID)
+ {
+ case SINGLE_RESPONSE_ALGORITHM:
+ sres->hash_algorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
+ break;
+ case SINGLE_RESPONSE_ISSUER_NAME_HASH:
+ sres->issuer_name_hash = object;
+ break;
+ case SINGLE_RESPONSE_ISSUER_KEY_HASH:
+ sres->issuer_key_hash = object;
+ break;
+ case SINGLE_RESPONSE_SERIAL_NUMBER:
+ sres->serialNumber = object;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_GOOD:
+ sres->status = CERT_GOOD;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
+ sres->status = CERT_REVOKED;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
+ sres->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
+ sres->revocationReason = (object.len == 1)
+ ? *object.ptr : REASON_UNSPECIFIED;
+ break;
+ case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
+ sres->status = CERT_UNKNOWN;
+ break;
+ case SINGLE_RESPONSE_THIS_UPDATE:
+ sres->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_NEXT_UPDATE:
+ sres->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
+ break;
+ case SINGLE_RESPONSE_EXT_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case SINGLE_RESPONSE_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(critical)?"TRUE":"FALSE");
+ )
+ case SINGLE_RESPONSE_EXT_VALUE:
+ break;
+ }
}
- objectID++;
- }
- return TRUE;
+ success = parser->success(parser);
+ parser->destroy(parser);
+ return success;
}
-/*
- * add an ocsp location to a chained list
+/**
+ * Add an ocsp location to a chained list
*/
-ocsp_location_t*
-add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
+ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc,
+ ocsp_location_t **chain)
{
- ocsp_location_t *location = alloc_thing(ocsp_location_t, "ocsp location");
-
- /* unshare location fields */
- clonetochunk(location->issuer
- , loc->issuer.ptr, loc->issuer.len
- , "ocsp issuer");
-
- clonetochunk(location->authNameID
- , loc->authNameID.ptr, loc->authNameID.len
- , "ocsp authNameID");
-
- if (loc->authKeyID.ptr == NULL)
- location->authKeyID = empty_chunk;
- else
- clonetochunk(location->authKeyID
- , loc->authKeyID.ptr, loc->authKeyID.len
- , "ocsp authKeyID");
-
- if (loc->authKeySerialNumber.ptr == NULL)
- location->authKeySerialNumber = empty_chunk;
- else
- clonetochunk(location->authKeySerialNumber
- , loc->authKeySerialNumber.ptr, loc->authKeySerialNumber.len
- , "ocsp authKeySerialNumber");
-
- clonetochunk(location->uri
- , loc->uri.ptr, loc->uri.len
- , "ocsp uri");
-
- location->certinfo = NULL;
-
- /* insert new ocsp location in front of chain */
- location->next = *chain;
- *chain = location;
-
- DBG(DBG_CONTROL,
- DBG_log("new ocsp location added")
- )
-
- return location;
+ ocsp_location_t *location = malloc_thing(ocsp_location_t);
+
+ /* unshare location fields */
+ location->issuer = chunk_clone(loc->issuer);
+ location->authNameID = chunk_clone(loc->authNameID);
+ location->authKeyID = chunk_clone(loc->authKeyID);
+ location->authKeySerialNumber = chunk_clone(loc->authKeySerialNumber);
+ location->uri = chunk_clone(loc->uri);
+ location->certinfo = NULL;
+
+ /* insert new ocsp location in front of chain */
+ location->next = *chain;
+ *chain = location;
+
+ DBG(DBG_CONTROL,
+ DBG_log("new ocsp location added")
+ )
+
+ return location;
}
-/*
+/**
* add a certinfo struct to a chained list
*/
-void
-add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chain
- , bool request)
+void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info,
+ ocsp_location_t **chain, bool request)
{
- ocsp_location_t *location;
- ocsp_certinfo_t *certinfo, **certinfop;
- char buf[BUF_LEN];
- time_t now;
- int cmp = -1;
-
- location = get_ocsp_location(loc, *chain);
- if (location == NULL)
- location = add_ocsp_location(loc, chain);
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
-
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(info->serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
+ ocsp_location_t *location;
+ ocsp_certinfo_t *certinfo, **certinfop;
+ char buf[BUF_LEN];
+ time_t now;
+ int cmp = -1;
+
+ location = get_ocsp_location(loc, *chain);
+ if (location == NULL)
+ {
+ location = add_ocsp_location(loc, chain);
+ }
+
+ /* traverse list of certinfos in increasing order */
+ certinfop = &location->certinfo;
certinfo = *certinfop;
- }
-
- if (cmp != 0)
- {
- /* add a new certinfo entry */
- ocsp_certinfo_t *cnew = alloc_thing(ocsp_certinfo_t, "ocsp certinfo");
- clonetochunk(cnew->serialNumber, info->serialNumber.ptr
- , info->serialNumber.len, "serialNumber");
- cnew->next = certinfo;
- *certinfop = cnew;
- certinfo = cnew;
- }
-
- DBG(DBG_CONTROL,
- datatot(info->serialNumber.ptr, info->serialNumber.len, ':'
- , buf, BUF_LEN);
- DBG_log("ocsp %s for serial %s %s"
- , request?"fetch request":"certinfo"
- , buf
- , (cmp == 0)? (request?"already exists":"updated"):"added")
- )
-
- time(&now);
-
- if (request)
- {
- certinfo->status = CERT_UNDEFINED;
-
+
+ while (certinfo != NULL)
+ {
+ cmp = chunk_compare(info->serialNumber, certinfo->serialNumber);
+ if (cmp <= 0)
+ break;
+ certinfop = &certinfo->next;
+ certinfo = *certinfop;
+ }
+
if (cmp != 0)
- certinfo->thisUpdate = now;
-
- certinfo->nextUpdate = UNDEFINED_TIME;
- }
- else
- {
- certinfo->status = info->status;
- certinfo->revocationTime = info->revocationTime;
- certinfo->revocationReason = info->revocationReason;
-
- certinfo->thisUpdate = (info->thisUpdate != UNDEFINED_TIME)?
- info->thisUpdate : now;
+ {
+ /* add a new certinfo entry */
+ ocsp_certinfo_t *cnew = malloc_thing(ocsp_certinfo_t);
+
+ cnew->serialNumber = chunk_clone(info->serialNumber);
+ cnew->next = certinfo;
+ *certinfop = cnew;
+ certinfo = cnew;
+ }
+
+ DBG(DBG_CONTROL,
+ datatot(info->serialNumber.ptr, info->serialNumber.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("ocsp %s for serial %s %s"
+ , request?"fetch request":"certinfo"
+ , buf
+ , (cmp == 0)? (request?"already exists":"updated"):"added")
+ )
+
+ time(&now);
+
+ if (request)
+ {
+ certinfo->status = CERT_UNDEFINED;
+
+ if (cmp != 0)
+ {
+ certinfo->thisUpdate = now;
+ }
+ certinfo->nextUpdate = UNDEFINED_TIME;
+ }
+ else
+ {
+ certinfo->status = info->status;
+ certinfo->revocationTime = info->revocationTime;
+ certinfo->revocationReason = info->revocationReason;
+
+ certinfo->thisUpdate = (info->thisUpdate != UNDEFINED_TIME)?
+ info->thisUpdate : now;
- certinfo->once = (info->nextUpdate == UNDEFINED_TIME);
+ certinfo->once = (info->nextUpdate == UNDEFINED_TIME);
- certinfo->nextUpdate = (certinfo->once)?
- (now + OCSP_DEFAULT_VALID_TIME) : info->nextUpdate;
- }
+ certinfo->nextUpdate = (certinfo->once)?
+ (now + OCSP_DEFAULT_VALID_TIME) : info->nextUpdate;
+ }
}
-/*
- * process received ocsp single response and add it to ocsp cache
+/**
+ * Process received ocsp single response and add it to ocsp cache
*/
-static void
-process_single_response(ocsp_location_t *location, single_response_t *sres)
+static void process_single_response(ocsp_location_t *location,
+ single_response_t *sres)
{
- ocsp_certinfo_t *certinfo, **certinfop;
- int cmp = -1;
-
- if (sres->hash_algorithm != OID_SHA1)
- {
- plog("only SHA-1 hash supported in OCSP single response");
- return;
- }
- if (!(same_chunk(sres->issuer_name_hash, location->authNameID)
- && same_chunk(sres->issuer_key_hash, location->authKeyID)))
- {
- plog("ocsp single response has wrong issuer");
- return;
- }
-
- /* traverse list of certinfos in increasing order */
- certinfop = &location->certinfo;
- certinfo = *certinfop;
-
- while (certinfo != NULL)
- {
- cmp = cmp_chunk(sres->serialNumber, certinfo->serialNumber);
- if (cmp <= 0)
- break;
- certinfop = &certinfo->next;
+ ocsp_certinfo_t *certinfo, **certinfop;
+ int cmp = -1;
+
+ if (sres->hash_algorithm != OID_SHA1)
+ {
+ plog("only SHA-1 hash supported in OCSP single response");
+ return;
+ }
+ if (!(chunk_equals(sres->issuer_name_hash, location->authNameID)
+ && chunk_equals(sres->issuer_key_hash, location->authKeyID)))
+ {
+ plog("ocsp single response has wrong issuer");
+ return;
+ }
+
+ /* traverse list of certinfos in increasing order */
+ certinfop = &location->certinfo;
certinfo = *certinfop;
- }
-
- if (cmp != 0)
- {
- plog("received unrequested cert status from ocsp server");
- return;
- }
-
- /* unlink cert from ocsp fetch request list */
- *certinfop = certinfo->next;
-
- /* update certinfo using the single response information */
- certinfo->thisUpdate = sres->thisUpdate;
- certinfo->nextUpdate = sres->nextUpdate;
- certinfo->status = sres->status;
- certinfo->revocationTime = sres->revocationTime;
- certinfo->revocationReason = sres->revocationReason;
-
- /* add or update certinfo in ocsp cache */
- lock_ocsp_cache("process_single_response");
- add_certinfo(location, certinfo, &ocsp_cache, FALSE);
- unlock_ocsp_cache("process_single_response");
-
- /* free certinfo unlinked from ocsp fetch request list */
- free_certinfo(certinfo);
+ while (certinfo != NULL)
+ {
+ cmp = chunk_compare(sres->serialNumber, certinfo->serialNumber);
+ if (cmp <= 0)
+ break;
+ certinfop = &certinfo->next;
+ certinfo = *certinfop;
+ }
+
+ if (cmp != 0)
+ {
+ plog("received unrequested cert status from ocsp server");
+ return;
+ }
+
+ /* unlink cert from ocsp fetch request list */
+ *certinfop = certinfo->next;
+
+ /* update certinfo using the single response information */
+ certinfo->thisUpdate = sres->thisUpdate;
+ certinfo->nextUpdate = sres->nextUpdate;
+ certinfo->status = sres->status;
+ certinfo->revocationTime = sres->revocationTime;
+ certinfo->revocationReason = sres->revocationReason;
+
+ /* add or update certinfo in ocsp cache */
+ lock_ocsp_cache("process_single_response");
+ add_certinfo(location, certinfo, &ocsp_cache, FALSE);
+ unlock_ocsp_cache("process_single_response");
+
+ /* free certinfo unlinked from ocsp fetch request list */
+ free_certinfo(certinfo);
}
-/*
- * parse and verify ocsp response and update the ocsp cache
+/**
+ * Parse and verify ocsp response and update the ocsp cache
*/
-void
-parse_ocsp(ocsp_location_t *location, chunk_t blob)
+void parse_ocsp(ocsp_location_t *location, chunk_t blob)
{
- response_t res = empty_response;
-
- /* parse the ocsp response without looking at the single responses yet */
- response_status status = parse_ocsp_response(blob, &res);
-
- if (status != STATUS_SUCCESSFUL)
- {
- plog("error in ocsp response");
- return;
- }
- /* check if there was a nonce in the request */
- if (location->nonce.ptr != NULL && res.nonce.ptr == NULL)
- {
- plog("ocsp response contains no nonce, replay attack possible");
- }
- /* check if the nonce is identical */
- if (res.nonce.ptr != NULL && !same_chunk(res.nonce, location->nonce))
- {
- plog("invalid nonce in ocsp response");
- return;
- }
- /* check if the response is signed by a trusted key */
- if (!valid_ocsp_response(&res))
- {
- plog("invalid ocsp response");
- return;
- }
- DBG(DBG_CONTROL,
- DBG_log("valid ocsp response")
- )
-
- /* now parse the single responses one at a time */
- {
- u_int level;
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
+ response_t res = empty_response;
- asn1_init(&ctx, res.responses, 0, FALSE, DBG_RAW);
+ /* parse the ocsp response without looking at the single responses yet */
+ response_status status = parse_ocsp_response(blob, &res);
- while (objectID < RESPONSES_ROOF)
+ if (status != STATUS_SUCCESSFUL)
+ {
+ plog("error in ocsp response");
+ return;
+ }
+ /* check if there was a nonce in the request */
+ if (location->nonce.ptr != NULL && res.nonce.ptr == NULL)
+ {
+ plog("ocsp response contains no nonce, replay attack possible");
+ }
+ /* check if the nonce is identical */
+ if (res.nonce.ptr != NULL && !chunk_equals(res.nonce, location->nonce))
+ {
+ plog("invalid nonce in ocsp response");
+ return;
+ }
+ /* check if the response is signed by a trusted key */
+ if (!valid_ocsp_response(&res))
{
- if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
+ plog("invalid ocsp response");
return;
-
- if (objectID == RESPONSES_SINGLE_RESPONSE)
- {
- single_response_t sres = empty_single_response;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("valid ocsp response")
+ )
- if (parse_ocsp_single_response(object, level+1, &sres))
+ /* now parse the single responses one at a time */
+ {
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(responsesObjects, res.responses);
+
+ while (parser->iterate(parser, &objectID, &object))
{
- process_single_response(location, &sres);
+ if (objectID == RESPONSES_SINGLE_RESPONSE)
+ {
+ single_response_t sres = empty_single_response;
+
+ if (!parse_ocsp_single_response(object,
+ parser->get_level(parser)+1, &sres))
+ {
+ goto end;
+ }
+ process_single_response(location, &sres);
+ }
}
- }
- objectID++;
+end:
+ parser->destroy(parser);
}
- }
}
diff --git a/src/pluto/ocsp.h b/src/pluto/ocsp.h
index 6bf42831b..d8ee7bd8c 100644
--- a/src/pluto/ocsp.h
+++ b/src/pluto/ocsp.h
@@ -11,27 +11,25 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: ocsp.h 3253 2007-10-06 21:39:00Z andreas $
*/
#include "constants.h"
/* constants */
-#define OCSP_BASIC_RESPONSE_VERSION 1
-#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
-#define OCSP_WARNING_INTERVAL 2 /* days */
+#define OCSP_BASIC_RESPONSE_VERSION 1
+#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
+#define OCSP_WARNING_INTERVAL 2 /* days */
/* OCSP response status */
typedef enum {
- STATUS_SUCCESSFUL = 0,
- STATUS_MALFORMEDREQUEST = 1,
- STATUS_INTERNALERROR = 2,
- STATUS_TRYLATER = 3,
- STATUS_SIGREQUIRED = 5,
- STATUS_UNAUTHORIZED= 6
+ STATUS_SUCCESSFUL = 0,
+ STATUS_MALFORMEDREQUEST = 1,
+ STATUS_INTERNALERROR = 2,
+ STATUS_TRYLATER = 3,
+ STATUS_SIGREQUIRED = 5,
+ STATUS_UNAUTHORIZED= 6
} response_status;
/* OCSP access structures */
@@ -39,46 +37,46 @@ typedef enum {
typedef struct ocsp_certinfo ocsp_certinfo_t;
struct ocsp_certinfo {
- ocsp_certinfo_t *next;
- int trials;
- chunk_t serialNumber;
- cert_status_t status;
- bool once;
- crl_reason_t revocationReason;
- time_t revocationTime;
- time_t thisUpdate;
- time_t nextUpdate;
+ ocsp_certinfo_t *next;
+ int trials;
+ chunk_t serialNumber;
+ cert_status_t status;
+ bool once;
+ crl_reason_t revocationReason;
+ time_t revocationTime;
+ time_t thisUpdate;
+ time_t nextUpdate;
};
typedef struct ocsp_location ocsp_location_t;
struct ocsp_location {
- ocsp_location_t *next;
- chunk_t issuer;
- chunk_t authNameID;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- chunk_t uri;
- chunk_t nonce;
- ocsp_certinfo_t *certinfo;
+ ocsp_location_t *next;
+ chunk_t issuer;
+ chunk_t authNameID;
+ chunk_t authKeyID;
+ chunk_t authKeySerialNumber;
+ chunk_t uri;
+ chunk_t nonce;
+ ocsp_certinfo_t *certinfo;
};
extern ocsp_location_t* get_ocsp_location(const ocsp_location_t *loc
- , ocsp_location_t *chain);
+ , ocsp_location_t *chain);
extern ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc
- , ocsp_location_t **chain);
+ , ocsp_location_t **chain);
extern void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info
- , ocsp_location_t **chain, bool request);
+ , ocsp_location_t **chain, bool request);
extern void check_ocsp(void);
extern cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until
- , time_t *revocationTime, crl_reason_t *revocationReason);
+ , time_t *revocationTime, crl_reason_t *revocationReason);
extern bool ocsp_set_request_cert(char* path);
extern void ocsp_set_default_uri(char* uri);
extern void ocsp_cache_add_cert(const x509cert_t* cert);
extern chunk_t build_ocsp_request(ocsp_location_t* location);
extern void parse_ocsp(ocsp_location_t* location, chunk_t blob);
extern void list_ocsp_locations(ocsp_location_t *location, bool requests
- , bool utc, bool strict);
+ , bool utc, bool strict);
extern void list_ocsp_cache(bool utc, bool strict);
extern void free_ocsp_locations(ocsp_location_t **chain);
extern void free_ocsp_cache(void);
diff --git a/src/pluto/packet.c b/src/pluto/packet.c
index e8a3a1e11..01967efed 100644
--- a/src/pluto/packet.c
+++ b/src/pluto/packet.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: packet.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include "defs.h"
#include "log.h"
#include "packet.h"
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "whack.h" /* for RC_LOG_SERIOUS */
/* ISAKMP Header: for all messages
* layout from RFC 2408 "ISAKMP" section 3.1
@@ -49,15 +47,15 @@
*/
static field_desc isa_fields[] = {
- { ft_raw, COOKIE_SIZE, "initiator cookie", NULL },
- { ft_raw, COOKIE_SIZE, "responder cookie", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names },
- { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names },
- { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names },
- { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL },
- { ft_len, 32/BITS_PER_BYTE, "length", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_raw, COOKIE_SIZE, "initiator cookie", NULL },
+ { ft_raw, COOKIE_SIZE, "responder cookie", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_enum, 8/BITS_PER_BYTE, "ISAKMP version", &version_names },
+ { ft_enum, 8/BITS_PER_BYTE, "exchange type", &exchange_names },
+ { ft_set, 8/BITS_PER_BYTE, "flags", flag_bit_names },
+ { ft_raw, 32/BITS_PER_BYTE, "message ID", NULL },
+ { ft_len, 32/BITS_PER_BYTE, "length", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isakmp_hdr) };
@@ -74,10 +72,10 @@ struct_desc isakmp_hdr_desc = { "ISAKMP Message", isa_fields, sizeof(struct isak
*/
static field_desc isag_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeof(struct isakmp_generic) };
@@ -100,36 +98,36 @@ struct_desc isakmp_generic_desc = { "ISAKMP Generic Payload", isag_fields, sizeo
/* Oakley Attributes */
static field_desc isaat_fields_oakley[] = {
- { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &oakley_attr_names },
+ { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_oakley_attribute_desc = {
- "ISAKMP Oakley attribute",
- isaat_fields_oakley, sizeof(struct isakmp_attribute) };
+ "ISAKMP Oakley attribute",
+ isaat_fields_oakley, sizeof(struct isakmp_attribute) };
/* IPsec DOI Attributes */
static field_desc isaat_fields_ipsec[] = {
- { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_af_enum, 16/BITS_PER_BYTE, "af+type", &ipsec_attr_names },
+ { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_ipsec_attribute_desc = {
- "ISAKMP IPsec DOI attribute",
- isaat_fields_ipsec, sizeof(struct isakmp_attribute) };
+ "ISAKMP IPsec DOI attribute",
+ isaat_fields_ipsec, sizeof(struct isakmp_attribute) };
/* Mode Config Attributes */
static field_desc isaat_fields_modecfg[] = {
- { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names },
- { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_af_loose_enum, 16/BITS_PER_BYTE, "ModeCfg attr type", &modecfg_attr_names },
+ { ft_lv, 16/BITS_PER_BYTE, "length/value", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_modecfg_attribute_desc = {
- "ISAKMP ModeCfg attribute",
- isaat_fields_modecfg, sizeof(struct isakmp_attribute) };
+ "ISAKMP ModeCfg attribute",
+ isaat_fields_modecfg, sizeof(struct isakmp_attribute) };
/* ISAKMP Security Association Payload
* layout from RFC 2408 "ISAKMP" section 3.4
@@ -148,18 +146,18 @@ struct_desc isakmp_modecfg_attribute_desc = {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isasa_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_sa_desc = { "ISAKMP Security Association Payload", isasa_fields, sizeof(struct isakmp_sa) };
static field_desc ipsec_sit_field[] = {
- { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names },
- { ft_end, 0, NULL, NULL }
+ { ft_set, 32/BITS_PER_BYTE, "IPsec DOI SIT", &sit_bit_names },
+ { ft_end, 0, NULL, NULL }
};
struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_t) };
@@ -179,14 +177,14 @@ struct_desc ipsec_sit_desc = { "IPsec DOI SIT", ipsec_sit_field, sizeof(u_int32_
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isap_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names },
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "proposal number", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "protocol ID", &protocol_names },
+ { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "number of transforms", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, sizeof(struct isakmp_proposal) };
@@ -210,63 +208,63 @@ struct_desc isakmp_proposal_desc = { "ISAKMP Proposal Payload", isap_fields, siz
/* PROTO_ISAKMP */
static field_desc isat_fields_isakmp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "transform ID", &isakmp_transformid_names },
+ { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_isakmp_transform_desc = {
- "ISAKMP Transform Payload (ISAKMP)",
- isat_fields_isakmp, sizeof(struct isakmp_transform) };
+ "ISAKMP Transform Payload (ISAKMP)",
+ isat_fields_isakmp, sizeof(struct isakmp_transform) };
/* PROTO_IPSEC_AH */
static field_desc isat_fields_ah[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ah_transformid_names },
+ { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_ah_transform_desc = {
- "ISAKMP Transform Payload (AH)",
- isat_fields_ah, sizeof(struct isakmp_transform) };
+ "ISAKMP Transform Payload (AH)",
+ isat_fields_ah, sizeof(struct isakmp_transform) };
/* PROTO_IPSEC_ESP */
static field_desc isat_fields_esp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "transform ID", &esp_transformid_names },
+ { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_esp_transform_desc = {
- "ISAKMP Transform Payload (ESP)",
- isat_fields_esp, sizeof(struct isakmp_transform) };
+ "ISAKMP Transform Payload (ESP)",
+ isat_fields_esp, sizeof(struct isakmp_transform) };
/* PROTO_IPCOMP */
static field_desc isat_fields_ipcomp[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names },
- { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_nat, 8/BITS_PER_BYTE, "transform number", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "transform ID", &ipcomp_transformid_names },
+ { ft_mbz, 16/BITS_PER_BYTE, NULL, NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_ipcomp_transform_desc = {
- "ISAKMP Transform Payload (COMP)",
- isat_fields_ipcomp, sizeof(struct isakmp_transform) };
+ "ISAKMP Transform Payload (COMP)",
+ isat_fields_ipcomp, sizeof(struct isakmp_transform) };
/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
@@ -303,13 +301,13 @@ struct_desc isakmp_keyex_desc = { "ISAKMP Key Exchange Payload", isag_fields, si
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isaid_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, /* ??? depends on DOI? */
- { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL }, /* ??? depends on DOI? */
- { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL }, /* ??? depends on DOI? */
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names }, /* ??? depends on DOI? */
+ { ft_nat, 8/BITS_PER_BYTE, "DOI specific A", NULL }, /* ??? depends on DOI? */
+ { ft_nat, 16/BITS_PER_BYTE, "DOI specific B", NULL }, /* ??? depends on DOI? */
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isaid_fields, sizeof(struct isakmp_id) };
@@ -330,13 +328,13 @@ struct_desc isakmp_identification_desc = { "ISAKMP Identification Payload", isai
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isaiid_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
- { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL }, /* ??? UDP/TCP or 0? */
- { ft_nat, 16/BITS_PER_BYTE, "port", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
+ { ft_nat, 8/BITS_PER_BYTE, "Protocol ID", NULL }, /* ??? UDP/TCP or 0? */
+ { ft_nat, 16/BITS_PER_BYTE, "port", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload (IPsec DOI)", isaiid_fields, sizeof(struct isakmp_ipsec_id) };
@@ -357,11 +355,11 @@ struct_desc isakmp_ipsec_identification_desc = { "ISAKMP Identification Payload
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isacert_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "cert encoding", &cert_type_names },
+ { ft_end, 0, NULL, NULL }
};
/* Note: the size field of isakmp_ipsec_certificate_desc cannot be
@@ -385,11 +383,11 @@ static field_desc isacert_fields[] = {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isacr_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "cert type", &cert_type_names },
+ { ft_end, 0, NULL, NULL }
};
/* Note: the size field of isakmp_ipsec_cert_req_desc cannot be
@@ -469,14 +467,14 @@ struct_desc isakmp_nonce_desc = { "ISAKMP Nonce Payload", isag_fields, sizeof(st
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isan_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC, ESP, ... */
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", &notification_names },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
+ { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC, ESP, ... */
+ { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
+ { ft_enum, 16/BITS_PER_BYTE, "Notify Message Type", &notification_names },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fields, sizeof(struct isakmp_notification) };
@@ -500,14 +498,14 @@ struct_desc isakmp_notification_desc = { "ISAKMP Notification Payload", isan_fie
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isad_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
- { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC */
- { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
- { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 32/BITS_PER_BYTE, "DOI", &doi_names },
+ { ft_nat, 8/BITS_PER_BYTE, "protocol ID", NULL }, /* ??? really enum: ISAKMP, IPSEC */
+ { ft_nat, 8/BITS_PER_BYTE, "SPI size", NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "number of SPIs", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_delete_desc = { "ISAKMP Delete Payload", isad_fields, sizeof(struct isakmp_delete) };
@@ -532,26 +530,26 @@ struct_desc isakmp_vendor_id_desc = { "ISAKMP Vendor ID Payload", isag_fields, s
/*
* From draft-dukes-ike-mode-cfg
3.2. Attribute Payload
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Next Payload ! RESERVED ! Payload Length !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Type ! RESERVED ! Identifier !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! !
- ~ Attributes ~
- ! !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Type ! RESERVED ! Identifier !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! !
+ ~ Attributes ~
+ ! !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isaattr_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "Attr Msg Type", &attr_msg_type_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_nat, 16/BITS_PER_BYTE, "Identifier", NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_attr_desc = { "ISAKMP Mode Attribute", isaattr_fields, sizeof(struct isakmp_mode_attr) };
@@ -581,12 +579,12 @@ struct_desc isakmp_nat_d = { "ISAKMP NAT-D Payload", isag_fields, sizeof(struct
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static field_desc isanat_oa_fields[] = {
- { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
- { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
- { ft_len, 16/BITS_PER_BYTE, "length", NULL },
- { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
- { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL },
- { ft_end, 0, NULL, NULL }
+ { ft_enum, 8/BITS_PER_BYTE, "next payload type", &payload_names },
+ { ft_mbz, 8/BITS_PER_BYTE, NULL, NULL },
+ { ft_len, 16/BITS_PER_BYTE, "length", NULL },
+ { ft_enum, 8/BITS_PER_BYTE, "ID type", &ident_names },
+ { ft_mbz, 24/BITS_PER_BYTE, NULL, NULL },
+ { ft_end, 0, NULL, NULL }
};
struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof(struct isakmp_nat_oa) };
@@ -600,40 +598,40 @@ struct_desc isakmp_nat_oa = { "ISAKMP NAT-OA Payload", isanat_oa_fields, sizeof(
* We make all these entries NULL
*/
struct_desc *const payload_descs[ISAKMP_NEXT_ROOF] = {
- NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */
- &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */
- NULL, /* 2 ISAKMP_NEXT_P (Proposal) */
- NULL, /* 3 ISAKMP_NEXT_T (Transform) */
- &isakmp_keyex_desc, /* 4 ISAKMP_NEXT_KE (Key Exchange) */
- NULL, /* 5 ISAKMP_NEXT_ID (Identification) */
- &isakmp_ipsec_certificate_desc, /* 6 ISAKMP_NEXT_CERT (Certificate) */
- &isakmp_ipsec_cert_req_desc, /* 7 ISAKMP_NEXT_CR (Certificate Request) */
- &isakmp_hash_desc, /* 8 ISAKMP_NEXT_HASH (Hash) */
- &isakmp_signature_desc, /* 9 ISAKMP_NEXT_SIG (Signature) */
- &isakmp_nonce_desc, /* 10 ISAKMP_NEXT_NONCE (Nonce) */
- &isakmp_notification_desc, /* 11 ISAKMP_NEXT_N (Notification) */
- &isakmp_delete_desc, /* 12 ISAKMP_NEXT_D (Delete) */
- &isakmp_vendor_id_desc, /* 13 ISAKMP_NEXT_VID (Vendor ID) */
- &isakmp_attr_desc, /* 14 ISAKMP_NEXT_ATTR (Mode Config) */
- NULL, /* 15 */
- NULL, /* 16 */
- NULL, /* 17 */
- NULL, /* 18 */
- NULL, /* 19 */
- &isakmp_nat_d, /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */
- &isakmp_nat_oa, /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */
+ NULL, /* 0 ISAKMP_NEXT_NONE (No other payload following) */
+ &isakmp_sa_desc, /* 1 ISAKMP_NEXT_SA (Security Association) */
+ NULL, /* 2 ISAKMP_NEXT_P (Proposal) */
+ NULL, /* 3 ISAKMP_NEXT_T (Transform) */
+ &isakmp_keyex_desc, /* 4 ISAKMP_NEXT_KE (Key Exchange) */
+ NULL, /* 5 ISAKMP_NEXT_ID (Identification) */
+ &isakmp_ipsec_certificate_desc, /* 6 ISAKMP_NEXT_CERT (Certificate) */
+ &isakmp_ipsec_cert_req_desc, /* 7 ISAKMP_NEXT_CR (Certificate Request) */
+ &isakmp_hash_desc, /* 8 ISAKMP_NEXT_HASH (Hash) */
+ &isakmp_signature_desc, /* 9 ISAKMP_NEXT_SIG (Signature) */
+ &isakmp_nonce_desc, /* 10 ISAKMP_NEXT_NONCE (Nonce) */
+ &isakmp_notification_desc, /* 11 ISAKMP_NEXT_N (Notification) */
+ &isakmp_delete_desc, /* 12 ISAKMP_NEXT_D (Delete) */
+ &isakmp_vendor_id_desc, /* 13 ISAKMP_NEXT_VID (Vendor ID) */
+ &isakmp_attr_desc, /* 14 ISAKMP_NEXT_ATTR (Mode Config) */
+ NULL, /* 15 */
+ NULL, /* 16 */
+ NULL, /* 17 */
+ NULL, /* 18 */
+ NULL, /* 19 */
+ &isakmp_nat_d, /* 20=130 ISAKMP_NEXT_NATD (NAT-D) */
+ &isakmp_nat_oa, /* 20=131 ISAKMP_NEXT_NATOA (NAT-OA) */
};
void
init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name)
{
- pbs->container = NULL;
- pbs->desc = NULL;
- pbs->name = name;
- pbs->start = pbs->cur = start;
- pbs->roof = start + len;
- pbs->lenfld = NULL;
- pbs->lenfld_desc = NULL;
+ pbs->container = NULL;
+ pbs->desc = NULL;
+ pbs->name = name;
+ pbs->start = pbs->cur = start;
+ pbs->roof = start + len;
+ pbs->lenfld = NULL;
+ pbs->lenfld_desc = NULL;
}
#ifdef DEBUG
@@ -648,85 +646,85 @@ void
DBG_print_struct(const char *label, const void *struct_ptr
, struct_desc *sd, bool len_meaningful)
{
- bool immediate = FALSE;
- const u_int8_t *inp = struct_ptr;
- field_desc *fp;
-
- DBG_log("%s%s:", label, sd->name);
+ bool immediate = FALSE;
+ const u_int8_t *inp = struct_ptr;
+ field_desc *fp;
- for (fp = sd->fields; fp->field_type != ft_end; fp++)
- {
- int i = fp->size;
- u_int32_t n = 0;
+ DBG_log("%s%s:", label, sd->name);
- switch (fp->field_type)
+ for (fp = sd->fields; fp->field_type != ft_end; fp++)
{
- case ft_mbz: /* must be zero */
- inp += i;
- break;
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- switch (i)
- {
- case 8/BITS_PER_BYTE:
- n = *(const u_int8_t *)inp;
- break;
- case 16/BITS_PER_BYTE:
- n = *(const u_int16_t *)inp;
- break;
- case 32/BITS_PER_BYTE:
- n = *(const u_int32_t *)inp;
- break;
- default:
- bad_case(i);
- }
- switch (fp->field_type)
- {
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- if (!immediate && !len_meaningful)
- break;
- /* FALL THROUGH */
- case ft_nat: /* natural number (may be 0) */
- DBG_log(" %s: %lu", fp->name, (unsigned long)n);
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n));
- break;
- case ft_set: /* bits representing set */
- DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n));
- break;
- default:
- bad_case(fp->field_type);
- }
- inp += i;
- break;
-
- case ft_raw: /* bytes to be left in network-order */
- {
- char m[50]; /* arbitrary limit on name width in log */
-
- snprintf(m, sizeof(m), " %s:", fp->name);
- DBG_dump(m, inp, i);
- inp += i;
- }
- break;
- default:
- bad_case(fp->field_type);
+ int i = fp->size;
+ u_int32_t n = 0;
+
+ switch (fp->field_type)
+ {
+ case ft_mbz: /* must be zero */
+ inp += i;
+ break;
+ case ft_nat: /* natural number (may be 0) */
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ case ft_enum: /* value from an enumeration */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ case ft_set: /* bits representing set */
+ switch (i)
+ {
+ case 8/BITS_PER_BYTE:
+ n = *(const u_int8_t *)inp;
+ break;
+ case 16/BITS_PER_BYTE:
+ n = *(const u_int16_t *)inp;
+ break;
+ case 32/BITS_PER_BYTE:
+ n = *(const u_int32_t *)inp;
+ break;
+ default:
+ bad_case(i);
+ }
+ switch (fp->field_type)
+ {
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ if (!immediate && !len_meaningful)
+ break;
+ /* FALL THROUGH */
+ case ft_nat: /* natural number (may be 0) */
+ DBG_log(" %s: %lu", fp->name, (unsigned long)n);
+ break;
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ immediate = TRUE;
+ /* FALL THROUGH */
+ case ft_enum: /* value from an enumeration */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n));
+ break;
+ case ft_set: /* bits representing set */
+ DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n));
+ break;
+ default:
+ bad_case(fp->field_type);
+ }
+ inp += i;
+ break;
+
+ case ft_raw: /* bytes to be left in network-order */
+ {
+ char m[50]; /* arbitrary limit on name width in log */
+
+ snprintf(m, sizeof(m), " %s:", fp->name);
+ DBG_dump(m, inp, i);
+ inp += i;
+ }
+ break;
+ default:
+ bad_case(fp->field_type);
+ }
}
- }
}
static void
@@ -734,35 +732,35 @@ DBG_prefix_print_struct(const pb_stream *pbs
, const char *label, const void *struct_ptr
, struct_desc *sd, bool len_meaningful)
{
- /* print out a title, with a prefix of asterisks to show
- * the nesting level.
- */
- char space[40]; /* arbitrary limit on label+flock-of-* */
- size_t len = strlen(label);
-
- if (sizeof(space) <= len)
- {
- DBG_print_struct(label, struct_ptr, sd, len_meaningful);
- }
- else
- {
- const pb_stream *p = pbs;
- char *pre = &space[sizeof(space) - (len + 1)];
-
- strcpy(pre, label);
-
- /* put at least one * out */
- for (;;)
+ /* print out a title, with a prefix of asterisks to show
+ * the nesting level.
+ */
+ char space[40]; /* arbitrary limit on label+flock-of-* */
+ size_t len = strlen(label);
+
+ if (sizeof(space) <= len)
+ {
+ DBG_print_struct(label, struct_ptr, sd, len_meaningful);
+ }
+ else
{
- if (pre <= space)
- break;
- *--pre = '*';
- if (p == NULL)
- break;
- p = p->container;
+ const pb_stream *p = pbs;
+ char *pre = &space[sizeof(space) - (len + 1)];
+
+ strcpy(pre, label);
+
+ /* put at least one * out */
+ for (;;)
+ {
+ if (pre <= space)
+ break;
+ *--pre = '*';
+ if (p == NULL)
+ break;
+ p = p->container;
+ }
+ DBG_print_struct(pre, struct_ptr, sd, len_meaningful);
}
- DBG_print_struct(pre, struct_ptr, sd, len_meaningful);
- }
}
#endif
@@ -785,191 +783,191 @@ bool
in_struct(void *struct_ptr, struct_desc *sd
, pb_stream *ins, pb_stream *obj_pbs)
{
- err_t ugh = NULL;
- u_int8_t *cur = ins->cur;
-
- if (ins->roof - cur < (ptrdiff_t)sd->size)
- {
- ugh = builddiag("not enough room in input packet for %s", sd->name);
- }
- else
- {
- u_int8_t *roof = cur + sd->size; /* may be changed by a length field */
- u_int8_t *outp = struct_ptr;
- bool immediate = FALSE;
- field_desc *fp;
+ err_t ugh = NULL;
+ u_int8_t *cur = ins->cur;
- for (fp = sd->fields; ugh == NULL; fp++)
+ if (ins->roof - cur < (ptrdiff_t)sd->size)
{
- size_t i = fp->size;
-
- passert(ins->roof - cur >= (ptrdiff_t)i);
- passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
- passert(outp - (cur - ins->cur) == struct_ptr);
-
-#if 0
- DBG(DBG_PARSING, DBG_log("%d %s"
- , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));
-#endif
- switch (fp->field_type)
- {
- case ft_mbz: /* must be zero */
- for (; i != 0; i--)
- {
- if (*cur++ != 0)
- {
- ugh = builddiag("byte %d of %s must be zero, but is not"
- , (int) (cur - ins->cur), sd->name);
- break;
- }
- *outp++ = '\0'; /* probably redundant */
- }
- break;
-
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- {
- u_int32_t n = 0;
-
- for (; i != 0; i--)
- n = (n << BITS_PER_BYTE) | *cur++;
+ ugh = builddiag("not enough room in input packet for %s", sd->name);
+ }
+ else
+ {
+ u_int8_t *roof = cur + sd->size; /* may be changed by a length field */
+ u_int8_t *outp = struct_ptr;
+ bool immediate = FALSE;
+ field_desc *fp;
- switch (fp->field_type)
- {
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- {
- u_int32_t len = fp->field_type == ft_len? n
- : immediate? sd->size : n + sd->size;
-
- if (len < sd->size)
- {
- ugh = builddiag("%s of %s is smaller than minimum"
- , fp->name, sd->name);
- }
- else if (pbs_left(ins) < len)
- {
- ugh = builddiag("%s of %s is larger than can fit"
- , fp->name, sd->name);
- }
- else
- {
- roof = ins->cur + len;
- }
- break;
- }
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- if (enum_name(fp->desc, n) == NULL)
- {
- ugh = builddiag("%s of %s has an unknown value: %lu"
- , fp->name, sd->name, (unsigned long)n);
- }
- /* FALL THROUGH */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- break;
- case ft_set: /* bits representing set */
- if (!testset(fp->desc, n))
- {
- ugh = builddiag("bitset %s of %s has unknown member(s): %s"
- , fp->name, sd->name, bitnamesof(fp->desc, n));
- }
- break;
- default:
- break;
- }
- i = fp->size;
- switch (i)
+ for (fp = sd->fields; ugh == NULL; fp++)
{
- case 8/BITS_PER_BYTE:
- *(u_int8_t *)outp = n;
- break;
- case 16/BITS_PER_BYTE:
- *(u_int16_t *)outp = n;
- break;
- case 32/BITS_PER_BYTE:
- *(u_int32_t *)outp = n;
- break;
- default:
- bad_case(i);
- }
- outp += i;
- break;
- }
+ size_t i = fp->size;
- case ft_raw: /* bytes to be left in network-order */
- for (; i != 0; i--)
- {
- *outp++ = *cur++;
- }
- break;
+ passert(ins->roof - cur >= (ptrdiff_t)i);
+ passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i));
+ passert(outp - (cur - ins->cur) == struct_ptr);
- case ft_end: /* end of field list */
- passert(cur == ins->cur + sd->size);
- if (obj_pbs != NULL)
- {
- init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name);
- obj_pbs->container = ins;
- obj_pbs->desc = sd;
- obj_pbs->cur = cur;
+#if 0
+ DBG(DBG_PARSING, DBG_log("%d %s"
+ , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));
+#endif
+ switch (fp->field_type)
+ {
+ case ft_mbz: /* must be zero */
+ for (; i != 0; i--)
+ {
+ if (*cur++ != 0)
+ {
+ ugh = builddiag("byte %d of %s must be zero, but is not"
+ , (int) (cur - ins->cur), sd->name);
+ break;
+ }
+ *outp++ = '\0'; /* probably redundant */
+ }
+ break;
+
+ case ft_nat: /* natural number (may be 0) */
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ case ft_enum: /* value from an enumeration */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ case ft_set: /* bits representing set */
+ {
+ u_int32_t n = 0;
+
+ for (; i != 0; i--)
+ n = (n << BITS_PER_BYTE) | *cur++;
+
+ switch (fp->field_type)
+ {
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ {
+ u_int32_t len = fp->field_type == ft_len? n
+ : immediate? sd->size : n + sd->size;
+
+ if (len < sd->size)
+ {
+ ugh = builddiag("%s of %s is smaller than minimum"
+ , fp->name, sd->name);
+ }
+ else if (pbs_left(ins) < len)
+ {
+ ugh = builddiag("%s of %s is larger than can fit"
+ , fp->name, sd->name);
+ }
+ else
+ {
+ roof = ins->cur + len;
+ }
+ break;
+ }
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ immediate = TRUE;
+ break;
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ immediate = TRUE;
+ /* FALL THROUGH */
+ case ft_enum: /* value from an enumeration */
+ if (enum_name(fp->desc, n) == NULL)
+ {
+ ugh = builddiag("%s of %s has an unknown value: %lu"
+ , fp->name, sd->name, (unsigned long)n);
+ }
+ /* FALL THROUGH */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ break;
+ case ft_set: /* bits representing set */
+ if (!testset(fp->desc, n))
+ {
+ ugh = builddiag("bitset %s of %s has unknown member(s): %s"
+ , fp->name, sd->name, bitnamesof(fp->desc, n));
+ }
+ break;
+ default:
+ break;
+ }
+ i = fp->size;
+ switch (i)
+ {
+ case 8/BITS_PER_BYTE:
+ *(u_int8_t *)outp = n;
+ break;
+ case 16/BITS_PER_BYTE:
+ *(u_int16_t *)outp = n;
+ break;
+ case 32/BITS_PER_BYTE:
+ *(u_int32_t *)outp = n;
+ break;
+ default:
+ bad_case(i);
+ }
+ outp += i;
+ break;
+ }
+
+ case ft_raw: /* bytes to be left in network-order */
+ for (; i != 0; i--)
+ {
+ *outp++ = *cur++;
+ }
+ break;
+
+ case ft_end: /* end of field list */
+ passert(cur == ins->cur + sd->size);
+ if (obj_pbs != NULL)
+ {
+ init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name);
+ obj_pbs->container = ins;
+ obj_pbs->desc = sd;
+ obj_pbs->cur = cur;
+ }
+ ins->cur = roof;
+ DBG(DBG_PARSING
+ , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE));
+ return TRUE;
+
+ default:
+ bad_case(fp->field_type);
+ }
}
- ins->cur = roof;
- DBG(DBG_PARSING
- , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE));
- return TRUE;
-
- default:
- bad_case(fp->field_type);
- }
}
- }
- /* some failure got us here: report it */
- loglog(RC_LOG_SERIOUS, ugh);
- return FALSE;
+ /* some failure got us here: report it */
+ loglog(RC_LOG_SERIOUS, ugh);
+ return FALSE;
}
bool
in_raw(void *bytes, size_t len, pb_stream *ins, const char *name)
{
- if (pbs_left(ins) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name);
- return FALSE;
- }
- else
- {
- if (bytes == NULL)
+ if (pbs_left(ins) < len)
{
- DBG(DBG_PARSING
- , DBG_log("skipping %u raw bytes of %s (%s)"
- , (unsigned) len, ins->name, name);
- DBG_dump(name, ins->cur, len));
+ loglog(RC_LOG_SERIOUS, "not enough bytes left to get %s from %s", name, ins->name);
+ return FALSE;
}
else
{
- memcpy(bytes, ins->cur, len);
- DBG(DBG_PARSING
- , DBG_log("parsing %u raw bytes of %s into %s"
- , (unsigned) len, ins->name, name);
- DBG_dump(name, bytes, len));
+ if (bytes == NULL)
+ {
+ DBG(DBG_PARSING
+ , DBG_log("skipping %u raw bytes of %s (%s)"
+ , (unsigned) len, ins->name, name);
+ DBG_dump(name, ins->cur, len));
+ }
+ else
+ {
+ memcpy(bytes, ins->cur, len);
+ DBG(DBG_PARSING
+ , DBG_log("parsing %u raw bytes of %s into %s"
+ , (unsigned) len, ins->name, name);
+ DBG_dump(name, bytes, len));
+ }
+ ins->cur += len;
+ return TRUE;
}
- ins->cur += len;
- return TRUE;
- }
}
/* "emit" a host struct into a network packet.
@@ -994,227 +992,227 @@ bool
out_struct(const void *struct_ptr, struct_desc *sd
, pb_stream *outs, pb_stream *obj_pbs)
{
- err_t ugh = NULL;
- const u_int8_t *inp = struct_ptr;
- u_int8_t *cur = outs->cur;
-
- DBG(DBG_EMITTING
- , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL));
-
- if (outs->roof - cur < (ptrdiff_t)sd->size)
- {
- ugh = builddiag("not enough room left in output packet to place %s"
- , sd->name);
- }
- else
- {
- bool immediate = FALSE;
- pb_stream obj;
- field_desc *fp;
+ err_t ugh = NULL;
+ const u_int8_t *inp = struct_ptr;
+ u_int8_t *cur = outs->cur;
- obj.lenfld = NULL; /* until a length field is discovered */
- obj.lenfld_desc = NULL;
+ DBG(DBG_EMITTING
+ , DBG_prefix_print_struct(outs, "emit ", struct_ptr, sd, obj_pbs==NULL));
- for (fp = sd->fields; ugh == NULL; fp++)
+ if (outs->roof - cur < (ptrdiff_t)sd->size)
{
- size_t i = fp->size;
-
- passert(outs->roof - cur >= (ptrdiff_t)i);
- passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i));
- passert(inp - (cur - outs->cur) == struct_ptr);
-
-#if 0
- DBG(DBG_EMITTING, DBG_log("%d %s"
- , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name);
-#endif
- switch (fp->field_type)
- {
- case ft_mbz: /* must be zero */
- inp += i;
- for (; i != 0; i--)
- *cur++ = '\0';
- break;
- case ft_nat: /* natural number (may be 0) */
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- case ft_enum: /* value from an enumeration */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- case ft_set: /* bits representing set */
- {
- u_int32_t n = 0;
+ ugh = builddiag("not enough room left in output packet to place %s"
+ , sd->name);
+ }
+ else
+ {
+ bool immediate = FALSE;
+ pb_stream obj;
+ field_desc *fp;
- switch (i)
- {
- case 8/BITS_PER_BYTE:
- n = *(const u_int8_t *)inp;
- break;
- case 16/BITS_PER_BYTE:
- n = *(const u_int16_t *)inp;
- break;
- case 32/BITS_PER_BYTE:
- n = *(const u_int32_t *)inp;
- break;
- default:
- bad_case(i);
- }
+ obj.lenfld = NULL; /* until a length field is discovered */
+ obj.lenfld_desc = NULL;
- switch (fp->field_type)
+ for (fp = sd->fields; ugh == NULL; fp++)
{
- case ft_len: /* length of this struct and any following crud */
- case ft_lv: /* length/value field of attribute */
- if (immediate)
- break; /* not a length */
- /* We can't check the length because it will likely
- * be filled in after variable part is supplied.
- * We do record where this is so that it can be
- * filled in by a subsequent close_output_pbs().
- */
- passert(obj.lenfld == NULL); /* only one ft_len allowed */
- obj.lenfld = cur;
- obj.lenfld_desc = fp;
- break;
- case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- break;
- case ft_af_enum: /* Attribute Format + value from an enumeration */
- if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- immediate = TRUE;
- /* FALL THROUGH */
- case ft_enum: /* value from an enumeration */
- if (enum_name(fp->desc, n) == NULL)
- {
- ugh = builddiag("%s of %s has an unknown value: %lu"
- , fp->name, sd->name, (unsigned long)n);
- }
- /* FALL THROUGH */
- case ft_loose_enum: /* value from an enumeration with only some names known */
- break;
- case ft_set: /* bits representing set */
- if (!testset(fp->desc, n))
- {
- ugh = builddiag("bitset %s of %s has unknown member(s): %s"
- , fp->name, sd->name, bitnamesof(fp->desc, n));
- }
- break;
- default:
- break;
- }
+ size_t i = fp->size;
- while (i-- != 0)
- {
- cur[i] = (u_int8_t)n;
- n >>= BITS_PER_BYTE;
- }
- inp += fp->size;
- cur += fp->size;
- break;
- }
- case ft_raw: /* bytes to be left in network-order */
- for (; i != 0; i--)
- *cur++ = *inp++;
- break;
- case ft_end: /* end of field list */
- passert(cur == outs->cur + sd->size);
-
- obj.container = outs;
- obj.desc = sd;
- obj.name = sd->name;
- obj.start = outs->cur;
- obj.cur = cur;
- obj.roof = outs->roof; /* limit of possible */
- /* obj.lenfld and obj.lenfld_desc already set */
-
- if (obj_pbs == NULL)
- {
- close_output_pbs(&obj); /* fill in length field, if any */
- }
- else
- {
- /* We set outs->cur to outs->roof so that
- * any attempt to output something into outs
- * before obj is closed will trigger an error.
- */
- outs->cur = outs->roof;
+ passert(outs->roof - cur >= (ptrdiff_t)i);
+ passert(cur - outs->cur <= (ptrdiff_t)(sd->size - i));
+ passert(inp - (cur - outs->cur) == struct_ptr);
- *obj_pbs = obj;
+#if 0
+ DBG(DBG_EMITTING, DBG_log("%d %s"
+ , (int) (cur - outs->cur), fp->name == NULL? "" : fp->name);
+#endif
+ switch (fp->field_type)
+ {
+ case ft_mbz: /* must be zero */
+ inp += i;
+ for (; i != 0; i--)
+ *cur++ = '\0';
+ break;
+ case ft_nat: /* natural number (may be 0) */
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ case ft_enum: /* value from an enumeration */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ case ft_set: /* bits representing set */
+ {
+ u_int32_t n = 0;
+
+ switch (i)
+ {
+ case 8/BITS_PER_BYTE:
+ n = *(const u_int8_t *)inp;
+ break;
+ case 16/BITS_PER_BYTE:
+ n = *(const u_int16_t *)inp;
+ break;
+ case 32/BITS_PER_BYTE:
+ n = *(const u_int32_t *)inp;
+ break;
+ default:
+ bad_case(i);
+ }
+
+ switch (fp->field_type)
+ {
+ case ft_len: /* length of this struct and any following crud */
+ case ft_lv: /* length/value field of attribute */
+ if (immediate)
+ break; /* not a length */
+ /* We can't check the length because it will likely
+ * be filled in after variable part is supplied.
+ * We do record where this is so that it can be
+ * filled in by a subsequent close_output_pbs().
+ */
+ passert(obj.lenfld == NULL); /* only one ft_len allowed */
+ obj.lenfld = cur;
+ obj.lenfld_desc = fp;
+ break;
+ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */
+ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ immediate = TRUE;
+ break;
+ case ft_af_enum: /* Attribute Format + value from an enumeration */
+ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ immediate = TRUE;
+ /* FALL THROUGH */
+ case ft_enum: /* value from an enumeration */
+ if (enum_name(fp->desc, n) == NULL)
+ {
+ ugh = builddiag("%s of %s has an unknown value: %lu"
+ , fp->name, sd->name, (unsigned long)n);
+ }
+ /* FALL THROUGH */
+ case ft_loose_enum: /* value from an enumeration with only some names known */
+ break;
+ case ft_set: /* bits representing set */
+ if (!testset(fp->desc, n))
+ {
+ ugh = builddiag("bitset %s of %s has unknown member(s): %s"
+ , fp->name, sd->name, bitnamesof(fp->desc, n));
+ }
+ break;
+ default:
+ break;
+ }
+
+ while (i-- != 0)
+ {
+ cur[i] = (u_int8_t)n;
+ n >>= BITS_PER_BYTE;
+ }
+ inp += fp->size;
+ cur += fp->size;
+ break;
+ }
+ case ft_raw: /* bytes to be left in network-order */
+ for (; i != 0; i--)
+ *cur++ = *inp++;
+ break;
+ case ft_end: /* end of field list */
+ passert(cur == outs->cur + sd->size);
+
+ obj.container = outs;
+ obj.desc = sd;
+ obj.name = sd->name;
+ obj.start = outs->cur;
+ obj.cur = cur;
+ obj.roof = outs->roof; /* limit of possible */
+ /* obj.lenfld and obj.lenfld_desc already set */
+
+ if (obj_pbs == NULL)
+ {
+ close_output_pbs(&obj); /* fill in length field, if any */
+ }
+ else
+ {
+ /* We set outs->cur to outs->roof so that
+ * any attempt to output something into outs
+ * before obj is closed will trigger an error.
+ */
+ outs->cur = outs->roof;
+
+ *obj_pbs = obj;
+ }
+ return TRUE;
+
+ default:
+ bad_case(fp->field_type);
+ }
}
- return TRUE;
-
- default:
- bad_case(fp->field_type);
- }
}
- }
- /* some failure got us here: report it */
- loglog(RC_LOG_SERIOUS, ugh); /* ??? serious, but errno not relevant */
- return FALSE;
+ /* some failure got us here: report it */
+ loglog(RC_LOG_SERIOUS, ugh); /* ??? serious, but errno not relevant */
+ return FALSE;
}
bool
out_generic(u_int8_t np, struct_desc *sd
, pb_stream *outs, pb_stream *obj_pbs)
{
- struct isakmp_generic gen;
+ struct isakmp_generic gen;
- passert(sd->fields == isakmp_generic_desc.fields);
- gen.isag_np = np;
- return out_struct(&gen, sd, outs, obj_pbs);
+ passert(sd->fields == isakmp_generic_desc.fields);
+ gen.isag_np = np;
+ return out_struct(&gen, sd, outs, obj_pbs);
}
bool
out_generic_raw(u_int8_t np, struct_desc *sd
, pb_stream *outs, const void *bytes, size_t len, const char *name)
{
- pb_stream pbs;
+ pb_stream pbs;
- if (!out_generic(np, sd, outs, &pbs)
- || !out_raw(bytes, len, &pbs, name))
- return FALSE;
- close_output_pbs(&pbs);
- return TRUE;
+ if (!out_generic(np, sd, outs, &pbs)
+ || !out_raw(bytes, len, &pbs, name))
+ return FALSE;
+ close_output_pbs(&pbs);
+ return TRUE;
}
bool
out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name)
{
- if (pbs_left(outs) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s"
- , (unsigned long) len, name, outs->name);
- return FALSE;
- }
- else
- {
- DBG(DBG_EMITTING
- , DBG_log("emitting %u raw bytes of %s into %s"
- , (unsigned) len, name, outs->name);
- DBG_dump(name, bytes, len));
- memcpy(outs->cur, bytes, len);
- outs->cur += len;
- return TRUE;
- }
+ if (pbs_left(outs) < len)
+ {
+ loglog(RC_LOG_SERIOUS, "not enough room left to place %lu bytes of %s in %s"
+ , (unsigned long) len, name, outs->name);
+ return FALSE;
+ }
+ else
+ {
+ DBG(DBG_EMITTING
+ , DBG_log("emitting %u raw bytes of %s into %s"
+ , (unsigned) len, name, outs->name);
+ DBG_dump(name, bytes, len));
+ memcpy(outs->cur, bytes, len);
+ outs->cur += len;
+ return TRUE;
+ }
}
bool
out_zero(size_t len, pb_stream *outs, const char *name)
{
- if (pbs_left(outs) < len)
- {
- loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name);
- return FALSE;
- }
- else
- {
- DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s"
- , (unsigned) len, name, outs->name));
- memset(outs->cur, 0x00, len);
- outs->cur += len;
- return TRUE;
- }
+ if (pbs_left(outs) < len)
+ {
+ loglog(RC_LOG_SERIOUS, "not enough room left to place %s in %s", name, outs->name);
+ return FALSE;
+ }
+ else
+ {
+ DBG(DBG_EMITTING, DBG_log("emitting %u zero bytes of %s into %s"
+ , (unsigned) len, name, outs->name));
+ memset(outs->cur, 0x00, len);
+ outs->cur += len;
+ return TRUE;
+ }
}
/* Record current length.
@@ -1224,21 +1222,21 @@ out_zero(size_t len, pb_stream *outs, const char *name)
void
close_output_pbs(pb_stream *pbs)
{
- if (pbs->lenfld != NULL)
- {
- u_int32_t len = pbs_offset(pbs);
- int i = pbs->lenfld_desc->size;
-
- if (pbs->lenfld_desc->field_type == ft_lv)
- len -= sizeof(struct isakmp_attribute);
- DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu"
- , pbs->name, (unsigned long) len));
- while (i-- != 0)
+ if (pbs->lenfld != NULL)
{
- pbs->lenfld[i] = (u_int8_t)len;
- len >>= BITS_PER_BYTE;
+ u_int32_t len = pbs_offset(pbs);
+ int i = pbs->lenfld_desc->size;
+
+ if (pbs->lenfld_desc->field_type == ft_lv)
+ len -= sizeof(struct isakmp_attribute);
+ DBG(DBG_EMITTING, DBG_log("emitting length of %s: %lu"
+ , pbs->name, (unsigned long) len));
+ while (i-- != 0)
+ {
+ pbs->lenfld[i] = (u_int8_t)len;
+ len >>= BITS_PER_BYTE;
+ }
}
- }
- if (pbs->container != NULL)
- pbs->container->cur = pbs->cur; /* pass space utilization up */
+ if (pbs->container != NULL)
+ pbs->container->cur = pbs->cur; /* pass space utilization up */
}
diff --git a/src/pluto/packet.h b/src/pluto/packet.h
index 1eadf0e02..1510b81a0 100644
--- a/src/pluto/packet.h
+++ b/src/pluto/packet.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: packet.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _PACKET_H
@@ -23,9 +21,9 @@
*/
typedef const struct struct_desc {
- const char *name;
- const struct field_desc *fields;
- size_t size;
+ const char *name;
+ const struct field_desc *fields;
+ size_t size;
} struct_desc;
/* Note: if an ft_af_enum field has the ISAKMP_ATTR_AF_TV bit set,
@@ -35,24 +33,24 @@ typedef const struct struct_desc {
*/
enum field_type {
- ft_mbz, /* must be zero */
- ft_nat, /* natural number (may be 0) */
- ft_len, /* length of this struct and any following crud */
- ft_lv, /* length/value field of attribute */
- ft_enum, /* value from an enumeration */
- ft_loose_enum, /* value from an enumeration with only some names known */
- ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
- ft_af_enum, /* Attribute Format + value from an enumeration */
- ft_set, /* bits representing set */
- ft_raw, /* bytes to be left in network-order */
- ft_end, /* end of field list */
+ ft_mbz, /* must be zero */
+ ft_nat, /* natural number (may be 0) */
+ ft_len, /* length of this struct and any following crud */
+ ft_lv, /* length/value field of attribute */
+ ft_enum, /* value from an enumeration */
+ ft_loose_enum, /* value from an enumeration with only some names known */
+ ft_af_loose_enum, /* Attribute Format + enumeration, some names known */
+ ft_af_enum, /* Attribute Format + value from an enumeration */
+ ft_set, /* bits representing set */
+ ft_raw, /* bytes to be left in network-order */
+ ft_end, /* end of field list */
};
typedef const struct field_desc {
- enum field_type field_type;
- int size; /* size, in bytes, of field */
- const char *name;
- const void *desc; /* enum_names for enum or char *[] for bits */
+ enum field_type field_type;
+ int size; /* size, in bytes, of field */
+ const char *name;
+ const void *desc; /* enum_names for enum or char *[] for bits */
} field_desc;
/* The formatting of input and output of packets is done
@@ -62,18 +60,18 @@ typedef const struct field_desc {
* Actual packet transfer is done elsewhere.
*/
typedef struct packet_byte_stream {
- struct packet_byte_stream *container; /* PBS of which we are part */
- struct_desc *desc;
- const char *name; /* what does this PBS represent? */
- u_int8_t
- *start,
- *cur, /* current position in stream */
- *roof; /* byte after last in PBS (actually just a limit on output) */
- /* For an output PBS, the length field will be filled in later so
- * we need to record its particulars. Note: it may not be aligned.
- */
- u_int8_t *lenfld;
- field_desc *lenfld_desc;
+ struct packet_byte_stream *container; /* PBS of which we are part */
+ struct_desc *desc;
+ const char *name; /* what does this PBS represent? */
+ u_int8_t
+ *start,
+ *cur, /* current position in stream */
+ *roof; /* byte after last in PBS (actually just a limit on output) */
+ /* For an output PBS, the length field will be filled in later so
+ * we need to record its particulars. Note: it may not be aligned.
+ */
+ u_int8_t *lenfld;
+ field_desc *lenfld_desc;
} pb_stream;
/* For an input PBS, pbs_offset is amount of stream processed.
@@ -88,17 +86,17 @@ typedef struct packet_byte_stream {
extern void init_pbs(pb_stream *pbs, u_int8_t *start, size_t len, const char *name);
extern bool in_struct(void *struct_ptr, struct_desc *sd,
- pb_stream *ins, pb_stream *obj_pbs);
+ pb_stream *ins, pb_stream *obj_pbs);
extern bool in_raw(void *bytes, size_t len, pb_stream *ins, const char *name);
extern bool out_struct(const void *struct_ptr, struct_desc *sd,
- pb_stream *outs, pb_stream *obj_pbs);
+ pb_stream *outs, pb_stream *obj_pbs);
extern bool out_generic(u_int8_t np, struct_desc *sd,
- pb_stream *outs, pb_stream *obj_pbs);
+ pb_stream *outs, pb_stream *obj_pbs);
extern bool out_generic_raw(u_int8_t np, struct_desc *sd,
- pb_stream *outs, const void *bytes, size_t len, const char *name);
+ pb_stream *outs, const void *bytes, size_t len, const char *name);
#define out_generic_chunk(np, sd, outs, ch, name) \
- out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
+ out_generic_raw(np, sd, outs, (ch).ptr, (ch).len, name)
extern bool out_zero(size_t len, pb_stream *outs, const char *name);
extern bool out_raw(const void *bytes, size_t len, pb_stream *outs, const char *name);
#define out_chunk(ch, outs, name) out_raw((ch).ptr, (ch).len, (outs), (name))
@@ -106,7 +104,7 @@ extern void close_output_pbs(pb_stream *pbs);
#ifdef DEBUG
extern void DBG_print_struct(const char *label, const void *struct_ptr,
- struct_desc *sd, bool len_meaningful);
+ struct_desc *sd, bool len_meaningful);
#endif
/* ISAKMP Header: for all messages
@@ -160,16 +158,16 @@ extern void DBG_print_struct(const char *label, const void *struct_ptr,
struct isakmp_hdr
{
- u_int8_t isa_icookie[COOKIE_SIZE];
- u_int8_t isa_rcookie[COOKIE_SIZE];
- u_int8_t isa_np; /* Next payload */
- u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
-#define ISA_MAJ_SHIFT 4
-#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
- u_int8_t isa_xchg; /* Exchange type */
- u_int8_t isa_flags;
- u_int32_t isa_msgid; /* Message ID (RAW) */
- u_int32_t isa_length; /* Length of message */
+ u_int8_t isa_icookie[COOKIE_SIZE];
+ u_int8_t isa_rcookie[COOKIE_SIZE];
+ u_int8_t isa_np; /* Next payload */
+ u_int8_t isa_version; /* high-order 4 bits: Major; low order 4: Minor */
+#define ISA_MAJ_SHIFT 4
+#define ISA_MIN_MASK (~((~0u) << ISA_MAJ_SHIFT))
+ u_int8_t isa_xchg; /* Exchange type */
+ u_int8_t isa_flags;
+ u_int32_t isa_msgid; /* Message ID (RAW) */
+ u_int32_t isa_length; /* Length of message */
};
extern struct_desc isakmp_hdr_desc;
@@ -186,9 +184,9 @@ extern struct_desc isakmp_hdr_desc;
*/
struct isakmp_generic
{
- u_int8_t isag_np;
- u_int8_t isag_reserved;
- u_int16_t isag_length;
+ u_int8_t isag_np;
+ u_int8_t isag_reserved;
+ u_int16_t isag_length;
};
extern struct_desc isakmp_generic_desc;
@@ -209,17 +207,17 @@ extern struct_desc isakmp_generic_desc;
*/
struct isakmp_attribute
{
- /* The high order bit of isaat_af_type is the Attribute Format
- * If it is off, the format is TLV: lv is the length of the following
- * attribute value.
- * If it is on, the format is TV: lv is the value of the attribute.
- * ISAKMP_ATTR_AF_MASK is the mask in host form.
- *
- * The low order 15 bits of isaat_af_type is the Attribute Type.
- * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
- */
- u_int16_t isaat_af_type; /* high order bit: AF; lower 15: rtype */
- u_int16_t isaat_lv; /* Length or value */
+ /* The high order bit of isaat_af_type is the Attribute Format
+ * If it is off, the format is TLV: lv is the length of the following
+ * attribute value.
+ * If it is on, the format is TV: lv is the value of the attribute.
+ * ISAKMP_ATTR_AF_MASK is the mask in host form.
+ *
+ * The low order 15 bits of isaat_af_type is the Attribute Type.
+ * ISAKMP_ATTR_RTYPE_MASK is the mask in host form.
+ */
+ u_int16_t isaat_af_type; /* high order bit: AF; lower 15: rtype */
+ u_int16_t isaat_lv; /* Length or value */
};
#define ISAKMP_ATTR_AF_MASK 0x8000
@@ -229,8 +227,8 @@ struct isakmp_attribute
#define ISAKMP_ATTR_RTYPE_MASK 0x7FFF
extern struct_desc
- isakmp_oakley_attribute_desc,
- isakmp_ipsec_attribute_desc;
+ isakmp_oakley_attribute_desc,
+ isakmp_ipsec_attribute_desc;
/* ISAKMP Security Association Payload
* layout from RFC 2408 "ISAKMP" section 3.4
@@ -250,10 +248,10 @@ extern struct_desc
*/
struct isakmp_sa
{
- u_int8_t isasa_np; /* Next payload */
- u_int8_t isasa_reserved;
- u_int16_t isasa_length; /* Payload length */
- u_int32_t isasa_doi; /* DOI */
+ u_int8_t isasa_np; /* Next payload */
+ u_int8_t isasa_reserved;
+ u_int16_t isasa_length; /* Payload length */
+ u_int32_t isasa_doi; /* DOI */
};
extern struct_desc isakmp_sa_desc;
@@ -276,13 +274,13 @@ extern struct_desc ipsec_sit_desc;
*/
struct isakmp_proposal
{
- u_int8_t isap_np;
- u_int8_t isap_reserved;
- u_int16_t isap_length;
- u_int8_t isap_proposal;
- u_int8_t isap_protoid;
- u_int8_t isap_spisize;
- u_int8_t isap_notrans; /* Number of transforms */
+ u_int8_t isap_np;
+ u_int8_t isap_reserved;
+ u_int16_t isap_length;
+ u_int8_t isap_proposal;
+ u_int8_t isap_protoid;
+ u_int8_t isap_spisize;
+ u_int8_t isap_notrans; /* Number of transforms */
};
extern struct_desc isakmp_proposal_desc;
@@ -305,19 +303,19 @@ extern struct_desc isakmp_proposal_desc;
*/
struct isakmp_transform
{
- u_int8_t isat_np;
- u_int8_t isat_reserved;
- u_int16_t isat_length;
- u_int8_t isat_transnum; /* Number of the transform */
- u_int8_t isat_transid;
- u_int16_t isat_reserved2;
+ u_int8_t isat_np;
+ u_int8_t isat_reserved;
+ u_int16_t isat_length;
+ u_int8_t isat_transnum; /* Number of the transform */
+ u_int8_t isat_transid;
+ u_int16_t isat_reserved2;
};
extern struct_desc
- isakmp_isakmp_transform_desc,
- isakmp_ah_transform_desc,
- isakmp_esp_transform_desc,
- isakmp_ipcomp_transform_desc;
+ isakmp_isakmp_transform_desc,
+ isakmp_ah_transform_desc,
+ isakmp_esp_transform_desc,
+ isakmp_ipcomp_transform_desc;
/* ISAKMP Key Exchange Payload: no fixed fields beyond the generic ones.
* layout from RFC 2408 "ISAKMP" section 3.7
@@ -354,12 +352,12 @@ extern struct_desc isakmp_keyex_desc;
*/
struct isakmp_id
{
- u_int8_t isaid_np;
- u_int8_t isaid_reserved;
- u_int16_t isaid_length;
- u_int8_t isaid_idtype;
- u_int8_t isaid_doi_specific_a;
- u_int16_t isaid_doi_specific_b;
+ u_int8_t isaid_np;
+ u_int8_t isaid_reserved;
+ u_int16_t isaid_length;
+ u_int8_t isaid_idtype;
+ u_int8_t isaid_doi_specific_a;
+ u_int16_t isaid_doi_specific_b;
};
extern struct_desc isakmp_identification_desc;
@@ -381,12 +379,12 @@ extern struct_desc isakmp_identification_desc;
*/
struct isakmp_ipsec_id
{
- u_int8_t isaiid_np;
- u_int8_t isaiid_reserved;
- u_int16_t isaiid_length;
- u_int8_t isaiid_idtype;
- u_int8_t isaiid_protoid;
- u_int16_t isaiid_port;
+ u_int8_t isaiid_np;
+ u_int8_t isaiid_reserved;
+ u_int16_t isaiid_length;
+ u_int8_t isaiid_idtype;
+ u_int8_t isaiid_protoid;
+ u_int16_t isaiid_port;
};
extern struct_desc isakmp_ipsec_identification_desc;
@@ -408,17 +406,17 @@ extern struct_desc isakmp_ipsec_identification_desc;
*/
struct isakmp_cert
{
- u_int8_t isacert_np;
- u_int8_t isacert_reserved;
- u_int16_t isacert_length;
- u_int8_t isacert_type;
+ u_int8_t isacert_np;
+ u_int8_t isacert_reserved;
+ u_int16_t isacert_length;
+ u_int8_t isacert_type;
};
/* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cert)
* yields the wrong value for the length.
*/
-#define ISAKMP_CERT_SIZE 5
+#define ISAKMP_CERT_SIZE 5
extern struct_desc isakmp_ipsec_certificate_desc;
@@ -439,17 +437,17 @@ extern struct_desc isakmp_ipsec_certificate_desc;
*/
struct isakmp_cr
{
- u_int8_t isacr_np;
- u_int8_t isacr_reserved;
- u_int16_t isacr_length;
- u_int8_t isacr_type;
+ u_int8_t isacr_np;
+ u_int8_t isacr_reserved;
+ u_int16_t isacr_length;
+ u_int8_t isacr_type;
};
/* NOTE: this packet type has a fixed portion that is not a
* multiple of 4 octets. This means that sizeof(struct isakmp_cr)
* yields the wrong value for the length.
*/
-#define ISAKMP_CR_SIZE 5
+#define ISAKMP_CR_SIZE 5
extern struct_desc isakmp_ipsec_cert_req_desc;
@@ -526,13 +524,13 @@ extern struct_desc isakmp_nonce_desc;
*/
struct isakmp_notification
{
- u_int8_t isan_np;
- u_int8_t isan_reserved;
- u_int16_t isan_length;
- u_int32_t isan_doi;
- u_int8_t isan_protoid;
- u_int8_t isan_spisize;
- u_int16_t isan_type;
+ u_int8_t isan_np;
+ u_int8_t isan_reserved;
+ u_int16_t isan_length;
+ u_int32_t isan_doi;
+ u_int8_t isan_protoid;
+ u_int8_t isan_spisize;
+ u_int16_t isan_type;
};
extern struct_desc isakmp_notification_desc;
@@ -557,40 +555,40 @@ extern struct_desc isakmp_notification_desc;
*/
struct isakmp_delete
{
- u_int8_t isad_np;
- u_int8_t isad_reserved;
- u_int16_t isad_length;
- u_int32_t isad_doi;
- u_int8_t isad_protoid;
- u_int8_t isad_spisize;
- u_int16_t isad_nospi;
+ u_int8_t isad_np;
+ u_int8_t isad_reserved;
+ u_int16_t isad_length;
+ u_int32_t isad_doi;
+ u_int8_t isad_protoid;
+ u_int8_t isad_spisize;
+ u_int16_t isad_nospi;
};
extern struct_desc isakmp_delete_desc;
/* From draft-dukes-ike-mode-cfg
3.2. Attribute Payload
- 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
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Next Payload ! RESERVED ! Payload Length !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! Type ! RESERVED ! Identifier !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ! !
- ! !
- ~ Attributes ~
- ! !
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Type ! RESERVED ! Identifier !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! !
+ ! !
+ ~ Attributes ~
+ ! !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct isakmp_mode_attr
{
- u_int8_t isama_np;
- u_int8_t isama_reserved;
- u_int16_t isama_length;
- u_int8_t isama_type;
- u_int8_t isama_reserved2;
- u_int16_t isama_identifier;
+ u_int8_t isama_np;
+ u_int8_t isama_reserved;
+ u_int16_t isama_length;
+ u_int8_t isama_type;
+ u_int8_t isama_reserved2;
+ u_int16_t isama_identifier;
};
extern struct_desc isakmp_attr_desc;
@@ -614,12 +612,12 @@ extern struct_desc isakmp_vendor_id_desc;
struct isakmp_nat_oa
{
- u_int8_t isanoa_np;
- u_int8_t isanoa_reserved_1;
- u_int16_t isanoa_length;
- u_int8_t isanoa_idtype;
- u_int8_t isanoa_reserved_2;
- u_int16_t isanoa_reserved_3;
+ u_int8_t isanoa_np;
+ u_int8_t isanoa_reserved_1;
+ u_int16_t isanoa_length;
+ u_int8_t isanoa_idtype;
+ u_int8_t isanoa_reserved_2;
+ u_int16_t isanoa_reserved_3;
};
extern struct_desc isakmp_nat_d;
@@ -628,18 +626,18 @@ extern struct_desc isakmp_nat_oa;
/* union of all payloads */
union payload {
- struct isakmp_generic generic;
- struct isakmp_sa sa;
- struct isakmp_proposal proposal;
- struct isakmp_transform transform;
- struct isakmp_id id; /* Main Mode */
- struct isakmp_cert cert;
- struct isakmp_cr cr;
- struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
- struct isakmp_notification notification;
- struct isakmp_delete delete;
- struct isakmp_nat_oa nat_oa;
- struct isakmp_mode_attr attribute;
+ struct isakmp_generic generic;
+ struct isakmp_sa sa;
+ struct isakmp_proposal proposal;
+ struct isakmp_transform transform;
+ struct isakmp_id id; /* Main Mode */
+ struct isakmp_cert cert;
+ struct isakmp_cr cr;
+ struct isakmp_ipsec_id ipsec_id; /* Quick Mode */
+ struct isakmp_notification notification;
+ struct isakmp_delete delete;
+ struct isakmp_nat_oa nat_oa;
+ struct isakmp_mode_attr attribute;
};
/* descriptor for each payload type
diff --git a/src/pluto/pem.c b/src/pluto/pem.c
index 5ebe4b576..646447c1a 100644
--- a/src/pluto/pem.c
+++ b/src/pluto/pem.c
@@ -1,5 +1,6 @@
/* Loading of PEM encoded files with optional encryption
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2009 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
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pem.c 3252 2007-10-06 21:24:50Z andreas $
*/
/* decrypt a PEM encoded data block using DES-EDE3-CBC
@@ -27,437 +26,101 @@
#include <sys/types.h>
#include <freeswan.h>
-#define HEADER_DES_LOCL_H /* stupid trick to force prototype decl in <des.h> */
-#include <libdes/des.h>
+
+#include <library.h>
+#include <asn1/pem.h>
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "md5.h"
#include "whack.h"
#include "pem.h"
-/*
- * check the presence of a pattern in a character string
- */
-static bool
-present(const char* pattern, chunk_t* ch)
-{
- u_int pattern_len = strlen(pattern);
-
- if (ch->len >= pattern_len && strncmp(ch->ptr, pattern, pattern_len) == 0)
- {
- ch->ptr += pattern_len;
- ch->len -= pattern_len;
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * compare string with chunk
- */
-static bool
-match(const char *pattern, const chunk_t *ch)
-{
- return ch->len == strlen(pattern) &&
- strncmp(pattern, ch->ptr, ch->len) == 0;
-}
-
-/*
- * find a boundary of the form -----tag name-----
- */
-static bool
-find_boundary(const char* tag, chunk_t *line)
-{
- chunk_t name = empty_chunk;
-
- if (!present("-----", line))
- return FALSE;
- if (!present(tag, line))
- return FALSE;
- if (*line->ptr != ' ')
- return FALSE;
- line->ptr++; line->len--;
-
- /* extract name */
- name.ptr = line->ptr;
- while (line->len > 0)
- {
- if (present("-----", line))
- {
- DBG(DBG_PARSING,
- DBG_log(" -----%s %.*s-----",
- tag, (int)name.len, name.ptr);
- )
- return TRUE;
- }
- line->ptr++; line->len--; name.len++;
- }
- return FALSE;
-}
-
-/*
- * eat whitespace
- */
-static void
-eat_whitespace(chunk_t *src)
-{
- while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
- {
- src->ptr++; src->len--;
- }
-}
-
-/*
- * extracts a token ending with a given termination symbol
- */
-static bool
-extract_token(chunk_t *token, char termination, chunk_t *src)
-{
- u_char *eot = memchr(src->ptr, termination, src->len);
-
- /* initialize empty token */
- *token = empty_chunk;
-
- if (eot == NULL) /* termination symbol not found */
- return FALSE;
-
- /* extract token */
- token->ptr = src->ptr;
- token->len = (u_int)(eot - src->ptr);
-
- /* advance src pointer after termination symbol */
- src->ptr = eot + 1;
- src->len -= (token->len + 1);
-
- return TRUE;
-}
-
-/*
- * extracts a name: value pair from the PEM header
- */
-static bool
-extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line)
-{
- DBG(DBG_PARSING,
- DBG_log(" %.*s", (int)line->len, line->ptr);
- )
-
- /* extract name */
- if (!extract_token(name,':', line))
- return FALSE;
-
- eat_whitespace(line);
-
- /* extract value */
- *value = *line;
- return TRUE;
-}
-
-/*
- * fetches a new line terminated by \n or \r\n
- */
-static bool
-fetchline(chunk_t *src, chunk_t *line)
-{
- if (src->len == 0) /* end of src reached */
- return FALSE;
-
- if (extract_token(line, '\n', src))
- {
- if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
- line->len--; /* remove optional \r */
- }
- else /*last line ends without newline */
- {
- *line = *src;
- src->ptr += src->len;
- src->len = 0;
- }
- return TRUE;
-}
-
-/*
- * decrypts a DES-EDE-CBC encrypted data block
- */
-static bool
-pem_decrypt_3des(chunk_t *blob, chunk_t *iv, const char *passphrase)
-{
- MD5_CTX context;
- u_char digest[MD5_DIGEST_SIZE];
- u_char des_iv[DES_CBC_BLOCK_SIZE];
- u_char key[24];
- des_cblock *deskey = (des_cblock *)key;
- des_key_schedule ks[3];
- u_char padding, *last_padding_pos, *first_padding_pos;
-
- /* Convert passphrase to 3des key */
- MD5Init(&context);
- MD5Update(&context, passphrase, strlen(passphrase));
- MD5Update(&context, iv->ptr, iv->len);
- MD5Final(digest, &context);
-
- memcpy(key, digest, MD5_DIGEST_SIZE);
-
- MD5Init(&context);
- MD5Update(&context, digest, MD5_DIGEST_SIZE);
- MD5Update(&context, passphrase, strlen(passphrase));
- MD5Update(&context, iv->ptr, iv->len);
- MD5Final(digest, &context);
-
- memcpy(key + MD5_DIGEST_SIZE, digest, 24 - MD5_DIGEST_SIZE);
-
- (void) des_set_key(&deskey[0], ks[0]);
- (void) des_set_key(&deskey[1], ks[1]);
- (void) des_set_key(&deskey[2], ks[2]);
-
- /* decrypt data block */
- memcpy(des_iv, iv->ptr, DES_CBC_BLOCK_SIZE);
- des_ede3_cbc_encrypt((des_cblock *)blob->ptr, (des_cblock *)blob->ptr,
- blob->len, ks[0], ks[1], ks[2], (des_cblock *)des_iv, FALSE);
-
- /* determine amount of padding */
- last_padding_pos = blob->ptr + blob->len - 1;
- padding = *last_padding_pos;
- first_padding_pos = (padding > blob->len)?
- blob->ptr : last_padding_pos - padding;
-
- /* check the padding pattern */
- while (--last_padding_pos > first_padding_pos)
- {
- if (*last_padding_pos != padding)
- return FALSE;
- }
-
- /* remove padding */
- blob->len -= padding;
- return TRUE;
-}
-
-/*
- * optionally prompts for a passphrase before decryption
- * currently we support DES-EDE3-CBC, only
+/**
+ * Converts a PEM encoded file into its binary form
+ * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
+ * RFC 934 Message Encapsulation, January 1985
*/
-static err_t
-pem_decrypt(chunk_t *blob, chunk_t *iv, prompt_pass_t *pass, const char* label)
+err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
{
- DBG(DBG_CRYPT,
- DBG_log(" decrypting file using 'DES-EDE3-CBC'");
- )
- if (iv->len != DES_CBC_BLOCK_SIZE)
- return "size of DES-EDE3-CBC IV is not 8 bytes";
-
- if (pass == NULL)
- return "no passphrase available";
+ chunk_t password = chunk_empty;
- /* do we prompt for the passphrase? */
- if (pass->prompt && pass->fd != NULL_FD)
- {
- int i;
- chunk_t blob_copy;
- err_t ugh = "invalid passphrase, too many trials";
-
- whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
-
- for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
+ /* do we prompt for the passphrase? */
+ if (pass && pass->prompt && pass->fd != NULL_FD)
{
- int n;
-
- if (i > 0)
- whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
-
- n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
-
- if (n == -1)
- {
- err_t ugh = "read(whackfd) failed";
-
- whack_log(RC_LOG_SERIOUS,ugh);
- return ugh;
- }
+ int i;
+ chunk_t blob_copy;
+ err_t ugh = "invalid passphrase, too many trials";
+ status_t status;
- pass->secret[n-1] = '\0';
-
- if (strlen(pass->secret) == 0)
- {
- err_t ugh = "no passphrase entered, aborted";
+ whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
+ for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
+ {
+ int n;
+
+ if (i > 0)
+ {
+ whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
+ }
+ n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
+
+ if (n == -1)
+ {
+ err_t ugh = "read(whackfd) failed";
+
+ whack_log(RC_LOG_SERIOUS,ugh);
+ return ugh;
+ }
+
+ pass->secret[n-1] = '\0';
+
+ if (strlen(pass->secret) == 0)
+ {
+ err_t ugh = "no passphrase entered, aborted";
+
+ whack_log(RC_LOG_SERIOUS, ugh);
+ return ugh;
+ }
+
+ blob_copy = chunk_clone(*blob);
+ password = chunk_create(pass->secret, strlen(pass->secret));
+
+ status = pem_to_bin(blob, password, pgp);
+ if (status != INVALID_ARG)
+ {
+ if (status == SUCCESS)
+ {
+ whack_log(RC_SUCCESS, "valid passphrase");
+ }
+ else
+ {
+ whack_log(RC_LOG_SERIOUS, "%N, aborted", status_names, status);
+ }
+ free(blob_copy.ptr);
+ return NULL;
+ }
+
+ /* blob is useless after wrong decryption, restore the original */
+ free(blob->ptr);
+ *blob = blob_copy;
+ }
whack_log(RC_LOG_SERIOUS, ugh);
return ugh;
- }
-
- clonetochunk(blob_copy, blob->ptr, blob->len, "blob copy");
-
- if (pem_decrypt_3des(blob, iv, pass->secret))
- {
- whack_log(RC_SUCCESS, "valid passphrase");
- pfree(blob_copy.ptr);
- return NULL;
- }
-
- /* blob is useless after wrong decryption, restore the original */
- pfree(blob->ptr);
- *blob = blob_copy;
- }
- whack_log(RC_LOG_SERIOUS, ugh);
- return ugh;
- }
- else
- {
- if (pem_decrypt_3des(blob, iv, pass->secret))
- return NULL;
- else
- return "invalid passphrase";
- }
-}
-
-/* Converts a PEM encoded file into its binary form
- *
- * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
- * RFC 934 Message Encapsulation, January 1985
- */
-err_t
-pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
-{
- typedef enum {
- PEM_PRE = 0,
- PEM_MSG = 1,
- PEM_HEADER = 2,
- PEM_BODY = 3,
- PEM_POST = 4,
- PEM_ABORT = 5
- } state_t;
-
- bool encrypted = FALSE;
-
- state_t state = PEM_PRE;
-
- chunk_t src = *blob;
- chunk_t dst = *blob;
- chunk_t line = empty_chunk;
- chunk_t iv = empty_chunk;
-
- u_char iv_buf[MAX_DIGEST_LEN];
-
- /* zero size of converted blob */
- dst.len = 0;
-
- /* zero size of IV */
- iv.ptr = iv_buf;
- iv.len = 0;
-
- while (fetchline(&src, &line))
- {
- if (state == PEM_PRE)
- {
- if (find_boundary("BEGIN", &line))
- {
- *pgp = FALSE;
- state = PEM_MSG;
- }
- continue;
}
else
{
- if (find_boundary("END", &line))
- {
- state = PEM_POST;
- break;
- }
- if (state == PEM_MSG)
- {
- state = (memchr(line.ptr, ':', line.len) == NULL)?
- PEM_BODY : PEM_HEADER;
- }
- if (state == PEM_HEADER)
- {
- chunk_t name = empty_chunk;
- chunk_t value = empty_chunk;
-
- /* an empty line separates HEADER and BODY */
- if (line.len == 0)
- {
- state = PEM_BODY;
- continue;
- }
-
- /* we are looking for a name: value pair */
- if (!extract_parameter(&name, &value, &line))
- continue;
-
- if (match("Proc-Type", &name) && *value.ptr == '4')
- encrypted = TRUE;
- else if (match("DEK-Info", &name))
+ if (pass)
{
- const char *ugh = NULL;
- size_t len = 0;
- chunk_t dek;
-
- if (!extract_token(&dek, ',', &value))
- dek = value;
-
- /* we support DES-EDE3-CBC encrypted files, only */
- if (!match("DES-EDE3-CBC", &dek))
- return "we support DES-EDE3-CBC encrypted files, only";
-
- eat_whitespace(&value);
- ugh = ttodata(value.ptr, value.len, 16,
- iv.ptr, MAX_DIGEST_LEN, &len);
- if (ugh)
- return "error in IV";
-
- iv.len = len;
+ password = chunk_create(pass->secret, strlen(pass->secret));
}
- }
- else /* state is PEM_BODY */
- {
- const char *ugh = NULL;
- size_t len = 0;
- chunk_t data;
-
- /* remove any trailing whitespace */
- if (!extract_token(&data ,' ', &line))
- data = line;
-
- /* check for PGP armor checksum */
- if (*data.ptr == '=')
+ if (pem_to_bin(blob, password, pgp) == SUCCESS)
{
- *pgp = TRUE;
- data.ptr++;
- data.len--;
- DBG(DBG_PARSING,
- DBG_log(" Armor checksum: %.*s", (int)data.len, data.ptr);
- )
- continue;
- }
-
- ugh = ttodata(data.ptr, data.len, 64,
- dst.ptr, blob->len - dst.len, &len);
- if (ugh)
- {
- DBG(DBG_PARSING,
- DBG_log(" %s", ugh);
- )
- state = PEM_ABORT;
- break;
+ return NULL;
}
else
{
- dst.ptr += len;
- dst.len += len;
+ return "pem to bin conversion failed";
}
- }
- }
- }
- /* set length to size of binary blob */
- blob->len = dst.len;
-
- if (state != PEM_POST)
- return "file coded in unknown format, discarded";
-
- if (encrypted)
- return pem_decrypt(blob, &iv, pass, label);
- else
- return NULL;
+ }
}
diff --git a/src/pluto/pem.h b/src/pluto/pem.h
index e74915cb2..5e97b99ed 100644
--- a/src/pluto/pem.h
+++ b/src/pluto/pem.h
@@ -1,5 +1,7 @@
/* Loading of PEM encoded files with optional encryption
- * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2009 Andreas Steffen
+ *
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,9 +12,7 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pem.h 3252 2007-10-06 21:24:50Z andreas $
*/
-extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label
- , bool *pgp);
+extern err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label,
+ bool *pgp);
diff --git a/src/pluto/pgp.c b/src/pluto/pgp.c
deleted file mode 100644
index b956ce4d7..000000000
--- a/src/pluto/pgp.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/* Support of OpenPGP certificates
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pgp.c 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <freeswan.h>
-#include <ipsec_policy.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "log.h"
-#include "id.h"
-#include "pgp.h"
-#include "certs.h"
-#include "md5.h"
-#include "whack.h"
-#include "pkcs1.h"
-#include "keys.h"
-
-/*
- * chained list of OpenPGP end certificates
- */
-static pgpcert_t *pgpcerts = NULL;
-
-/*
- * OpenPGP packet tags defined in section 4.3 of RFC 2440
- */
-#define PGP_PKT_RESERVED 0
-#define PGP_PKT_PUBKEY_ENC_SESSION_KEY 1
-#define PGP_PKT_SIGNATURE 2
-#define PGP_PKT_SYMKEY_ENC_SESSION_KEY 3
-#define PGP_PKT_ONE_PASS_SIGNATURE_PKT 4
-#define PGP_PKT_SECRET_KEY 5
-#define PGP_PKT_PUBLIC_KEY 6
-#define PGP_PKT_SECRET_SUBKEY 7
-#define PGP_PKT_COMPRESSED_DATA 8
-#define PGP_PKT_SYMKEY_ENC_DATA 9
-#define PGP_PKT_MARKER 10
-#define PGP_PKT_LITERAL_DATA 11
-#define PGP_PKT_TRUST 12
-#define PGP_PKT_USER_ID 13
-#define PGP_PKT_PUBLIC_SUBKEY 14
-#define PGP_PKT_ROOF 15
-
-static const char *const pgp_packet_type_name[] = {
- "Reserved",
- "Public-Key Encrypted Session Key Packet",
- "Signature Packet",
- "Symmetric-Key Encrypted Session Key Packet",
- "One-Pass Signature Packet",
- "Secret Key Packet",
- "Public Key Packet",
- "Secret Subkey Packet",
- "Compressed Data Packet",
- "Symmetrically Encrypted Data Packet",
- "Marker Packet",
- "Literal Data Packet",
- "Trust Packet",
- "User ID Packet",
- "Public Subkey Packet"
-};
-
-/*
- * OpenPGP public key algorithms defined in section 9.1 of RFC 2440
- */
-#define PGP_PUBKEY_ALG_RSA 1
-#define PGP_PUBKEY_ALG_RSA_ENC_ONLY 2
-#define PGP_PUBKEY_ALG_RSA_SIGN_ONLY 3
-#define PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY 16
-#define PGP_PUBKEY_ALG_DSA 17
-#define PGP_PUBKEY_ALG_ECC 18
-#define PGP_PUBKEY_ALG_ECDSA 19
-#define PGP_PUBKEY_ALG_ELGAMAL 20
-
-/*
- * OpenPGP symmetric key algorithms defined in section 9.2 of RFC 2440
- */
-#define PGP_SYM_ALG_PLAIN 0
-#define PGP_SYM_ALG_IDEA 1
-#define PGP_SYM_ALG_3DES 2
-#define PGP_SYM_ALG_CAST5 3
-#define PGP_SYM_ALG_BLOWFISH 4
-#define PGP_SYM_ALG_SAFER 5
-#define PGP_SYM_ALG_DES 6
-#define PGP_SYM_ALG_AES 7
-#define PGP_SYM_ALG_AES_192 8
-#define PGP_SYM_ALG_AES_256 9
-#define PGP_SYM_ALG_TWOFISH 10
-#define PGP_SYM_ALG_ROOF 11
-
-static const char *const pgp_sym_alg_name[] = {
- "Plaintext",
- "IDEA",
- "3DES",
- "CAST5",
- "Blowfish",
- "SAFER",
- "DES",
- "AES",
- "AES-192",
- "AES-256",
- "Twofish"
-};
-
-/*
- * Size of PGP Key ID
- */
-#define PGP_KEYID_SIZE 8
-
-const pgpcert_t empty_pgpcert = {
- NULL , /* *next */
- 0 , /* installed */
- 0 , /* count */
- { NULL, 0 }, /* certificate */
- 0 , /* created */
- 0 , /* until */
- 0 , /* pubkeyAlgorithm */
- { NULL, 0 }, /* modulus */
- { NULL, 0 }, /* publicExponent */
- "" /* fingerprint */
-};
-
-static size_t
-pgp_size(chunk_t *blob, int len)
-{
- size_t size = 0;
-
- blob->len -= len;
- while (len-- > 0)
- size = 256*size + *blob->ptr++;
- return size;
-}
-
-/*
- * extracts the length of a PGP packet
- */
-static size_t
-pgp_old_packet_length(chunk_t *blob)
-{
- /* bits 0 and 1 define the packet length type */
- int len_type = 0x03 & *blob->ptr++;
-
- blob->len--;
-
- /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
- return pgp_size(blob, (len_type == 0)? 1: len_type << 1);
-}
-
-/*
- * extracts PGP packet version (V3 or V4)
- */
-static u_char
-pgp_version(chunk_t *blob)
-{
- u_char version = *blob->ptr++;
- blob->len--;
- DBG(DBG_PARSING,
- DBG_log("L3 - version:");
- DBG_log(" V%d", version)
- )
- return version;
-}
-
-/*
- * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 2440
- */
-static bool
-parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
-{
- u_char version = pgp_version(packet);
-
- if (version < 3 || version > 4)
- {
- plog("PGP packet version V%d not supported", version);
- return FALSE;
- }
-
- /* creation date - 4 bytes */
- cert->created = (time_t)pgp_size(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %s", timetoa(&cert->created, TRUE))
- )
-
- if (version == 3)
- {
- /* validity in days - 2 bytes */
- cert->until = (time_t)pgp_size(packet, 2);
-
- /* validity of 0 days means that the key never expires */
- if (cert->until > 0)
- cert->until = cert->created + 24*3600*cert->until;
-
- DBG(DBG_PARSING,
- DBG_log("L3 - until:");
- DBG_log(" %s", timetoa(&cert->until, TRUE));
- )
- }
-
- /* public key algorithm - 1 byte */
- DBG(DBG_PARSING,
- DBG_log("L3 - public key algorithm:")
- )
-
- switch (pgp_size(packet, 1))
- {
- case PGP_PUBKEY_ALG_RSA:
- case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
- cert->pubkeyAlg = PUBKEY_ALG_RSA;
- DBG(DBG_PARSING,
- DBG_log(" RSA")
- )
- /* modulus n */
- cert->modulus.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
- cert->modulus.ptr = packet->ptr;
- packet->ptr += cert->modulus.len;
- packet->len -= cert->modulus.len;
- DBG(DBG_PARSING,
- DBG_log("L3 - modulus:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", cert->modulus);
-
- /* public exponent e */
- cert->publicExponent.len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
- cert->publicExponent.ptr = packet->ptr;
- packet->ptr += cert->publicExponent.len;
- packet->len -= cert->publicExponent.len;
- DBG(DBG_PARSING,
- DBG_log("L3 - public exponent:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", cert->publicExponent);
-
- if (version == 3)
- {
- /* a V3 fingerprint is the MD5 hash of modulus and public exponent */
- MD5_CTX context;
- MD5Init(&context);
- MD5Update(&context, cert->modulus.ptr, cert->modulus.len);
- MD5Update(&context, cert->publicExponent.ptr, cert->publicExponent.len);
- MD5Final(cert->fingerprint, &context);
- }
- else
- {
- plog(" computation of V4 key ID not implemented yet");
- }
- break;
- case PGP_PUBKEY_ALG_DSA:
- cert->pubkeyAlg = PUBKEY_ALG_DSA;
- DBG(DBG_PARSING,
- DBG_log(" DSA")
- )
- plog(" DSA public keys not supported");
- return FALSE;
- default:
- cert->pubkeyAlg = 0;
- DBG(DBG_PARSING,
- DBG_log(" other")
- )
- plog(" exotic not RSA public keys not supported");
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 2440
- */
-static bool
-parse_pgp_secretkey_packet(chunk_t *packet, RSA_private_key_t *key)
-{
- int i, s2k;
- pgpcert_t cert = empty_pgpcert;
-
- if (!parse_pgp_pubkey_packet(packet, &cert))
- return FALSE;
-
- init_RSA_public_key((RSA_public_key_t *)key, cert.publicExponent
- , cert.modulus);
-
- /* string-to-key usage */
- s2k = pgp_size(packet, 1);
-
- DBG(DBG_PARSING,
- DBG_log("L3 - string-to-key: %d", s2k)
- )
-
- if (s2k == 255)
- {
- plog(" string-to-key specifiers not supported");
- return FALSE;
- }
-
- if (s2k >= PGP_SYM_ALG_ROOF)
- {
- plog(" undefined symmetric key algorithm");
- return FALSE;
- }
-
- /* a known symmetric key algorithm is specified*/
- DBG(DBG_PARSING,
- DBG_log(" %s", pgp_sym_alg_name[s2k])
- )
-
- /* private key is unencrypted */
- if (s2k == PGP_SYM_ALG_PLAIN)
- {
- for (i = 2; i < RSA_PRIVATE_FIELD_ELEMENTS; i++)
- {
- mpz_t u; /* auxiliary variable */
-
- /* compute offset to private key component i*/
- MP_INT *n = (MP_INT*)((char *)key + RSA_private_field[i].offset);
-
- switch (i)
- {
- case 2:
- case 3:
- case 4:
- {
- size_t len = (pgp_size(packet, 2)+7) / BITS_PER_BYTE;
-
- n_to_mpz(n, packet->ptr, len);
- DBG(DBG_PARSING,
- DBG_log("L3 - %s:", RSA_private_field[i].name)
- )
- DBG_cond_dump(DBG_PRIVATE, "", packet->ptr, len);
- packet->ptr += len;
- packet->len -= len;
- }
- break;
- case 5: /* dP = d mod (p-1) */
- mpz_init(u);
- mpz_sub_ui(u, &key->p, 1);
- mpz_mod(n, &key->d, u);
- mpz_clear(u);
- break;
- case 6: /* dQ = d mod (q-1) */
- mpz_init(u);
- mpz_sub_ui(u, &key->q, 1);
- mpz_mod(n, &key->d, u);
- mpz_clear(u);
- break;
- case 7: /* qInv = (q^-1) mod p */
- mpz_invert(n, &key->q, &key->p);
- if (mpz_cmp_ui(n, 0) < 0)
- mpz_add(n, n, &key->p);
- passert(mpz_cmp(n, &key->p) < 0);
- break;
- }
- }
- return TRUE;
- }
-
- plog(" %s encryption not supported", pgp_sym_alg_name[s2k]);
- return FALSE;
-}
-
-/*
- * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
- */
-static bool
-parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
-{
- time_t created;
- chunk_t keyid;
- u_char sig_type;
- u_char version = pgp_version(packet);
-
- /* we parse only V3 signature packets */
- if (version != 3)
- return TRUE;
-
- /* size byte must have the value 5 */
- if (pgp_size(packet, 1) != 5)
- {
- plog(" size must be 5");
- return FALSE;
- }
-
- /* signature type - 1 byte */
- sig_type = (u_char)pgp_size(packet, 1);
- DBG(DBG_PARSING,
- DBG_log("L3 - signature type: 0x%2x", sig_type)
- )
-
- /* creation date - 4 bytes */
- created = (time_t)pgp_size(packet, 4);
- DBG(DBG_PARSING,
- DBG_log("L3 - created:");
- DBG_log(" %s", timetoa(&cert->created, TRUE))
- )
-
- /* key ID of signer - 8 bytes */
- keyid.ptr = packet->ptr;
- keyid.len = PGP_KEYID_SIZE;
- DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
-
- return TRUE;
-}
-
-bool
-parse_pgp(chunk_t blob, pgpcert_t *cert, RSA_private_key_t *key)
-{
- DBG(DBG_PARSING,
- DBG_log("L0 - PGP file:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", blob);
-
- if (cert != NULL)
- {
- /* parse a PGP certificate file */
- cert->certificate = blob;
- time(&cert->installed);
- }
- else if (key == NULL)
- {
- /* should not occur, nothing to parse */
- return FALSE;
- }
-
- while (blob.len > 0)
- {
- chunk_t packet = empty_chunk;
- u_char packet_tag = *blob.ptr;
-
- DBG(DBG_PARSING,
- DBG_log("L1 - PGP packet: tag= 0x%2x", packet_tag)
- )
-
- /* bit 7 must be set */
- if (!(packet_tag & 0x80))
- {
- plog(" incorrect Packet Tag");
- return FALSE;
- }
-
- /* bit 6 set defines new packet format */
- if (packet_tag & 0x40)
- {
- plog(" new PGP packet format not supported");
- return FALSE;
- }
- else
- {
- int packet_type = (packet_tag & 0x3C) >> 2;
-
- packet.len = pgp_old_packet_length(&blob);
- packet.ptr = blob.ptr;
- blob.ptr += packet.len;
- blob.len -= packet.len;
- DBG(DBG_PARSING,
- DBG_log(" %s (%d), old format, %d bytes",
- (packet_type < PGP_PKT_ROOF) ?
- pgp_packet_type_name[packet_type] :
- "Undefined Packet Type", packet_type, (int)packet.len);
- DBG_log("L2 - body:")
- )
- DBG_cond_dump_chunk(DBG_RAW, "", packet);
-
- if (cert != NULL)
- {
- /* parse a PGP certificate */
- switch (packet_type)
- {
- case PGP_PKT_PUBLIC_KEY:
- if (!parse_pgp_pubkey_packet(&packet, cert))
- return FALSE;
- break;
- case PGP_PKT_SIGNATURE:
- if (!parse_pgp_signature_packet(&packet, cert))
- return FALSE;
- break;
- case PGP_PKT_USER_ID:
- DBG(DBG_PARSING,
- DBG_log("L3 - user ID:");
- DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
- )
- break;
- default:
- break;
- }
- }
- else
- {
- /* parse a PGP private key file */
- switch (packet_type)
- {
- case PGP_PKT_SECRET_KEY:
- if (!parse_pgp_secretkey_packet(&packet, key))
- return FALSE;
- break;
- default:
- break;
- }
- }
- }
- }
- return TRUE;
-}
-
-/*
- * compare two OpenPGP certificates
- */
-static bool
-same_pgpcert(pgpcert_t *a, pgpcert_t *b)
-{
- return a->certificate.len == b->certificate.len &&
- memcmp(a->certificate.ptr, b->certificate.ptr, b->certificate.len) == 0;
-}
-
-/*
- * for each link pointing to the certificate increase the count by one
- */
-void
-share_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- cert->count++;
-}
-
-/*
- * select the OpenPGP keyid as ID
- */
-void
-select_pgpcert_id(pgpcert_t *cert, struct id *end_id)
-{
- end_id->kind = ID_KEY_ID;
- end_id->name.len = PGP_FINGERPRINT_SIZE;
- end_id->name.ptr = cert->fingerprint;
- end_id->name.ptr = temporary_cyclic_buffer();
- memcpy(end_id->name.ptr, cert->fingerprint, PGP_FINGERPRINT_SIZE);
-}
-
-/*
- * add an OpenPGP user/host certificate to the chained list
- */
-pgpcert_t*
-add_pgpcert(pgpcert_t *cert)
-{
- pgpcert_t *c = pgpcerts;
-
- while (c != NULL)
- {
- if (same_pgpcert(c, cert)) /* already in chain, free cert */
- {
- free_pgpcert(cert);
- return c;
- }
- c = c->next;
- }
-
- /* insert new cert at the root of the chain */
- cert->next = pgpcerts;
- pgpcerts = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" pgp cert inserted")
- )
- return cert;
-}
-
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
- */
-void
-release_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL && --cert->count == 0)
- {
- pgpcert_t **pp = &pgpcerts;
- while (*pp != cert)
- pp = &(*pp)->next;
- *pp = cert->next;
- free_pgpcert(cert);
- }
-}
-
-/*
- * free a PGP certificate
- */
-void
-free_pgpcert(pgpcert_t *cert)
-{
- if (cert != NULL)
- {
- if (cert->certificate.ptr != NULL)
- pfree(cert->certificate.ptr);
- pfree(cert);
- }
-}
-
-/*
- * list all PGP end certificates in a chained list
- */
-void
-list_pgp_end_certs(bool utc)
-{
- pgpcert_t *cert = pgpcerts;
- time_t now;
-
- /* determine the current time */
- time(&now);
-
- if (cert != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of PGP End certificates:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (cert != NULL)
- {
- unsigned keysize;
- char buf[BUF_LEN];
- cert_t c;
-
- c.type = CERT_PGP;
- c.u.pgp = cert;
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc), cert->count);
- datatot(cert->fingerprint, PGP_FINGERPRINT_SIZE, 'x', buf, BUF_LEN);
- whack_log(RC_COMMENT, " fingerprint: %s", buf);
- form_keyid(cert->publicExponent, cert->modulus, buf, &keysize);
- whack_log(RC_COMMENT, " pubkey: %4d RSA Key %s%s", 8*keysize, buf,
- (has_private_key(c))? ", has private key" : "");
- whack_log(RC_COMMENT, " created: %s", timetoa(&cert->created, utc));
- whack_log(RC_COMMENT, " until: %s %s", timetoa(&cert->until, utc),
- check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
- cert = cert->next;
- }
-}
-
diff --git a/src/pluto/pgpcert.c b/src/pluto/pgpcert.c
new file mode 100644
index 000000000..7fb8232d5
--- /dev/null
+++ b/src/pluto/pgpcert.c
@@ -0,0 +1,496 @@
+/* Support of OpenPGP certificates
+ * Copyright (C) 2002-2009 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 <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <freeswan.h>
+
+#include <library.h>
+#include <pgp/pgp.h>
+#include <crypto/hashers/hasher.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "id.h"
+#include "pgpcert.h"
+#include "certs.h"
+#include "whack.h"
+#include "keys.h"
+
+/**
+ * Chained list of OpenPGP end certificates
+ */
+static pgpcert_t *pgpcerts = NULL;
+
+/**
+ * Size of PGP Key ID
+ */
+#define PGP_KEYID_SIZE 8
+
+const pgpcert_t pgpcert_empty = {
+ NULL , /* next */
+ 0 , /* version */
+ 0 , /* installed */
+ 0 , /* count */
+ { NULL, 0 }, /* certificate */
+ 0 , /* created */
+ 0 , /* until */
+ NULL , /* public key */
+ NULL /* fingerprint */
+};
+
+
+/**
+ * Extracts the length of a PGP packet
+ */
+static size_t pgp_old_packet_length(chunk_t *blob)
+{
+ /* bits 0 and 1 define the packet length type */
+ int len_type = 0x03 & *blob->ptr++;
+
+ blob->len--;
+
+ /* len_type: 0 -> 1 byte, 1 -> 2 bytes, 2 -> 4 bytes */
+ return pgp_length(blob, (len_type == 0)? 1: len_type << 1);
+}
+
+/**
+ * Extracts PGP packet version (V3 or V4)
+ */
+static u_char pgp_version(chunk_t *blob)
+{
+ u_char version = *blob->ptr++;
+ blob->len--;
+ DBG(DBG_PARSING,
+ DBG_log("L3 - version:");
+ DBG_log(" V%d", version)
+ )
+ return version;
+}
+
+/**
+ * Parse OpenPGP signature packet defined in section 5.2.2 of RFC 2440
+ */
+static bool parse_pgp_signature_packet(chunk_t *packet, pgpcert_t *cert)
+{
+ time_t created;
+ chunk_t keyid;
+ u_char sig_type;
+ u_char version = pgp_version(packet);
+
+ /* we parse only V3 signature packets */
+ if (version != 3)
+ {
+ return TRUE;
+ }
+
+ /* size byte must have the value 5 */
+ if (pgp_length(packet, 1) != 5)
+ {
+ plog(" size must be 5");
+ return FALSE;
+ }
+
+ /* signature type - 1 byte */
+ sig_type = (u_char)pgp_length(packet, 1);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - signature type: 0x%2x", sig_type)
+ )
+
+ /* creation date - 4 bytes */
+ created = (time_t)pgp_length(packet, 4);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - created:");
+ DBG_log(" %T", &cert->created, TRUE)
+ )
+
+ /* key ID of signer - 8 bytes */
+ keyid.ptr = packet->ptr;
+ keyid.len = PGP_KEYID_SIZE;
+ DBG_cond_dump_chunk(DBG_PARSING, "L3 - key ID of signer", keyid);
+
+ return TRUE;
+}
+
+/**
+ * Parses the version and validity of an OpenPGP public key packet
+ */
+static bool parse_pgp_pubkey_version_validity(chunk_t *packet, pgpcert_t *cert)
+{
+ cert->version = pgp_version(packet);
+
+ if (cert->version < 3 || cert->version > 4)
+ {
+ plog("OpenPGP packet version V%d not supported", cert->version);
+ return FALSE;
+ }
+
+ /* creation date - 4 bytes */
+ cert->created = (time_t)pgp_length(packet, 4);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - created:");
+ DBG_log(" %T", &cert->created, TRUE)
+ )
+
+ if (cert->version == 3)
+ {
+ /* validity in days - 2 bytes */
+ cert->until = (time_t)pgp_length(packet, 2);
+
+ /* validity of 0 days means that the key never expires */
+ if (cert->until > 0)
+ {
+ cert->until = cert->created + 24*3600*cert->until;
+ }
+ DBG(DBG_PARSING,
+ DBG_log("L3 - until:");
+ DBG_log(" %T", &cert->until, TRUE);
+ )
+ }
+ return TRUE;
+}
+
+/**
+ * Parse OpenPGP public key packet defined in section 5.5.2 of RFC 4880
+ */
+static bool parse_pgp_pubkey_packet(chunk_t *packet, pgpcert_t *cert)
+{
+ pgp_pubkey_alg_t pubkey_alg;
+ public_key_t *key;
+
+ if (!parse_pgp_pubkey_version_validity(packet, cert))
+ {
+ return FALSE;
+ }
+
+ /* public key algorithm - 1 byte */
+ pubkey_alg = pgp_length(packet, 1);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - public key algorithm:");
+ DBG_log(" %N", pgp_pubkey_alg_names, pubkey_alg)
+ )
+
+ switch (pubkey_alg)
+ {
+ case PGP_PUBKEY_ALG_RSA:
+ case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_PGP, *packet,
+ BUILD_END);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ cert->public_key = key;
+
+ if (cert->version == 3)
+ {
+ cert->fingerprint = key->get_id(key, ID_KEY_ID);
+ if (cert->fingerprint == NULL)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ plog(" computation of V4 key ID not implemented yet");
+ return FALSE;
+ }
+ break;
+ default:
+ plog(" non RSA public keys not supported");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Parse OpenPGP secret key packet defined in section 5.5.3 of RFC 4880
+ */
+static bool parse_pgp_secretkey_packet(chunk_t *packet, private_key_t **key)
+{
+ pgp_pubkey_alg_t pubkey_alg;
+ pgpcert_t cert = pgpcert_empty;
+
+ if (!parse_pgp_pubkey_version_validity(packet, &cert))
+ {
+ return FALSE;
+ }
+
+ /* public key algorithm - 1 byte */
+ pubkey_alg = pgp_length(packet, 1);
+ DBG(DBG_PARSING,
+ DBG_log("L3 - public key algorithm:");
+ DBG_log(" %N", pgp_pubkey_alg_names, pubkey_alg)
+ )
+
+ switch (pubkey_alg)
+ {
+ case PGP_PUBKEY_ALG_RSA:
+ case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
+ *key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_PGP, *packet,
+ BUILD_END);
+ break;
+ default:
+ plog(" non RSA private keys not supported");
+ return FALSE;
+ }
+ return (*key != NULL);
+}
+
+bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key)
+{
+ DBG(DBG_PARSING,
+ DBG_log("L0 - PGP file:")
+ )
+ DBG_cond_dump_chunk(DBG_RAW, "", blob);
+
+ if (cert != NULL)
+ {
+ /* parse a PGP certificate file */
+ cert->certificate = blob;
+ time(&cert->installed);
+ }
+ else if (key == NULL)
+ {
+ /* should not occur, nothing to parse */
+ return FALSE;
+ }
+
+ while (blob.len > 0)
+ {
+ chunk_t packet = chunk_empty;
+ u_char packet_tag = *blob.ptr;
+
+ DBG(DBG_PARSING,
+ DBG_log("L1 - PGP packet: tag= 0x%2x", packet_tag)
+ )
+
+ /* bit 7 must be set */
+ if (!(packet_tag & 0x80))
+ {
+ plog(" incorrect Packet Tag");
+ return FALSE;
+ }
+
+ /* bit 6 set defines new packet format */
+ if (packet_tag & 0x40)
+ {
+ plog(" new PGP packet format not supported");
+ return FALSE;
+ }
+ else
+ {
+ int packet_type = (packet_tag & 0x3C) >> 2;
+
+ packet.len = pgp_old_packet_length(&blob);
+ packet.ptr = blob.ptr;
+ blob.ptr += packet.len;
+ blob.len -= packet.len;
+ DBG(DBG_PARSING,
+ DBG_log(" %N (%d), old format, %u bytes",
+ pgp_packet_tag_names, packet_type,
+ packet_type, packet.len);
+ DBG_log("L2 - body:")
+ )
+ DBG_cond_dump_chunk(DBG_RAW, "", packet);
+
+ if (cert != NULL)
+ {
+ /* parse a PGP certificate */
+ switch (packet_type)
+ {
+ case PGP_PKT_PUBLIC_KEY:
+ if (!parse_pgp_pubkey_packet(&packet, cert))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_SIGNATURE:
+ if (!parse_pgp_signature_packet(&packet, cert))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_USER_ID:
+ DBG(DBG_PARSING,
+ DBG_log("L3 - user ID:");
+ DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
+ )
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ /* parse a PGP private key file */
+ switch (packet_type)
+ {
+ case PGP_PKT_SECRET_KEY:
+ if (!parse_pgp_secretkey_packet(&packet, key))
+ {
+ return FALSE;
+ }
+ break;
+ case PGP_PKT_USER_ID:
+ DBG(DBG_PARSING,
+ DBG_log("L3 - user ID:");
+ DBG_log(" '%.*s'", (int)packet.len, packet.ptr)
+ )
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Compare two OpenPGP certificates
+ */
+static bool same_pgpcert(pgpcert_t *a, pgpcert_t *b)
+{
+ return a->certificate.len == b->certificate.len &&
+ memeq(a->certificate.ptr, b->certificate.ptr, b->certificate.len);
+}
+
+/**
+ * For each link pointing to the certificate increase the count by one
+ */
+void share_pgpcert(pgpcert_t *cert)
+{
+ if (cert != NULL)
+ {
+ cert->count++;
+ }
+}
+
+/**
+ * Select the OpenPGP keyid as ID
+ */
+void select_pgpcert_id(pgpcert_t *cert, struct id *end_id)
+{
+ end_id->kind = ID_KEY_ID;
+ end_id->name = cert->fingerprint->get_encoding(cert->fingerprint);
+}
+
+/**
+ * Add an OpenPGP user/host certificate to the chained list
+ */
+pgpcert_t* add_pgpcert(pgpcert_t *cert)
+{
+ pgpcert_t *c = pgpcerts;
+
+ while (c != NULL)
+ {
+ if (same_pgpcert(c, cert)) /* already in chain, free cert */
+ {
+ free_pgpcert(cert);
+ return c;
+ }
+ c = c->next;
+ }
+
+ /* insert new cert at the root of the chain */
+ cert->next = pgpcerts;
+ pgpcerts = cert;
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" pgp cert inserted")
+ )
+ return cert;
+}
+
+/**
+ * Release of a certificate decreases the count by one.
+ * The certificate is freed when the counter reaches zero
+ */
+void release_pgpcert(pgpcert_t *cert)
+{
+ if (cert != NULL && --cert->count == 0)
+ {
+ pgpcert_t **pp = &pgpcerts;
+ while (*pp != cert)
+ {
+ pp = &(*pp)->next;
+ }
+ *pp = cert->next;
+ free_pgpcert(cert);
+ }
+}
+
+/**
+ * Free a PGP certificate
+ */
+void free_pgpcert(pgpcert_t *cert)
+{
+ if (cert != NULL)
+ {
+ DESTROY_IF(cert->public_key);
+ DESTROY_IF(cert->fingerprint);
+ free(cert->certificate.ptr);
+ free(cert);
+ }
+}
+
+/**
+ * List all PGP end certificates in a chained list
+ */
+void list_pgp_end_certs(bool utc)
+{
+ pgpcert_t *cert = pgpcerts;
+ time_t now;
+
+ /* determine the current time */
+ time(&now);
+
+ if (cert != NULL)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of PGP End certificates:");
+ whack_log(RC_COMMENT, " ");
+ }
+
+ while (cert != NULL)
+ {
+ public_key_t *key = cert->public_key;
+ cert_t c;
+
+ c.type = CERT_PGP;
+ c.u.pgp = cert;
+
+ whack_log(RC_COMMENT, "%T, count: %d", &cert->installed, utc, cert->count);
+ whack_log(RC_COMMENT, " digest: %Y", cert->fingerprint);
+ whack_log(RC_COMMENT, " created: %T", &cert->created, utc);
+ whack_log(RC_COMMENT, " until: %T %s", &cert->until, utc,
+ check_expiry(cert->until, CA_CERT_WARNING_INTERVAL, TRUE));
+ whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
+ key_type_names, key->get_type(key),
+ key->get_keysize(key) * BITS_PER_BYTE,
+ has_private_key(c)? ", has private key" : "");
+ whack_log(RC_COMMENT, " keyid: %Y",
+ key->get_id(key, ID_PUBKEY_INFO_SHA1));
+ cert = cert->next;
+ }
+}
+
diff --git a/src/pluto/pgp.h b/src/pluto/pgpcert.h
index 514265086..727648391 100644
--- a/src/pluto/pgp.h
+++ b/src/pluto/pgpcert.h
@@ -1,5 +1,7 @@
/* Support of OpenPGP certificates
- * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2002-2009 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
@@ -10,18 +12,19 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pgp.h 3252 2007-10-06 21:24:50Z andreas $
*/
-#ifndef _PGP_H
-#define _PGP_H
+#ifndef _PGPCERT_H
+#define _PGPCERT_H
+
+#include <crypto/hashers/hasher.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
-#include "pkcs1.h"
/*
* Length of PGP V3 fingerprint
*/
-#define PGP_FINGERPRINT_SIZE MD5_DIGEST_SIZE
+#define PGP_FINGERPRINT_SIZE HASH_SIZE_MD5
typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
@@ -30,20 +33,19 @@ typedef char fingerprint_t[PGP_FINGERPRINT_SIZE];
typedef struct pgpcert pgpcert_t;
struct pgpcert {
- pgpcert_t *next;
- time_t installed;
- int count;
- chunk_t certificate;
- time_t created;
- time_t until;
- enum pubkey_alg pubkeyAlg;
- chunk_t modulus;
- chunk_t publicExponent;
- fingerprint_t fingerprint;
+ pgpcert_t *next;
+ int version;
+ time_t installed;
+ int count;
+ chunk_t certificate;
+ time_t created;
+ time_t until;
+ public_key_t *public_key;
+ identification_t *fingerprint;
};
-extern const pgpcert_t empty_pgpcert;
-extern bool parse_pgp(chunk_t blob, pgpcert_t *cert, RSA_private_key_t *key);
+extern const pgpcert_t pgpcert_empty;
+extern bool parse_pgp(chunk_t blob, pgpcert_t *cert, private_key_t **key);
extern void share_pgpcert(pgpcert_t *cert);
extern void select_pgpcert_id(pgpcert_t *cert, struct id *end_id);
extern pgpcert_t* add_pgpcert(pgpcert_t *cert);
@@ -51,4 +53,4 @@ extern void list_pgp_end_certs(bool utc);
extern void release_pgpcert(pgpcert_t *cert);
extern void free_pgpcert(pgpcert_t *cert);
-#endif /* _PGP_H */
+#endif /* _PGPCERT_H */
diff --git a/src/pluto/pkcs1.c b/src/pluto/pkcs1.c
deleted file mode 100644
index 49a06a8bc..000000000
--- a/src/pluto/pkcs1.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/* Support of PKCS#1 private key data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs1.c 3427 2008-01-27 20:17:15Z andreas $
- */
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <freeswan.h>
-#include <libsha2/sha2.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "mp_defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
-#include "log.h"
-#include "pkcs1.h"
-#include "md2.h"
-#include "md5.h"
-#include "sha1.h"
-#include "rnd.h"
-
-const struct fld RSA_private_field[] =
-{
- { "Modulus", offsetof(RSA_private_key_t, pub.n) },
- { "PublicExponent", offsetof(RSA_private_key_t, pub.e) },
-
- { "PrivateExponent", offsetof(RSA_private_key_t, d) },
- { "Prime1", offsetof(RSA_private_key_t, p) },
- { "Prime2", offsetof(RSA_private_key_t, q) },
- { "Exponent1", offsetof(RSA_private_key_t, dP) },
- { "Exponent2", offsetof(RSA_private_key_t, dQ) },
- { "Coefficient", offsetof(RSA_private_key_t, qInv) },
-};
-
-/* ASN.1 definition of a PKCS#1 RSA private key */
-
-static const asn1Object_t privkeyObjects[] = {
- { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
- { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
- { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 10 */
- { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
- { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
- { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
-};
-
-#define PKCS1_PRIV_KEY_VERSION 1
-#define PKCS1_PRIV_KEY_MODULUS 2
-#define PKCS1_PRIV_KEY_PUB_EXP 3
-#define PKCS1_PRIV_KEY_COEFF 9
-#define PKCS1_PRIV_KEY_ROOF 16
-
-
-/*
- * forms the FreeS/WAN keyid from the public exponent e and modulus n
- */
-void
-form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize)
-{
- /* eliminate leading zero bytes in modulus from ASN.1 coding */
- while (n.len > 1 && *n.ptr == 0x00)
- {
- n.ptr++; n.len--;
- }
-
- /* form the FreeS/WAN keyid */
- keyid[0] = '\0'; /* in case of splitkeytoid failure */
- splitkeytoid(e.ptr, e.len, n.ptr, n.len, keyid, KEYID_BUF);
-
- /* return the RSA modulus size in octets */
- *keysize = n.len;
-}
-
-/*
- * initialize an RSA_public_key_t object
- */
-void
-init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n)
-{
- n_to_mpz(&rsa->e, e.ptr, e.len);
- n_to_mpz(&rsa->n, n.ptr, n.len);
-
- form_keyid(e, n, rsa->keyid, &rsa->k);
-}
-
-#ifdef DEBUG
-static void
-RSA_show_key_fields(RSA_private_key_t *k, int fieldcnt)
-{
- const struct fld *p;
-
- DBG_log(" keyid: *%s", k->pub.keyid);
-
- for (p = RSA_private_field; p < &RSA_private_field[fieldcnt]; p++)
- {
- MP_INT *n = (MP_INT *) ((char *)k + p->offset);
- size_t sz = mpz_sizeinbase(n, 16);
- char buf[RSA_MAX_OCTETS * 2 + 2]; /* ought to be big enough */
-
- passert(sz <= sizeof(buf));
- mpz_get_str(buf, 16, n);
-
- DBG_log(" %s: 0x%s", p->name, buf);
- }
-}
-
-/* debugging info that compromises security! */
-void
-RSA_show_private_key(RSA_private_key_t *k)
-{
- RSA_show_key_fields(k, elemsof(RSA_private_field));
-}
-
-void
-RSA_show_public_key(RSA_public_key_t *k)
-{
- /* Kludge: pretend that it is a private key, but only display the
- * first two fields (which are the public key).
- */
- passert(offsetof(RSA_private_key_t, pub) == 0);
- RSA_show_key_fields((RSA_private_key_t *)k, 2);
-}
-#endif
-
-err_t
-RSA_private_key_sanity(RSA_private_key_t *k)
-{
- /* note that the *last* error found is reported */
- err_t ugh = NULL;
- mpz_t t, u, q1;
-
-#ifdef DEBUG /* debugging info that compromises security */
- DBG(DBG_PRIVATE, RSA_show_private_key(k));
-#endif
-
- /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
- * We actually require more (for security).
- */
- if (k->pub.k < RSA_MIN_OCTETS)
- return RSA_MIN_OCTETS_UGH;
-
- /* we picked a max modulus size to simplify buffer allocation */
- if (k->pub.k > RSA_MAX_OCTETS)
- return RSA_MAX_OCTETS_UGH;
-
- mpz_init(t);
- mpz_init(u);
- mpz_init(q1);
-
- /* check that n == p * q */
- mpz_mul(u, &k->p, &k->q);
- if (mpz_cmp(u, &k->pub.n) != 0)
- ugh = "n != p * q";
-
- /* check that e divides neither p-1 nor q-1 */
- mpz_sub_ui(t, &k->p, 1);
- mpz_mod(t, t, &k->pub.e);
- if (mpz_cmp_ui(t, 0) == 0)
- ugh = "e divides p-1";
-
- mpz_sub_ui(t, &k->q, 1);
- mpz_mod(t, t, &k->pub.e);
- if (mpz_cmp_ui(t, 0) == 0)
- ugh = "e divides q-1";
-
- /* check that d is e^-1 (mod lcm(p-1, q-1)) */
- /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
- mpz_sub_ui(q1, &k->q, 1);
- mpz_sub_ui(u, &k->p, 1);
- mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
- mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
- mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
-
- mpz_mul(t, &k->d, &k->pub.e);
- mpz_mod(t, t, u);
- if (mpz_cmp_ui(t, 1) != 0)
- ugh = "(d * e) mod (lcm(p-1, q-1)) != 1";
-
- /* check that dP is d mod (p-1) */
- mpz_sub_ui(u, &k->p, 1);
- mpz_mod(t, &k->d, u);
- if (mpz_cmp(t, &k->dP) != 0)
- ugh = "dP is not congruent to d mod (p-1)";
-
- /* check that dQ is d mod (q-1) */
- mpz_sub_ui(u, &k->q, 1);
- mpz_mod(t, &k->d, u);
- if (mpz_cmp(t, &k->dQ) != 0)
- ugh = "dQ is not congruent to d mod (q-1)";
-
- /* check that qInv is (q^-1) mod p */
- mpz_mul(t, &k->qInv, &k->q);
- mpz_mod(t, t, &k->p);
- if (mpz_cmp_ui(t, 1) != 0)
- ugh = "qInv is not conguent ot (q^-1) mod p";
-
- mpz_clear(t);
- mpz_clear(u);
- mpz_clear(q1);
- return ugh;
-}
-
-/*
- * Check the equality of two RSA public keys
- */
-bool
-same_RSA_public_key(const RSA_public_key_t *a, const RSA_public_key_t *b)
-{
- return a == b
- || (a->k == b->k && mpz_cmp(&a->n, &b->n) == 0 && mpz_cmp(&a->e, &b->e) == 0);
-}
-
-/*
- * Parses a PKCS#1 private key
- */
-bool
-pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key)
-{
- err_t ugh = NULL;
- asn1_ctx_t ctx;
- chunk_t object, modulus, exp;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_PRIVATE);
-
- while (objectID < PKCS1_PRIV_KEY_ROOF) {
-
- if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- if (objectID == PKCS1_PRIV_KEY_VERSION)
- {
- if (object.len > 0 && *object.ptr != 0)
- {
- plog(" wrong PKCS#1 private key version");
- return FALSE;
- }
- }
- else if (objectID >= PKCS1_PRIV_KEY_MODULUS &&
- objectID <= PKCS1_PRIV_KEY_COEFF)
- {
- MP_INT *u = (MP_INT *) ((char *)key
- + RSA_private_field[objectID - PKCS1_PRIV_KEY_MODULUS].offset);
-
- n_to_mpz(u, object.ptr, object.len);
-
- if (objectID == PKCS1_PRIV_KEY_MODULUS)
- modulus = object;
- else if (objectID == PKCS1_PRIV_KEY_PUB_EXP)
- exp = object;
- }
- objectID++;
- }
- form_keyid(exp, modulus, key->pub.keyid, &key->pub.k);
- ugh = RSA_private_key_sanity(key);
- return (ugh == NULL);
-}
-
-/*
- * compute a digest over a binary blob
- */
-bool
-compute_digest(chunk_t tbs, int alg, chunk_t *digest)
-{
- switch (alg)
- {
- case OID_MD2:
- case OID_MD2_WITH_RSA:
- {
- MD2_CTX context;
-
- MD2Init(&context);
- MD2Update(&context, tbs.ptr, tbs.len);
- MD2Final(digest->ptr, &context);
- digest->len = MD2_DIGEST_SIZE;
- return TRUE;
- }
- case OID_MD5:
- case OID_MD5_WITH_RSA:
- {
- MD5_CTX context;
-
- MD5Init(&context);
- MD5Update(&context, tbs.ptr, tbs.len);
- MD5Final(digest->ptr, &context);
- digest->len = MD5_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA1:
- case OID_SHA1_WITH_RSA:
- case OID_SHA1_WITH_RSA_OIW:
- {
- SHA1_CTX context;
-
- SHA1Init(&context);
- SHA1Update(&context, tbs.ptr, tbs.len);
- SHA1Final(digest->ptr, &context);
- digest->len = SHA1_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA256:
- case OID_SHA256_WITH_RSA:
- {
- sha256_context context;
-
- sha256_init(&context);
- sha256_write(&context, tbs.ptr, tbs.len);
- sha256_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_256_DIGEST_SIZE);
- digest->len = SHA2_256_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA384:
- case OID_SHA384_WITH_RSA:
- {
- sha512_context context;
-
- sha384_init(&context);
- sha512_write(&context, tbs.ptr, tbs.len);
- sha512_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_384_DIGEST_SIZE);
- digest->len = SHA2_384_DIGEST_SIZE;
- return TRUE;
- }
- case OID_SHA512:
- case OID_SHA512_WITH_RSA:
- {
- sha512_context context;
-
- sha512_init(&context);
- sha512_write(&context, tbs.ptr, tbs.len);
- sha512_final(&context);
- memcpy(digest->ptr, context.sha_out, SHA2_512_DIGEST_SIZE);
- digest->len = SHA2_512_DIGEST_SIZE;
- return TRUE;
- }
- default:
- digest->len = 0;
- return FALSE;
- }
-}
-
-/*
- * compute an RSA signature with PKCS#1 padding
- */
-void
-sign_hash(const RSA_private_key_t *k, const u_char *hash_val, size_t hash_len
- , u_char *sig_val, size_t sig_len)
-{
- chunk_t ch;
- mpz_t t1, t2;
- size_t padlen;
- u_char *p = sig_val;
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("signing hash with RSA Key *%s", k->pub.keyid)
- )
- /* PKCS#1 v1.5 8.1 encryption-block formatting */
- *p++ = 0x00;
- *p++ = 0x01; /* BT (block type) 01 */
- padlen = sig_len - 3 - hash_len;
- memset(p, 0xFF, padlen);
- p += padlen;
- *p++ = 0x00;
- memcpy(p, hash_val, hash_len);
- passert(p + hash_len - sig_val == (ptrdiff_t)sig_len);
-
- /* PKCS#1 v1.5 8.2 octet-string-to-integer conversion */
- n_to_mpz(t1, sig_val, sig_len); /* (could skip leading 0x00) */
-
- /* PKCS#1 v1.5 8.3 RSA computation y = x^c mod n
- * Better described in PKCS#1 v2.0 5.1 RSADP.
- * There are two methods, depending on the form of the private key.
- * We use the one based on the Chinese Remainder Theorem.
- */
- mpz_init(t2);
-
- mpz_powm(t2, t1, &k->dP, &k->p); /* m1 = c^dP mod p */
-
- mpz_powm(t1, t1, &k->dQ, &k->q); /* m2 = c^dQ mod Q */
-
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, &k->p);
- mpz_mul(t2, t2, &k->qInv);
- mpz_mod(t2, t2, &k->p);
-
- mpz_mul(t2, t2, &k->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- /* PKCS#1 v1.5 8.4 integer-to-octet-string conversion */
- ch = mpz_to_n(t1, sig_len);
- memcpy(sig_val, ch.ptr, sig_len);
- pfree(ch.ptr);
-
- mpz_clear(t1);
- mpz_clear(t2);
-}
-
-/*
- * encrypt data with an RSA public key after padding
- */
-chunk_t
-RSA_encrypt(const RSA_public_key_t *key, chunk_t in)
-{
- u_char padded[RSA_MAX_OCTETS];
- u_char *pos = padded;
- int padding = key->k - in.len - 3;
- int i;
-
- if (padding < 8 || key->k > RSA_MAX_OCTETS)
- return empty_chunk;
-
- /* add padding according to PKCS#1 7.2.1 1.+2. */
- *pos++ = 0x00;
- *pos++ = 0x02;
-
- /* pad with pseudo random bytes unequal to zero */
- for (i = 0; i < padding; i++)
- {
- get_rnd_bytes(pos, padding);
- while (!*pos)
- {
- get_rnd_bytes(pos, 1);
- }
- pos++;
- }
-
- /* append the padding terminator */
- *pos++ = 0x00;
-
- /* now add the data */
- memcpy(pos, in.ptr, in.len);
- DBG(DBG_RAW,
- DBG_dump_chunk("data for rsa encryption:\n", in);
- DBG_dump("padded data for rsa encryption:\n", padded, key->k)
- )
-
- /* convert chunk to integer (PKCS#1 7.2.1 3.a) */
- {
- chunk_t out;
- mpz_t m, c;
-
- mpz_init(c);
- n_to_mpz(m, padded, key->k);
-
- /* encrypt(PKCS#1 7.2.1 3.b) */
- mpz_powm(c, m, &key->e, &key->n);
-
- /* convert integer back to a chunk (PKCS#1 7.2.1 3.c) */
- out = mpz_to_n(c, key->k);
- mpz_clear(c);
- mpz_clear(m);
-
- DBG(DBG_RAW,
- DBG_dump_chunk("rsa encrypted data:\n", out)
- )
- return out;
- }
-}
-
-/*
- * decrypt data with an RSA private key and remove padding
- */
-bool
-RSA_decrypt(const RSA_private_key_t *key, chunk_t in, chunk_t *out)
-{
- chunk_t padded;
- u_char *pos;
- mpz_t t1, t2;
-
- n_to_mpz(t1, in.ptr,in.len);
-
- /* PKCS#1 v1.5 8.3 RSA computation y = x^c mod n
- * Better described in PKCS#1 v2.0 5.1 RSADP.
- * There are two methods, depending on the form of the private key.
- * We use the one based on the Chinese Remainder Theorem.
- */
- mpz_init(t2);
-
- mpz_powm(t2, t1, &key->dP, &key->p); /* m1 = c^dP mod p */
- mpz_powm(t1, t1, &key->dQ, &key->q); /* m2 = c^dQ mod Q */
-
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, &key->p);
- mpz_mul(t2, t2, &key->qInv);
- mpz_mod(t2, t2, &key->p);
-
- mpz_mul(t2, t2, &key->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- padded = mpz_to_n(t1, key->pub.k);
- mpz_clear(t1);
- mpz_clear(t2);
-
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("rsa decrypted data with padding:\n", padded)
- )
- pos = padded.ptr;
-
- /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */
-
- /* check for hex pattern 00 02 in decrypted message */
- if ((*pos++ != 0x00) || (*(pos++) != 0x02))
- {
- plog("incorrect padding - probably wrong RSA key");
- freeanychunk(padded);
- return FALSE;
- }
- padded.len -= 2;
-
- /* the plaintext data starts after first 0x00 byte */
- while (padded.len-- > 0 && *pos++ != 0x00)
-
- if (padded.len == 0)
- {
- plog("no plaintext data");
- freeanychunk(padded);
- return FALSE;
- }
-
- clonetochunk(*out, pos, padded.len, "decrypted data");
- freeanychunk(padded);
- return TRUE;
-}
-
-/*
- * build signatureValue
- */
-chunk_t
-pkcs1_build_signature(chunk_t tbs, int hash_alg, const RSA_private_key_t *key
-, bool bit_string)
-{
-
- size_t siglen = key->pub.k;
-
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest = { digest_buf, MAX_DIGEST_LEN };
- chunk_t digestInfo, alg_id, signatureValue;
- u_char *pos;
-
- switch (hash_alg)
- {
- case OID_MD5:
- case OID_MD5_WITH_RSA:
- alg_id = ASN1_md5_id;
- break;
- case OID_SHA1:
- case OID_SHA1_WITH_RSA:
- alg_id = ASN1_sha1_id;
- break;
- default:
- return empty_chunk;
- }
- compute_digest(tbs, hash_alg, &digest);
-
- /* according to PKCS#1 v2.1 digest must be packaged into
- * an ASN.1 structure for encryption
- */
- digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm"
- , alg_id
- , asn1_simple_object(ASN1_OCTET_STRING, digest));
-
- /* generate the RSA signature */
- if (bit_string)
- {
- pos = build_asn1_object(&signatureValue, ASN1_BIT_STRING, 1 + siglen);
- *pos++ = 0x00;
- }
- else
- {
- pos = build_asn1_object(&signatureValue, ASN1_OCTET_STRING, siglen);
- }
- sign_hash(key, digestInfo.ptr, digestInfo.len, pos, siglen);
- pfree(digestInfo.ptr);
-
- return signatureValue;
-}
-
-/*
- * build a DER-encoded PKCS#1 private key object
- */
-chunk_t
-pkcs1_build_private_key(const RSA_private_key_t *key)
-{
- chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm"
- , ASN1_INTEGER_0
- , asn1_integer_from_mpz(&key->pub.n)
- , asn1_integer_from_mpz(&key->pub.e)
- , asn1_integer_from_mpz(&key->d)
- , asn1_integer_from_mpz(&key->p)
- , asn1_integer_from_mpz(&key->q)
- , asn1_integer_from_mpz(&key->dP)
- , asn1_integer_from_mpz(&key->dQ)
- , asn1_integer_from_mpz(&key->qInv));
-
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("PKCS#1 encoded private key:", pkcs1)
- )
- return pkcs1;
-}
-
-/*
- * build a DER-encoded PKCS#1 public key object
- */
-chunk_t
-pkcs1_build_public_key(const RSA_public_key_t *rsa)
-{
- return asn1_wrap(ASN1_SEQUENCE, "mm"
- , asn1_integer_from_mpz(&rsa->n)
- , asn1_integer_from_mpz(&rsa->e));
-}
-
-/*
- * build a DER-encoded publicKeyInfo object
- */
-chunk_t
-pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa)
-{
- chunk_t publicKey;
- chunk_t rawKey = pkcs1_build_public_key(rsa);
-
- u_char *pos = build_asn1_object(&publicKey, ASN1_BIT_STRING
- , 1 + rawKey.len);
- *pos++ = 0x00;
- mv_chunk(&pos, rawKey);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_rsaEncryption_id
- , publicKey);
-}
-void
-free_RSA_public_content(RSA_public_key_t *rsa)
-{
- mpz_clear(&rsa->n);
- mpz_clear(&rsa->e);
-}
-
-void
-free_RSA_private_content(RSA_private_key_t *rsak)
-{
- free_RSA_public_content(&rsak->pub);
- mpz_clear(&rsak->d);
- mpz_clear(&rsak->p);
- mpz_clear(&rsak->q);
- mpz_clear(&rsak->dP);
- mpz_clear(&rsak->dQ);
- mpz_clear(&rsak->qInv);
-}
-
diff --git a/src/pluto/pkcs1.h b/src/pluto/pkcs1.h
deleted file mode 100644
index 16a6f02b9..000000000
--- a/src/pluto/pkcs1.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Support of PKCS#1 private key data structures
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: pkcs1.h 3252 2007-10-06 21:24:50Z andreas $
- */
-
-#ifndef _PKCS1_H
-#define _PKCS1_H
-
-#include <gmp.h> /* GNU Multi Precision library */
-
-#include "defs.h"
-
-typedef struct RSA_public_key RSA_public_key_t;
-
-struct RSA_public_key
-{
- char keyid[KEYID_BUF]; /* see ipsec_keyblobtoid(3) */
-
- /* length of modulus n in octets: [RSA_MIN_OCTETS, RSA_MAX_OCTETS] */
- unsigned k;
-
- /* public: */
- MP_INT
- n, /* modulus: p * q */
- e; /* exponent: relatively prime to (p-1) * (q-1) [probably small] */
-};
-
-typedef struct RSA_private_key RSA_private_key_t;
-
-struct RSA_private_key {
- struct RSA_public_key pub; /* must be at start for RSA_show_public_key */
-
- MP_INT
- d, /* private exponent: (e^-1) mod ((p-1) * (q-1)) */
- /* help for Chinese Remainder Theorem speedup: */
- p, /* first secret prime */
- q, /* second secret prime */
- dP, /* first factor's exponent: (e^-1) mod (p-1) == d mod (p-1) */
- dQ, /* second factor's exponent: (e^-1) mod (q-1) == d mod (q-1) */
- qInv; /* (q^-1) mod p */
-};
-
-struct fld {
- const char *name;
- size_t offset;
-};
-
-extern const struct fld RSA_private_field[];
-#define RSA_PRIVATE_FIELD_ELEMENTS 8
-
-extern void init_RSA_public_key(RSA_public_key_t *rsa, chunk_t e, chunk_t n);
-extern bool pkcs1_parse_private_key(chunk_t blob, RSA_private_key_t *key);
-extern chunk_t pkcs1_build_private_key(const RSA_private_key_t *key);
-extern chunk_t pkcs1_build_public_key(const RSA_public_key_t *rsa);
-extern chunk_t pkcs1_build_publicKeyInfo(const RSA_public_key_t *rsa);
-extern chunk_t pkcs1_build_signature(chunk_t tbs, int hash_alg
- , const RSA_private_key_t *key, bool bit_string);
-extern bool compute_digest(chunk_t tbs, int alg, chunk_t *digest);
-extern void sign_hash(const RSA_private_key_t *k, const u_char *hash_val
- , size_t hash_len, u_char *sig_val, size_t sig_len);
-extern chunk_t RSA_encrypt(const RSA_public_key_t *key, chunk_t in);
-extern bool RSA_decrypt(const RSA_private_key_t *key, chunk_t in
- , chunk_t *out);
-extern bool same_RSA_public_key(const RSA_public_key_t *a
- , const RSA_public_key_t *b);
-extern void form_keyid(chunk_t e, chunk_t n, char* keyid, unsigned *keysize);
-extern err_t RSA_private_key_sanity(RSA_private_key_t *k);
-#ifdef DEBUG
-extern void RSA_show_public_key(RSA_public_key_t *k);
-extern void RSA_show_private_key(RSA_private_key_t *k);
-#endif
-extern void free_RSA_public_content(RSA_public_key_t *rsa);
-extern void free_RSA_private_content(RSA_private_key_t *rsak);
-
-#endif /* _PKCS1_H */
diff --git a/src/pluto/pkcs7.c b/src/pluto/pkcs7.c
index 60636f385..7248b042f 100644
--- a/src/pluto/pkcs7.c
+++ b/src/pluto/pkcs7.c
@@ -1,7 +1,8 @@
/* Support of PKCS#7 data structures
* Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
+ * Copyright (C) 2002-2009 Andreas Steffen
+ *
+ * HSR Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -12,564 +13,562 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pkcs7.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdlib.h>
#include <string.h>
-#include <libdes/des.h>
#include <freeswan.h>
+#include <library.h>
+#include <debug.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+#include <crypto/rngs/rng.h>
+#include <crypto/crypters/crypter.h>
+
#include "constants.h"
#include "defs.h"
-#include "asn1.h"
-#include <asn1/oid.h>
-#include "log.h"
#include "x509.h"
#include "certs.h"
#include "pkcs7.h"
-#include "rnd.h"
const contentInfo_t empty_contentInfo = {
- OID_UNKNOWN , /* type */
- { NULL, 0 } /* content */
+ OID_UNKNOWN , /* type */
+ { NULL, 0 } /* content */
};
-/* ASN.1 definition of the PKCS#7 ContentInfo type */
-
+/**
+ * ASN.1 definition of the PKCS#7 ContentInfo type
+ */
static const asn1Object_t contentInfoObjects[] = {
- { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
+ { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define PKCS7_INFO_TYPE 1
+#define PKCS7_INFO_CONTENT 2
-#define PKCS7_INFO_TYPE 1
-#define PKCS7_INFO_CONTENT 2
-#define PKCS7_INFO_ROOF 4
-
-/* ASN.1 definition of the PKCS#7 signedData type */
-
+/**
+ * ASN.1 definition of the PKCS#7 signedData type
+ */
static const asn1Object_t signedDataObjects[] = {
- { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 6 */
- { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
- { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_LOOP }, /* 9 */
- { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
- { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
- { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
- { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
- { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
- { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
- { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */
+ { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
+ { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
+ { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 6 */
+ { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
+ { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
+ { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 9 */
+ { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
+ { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
+ { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
+ { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
+ { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
+ { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
+ { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
+ { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
+ { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 19 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
+ { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
+ { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
+ { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
+ { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define PKCS7_DIGEST_ALG 3
+#define PKCS7_SIGNED_CONTENT_INFO 5
+#define PKCS7_SIGNED_CERT 7
+#define PKCS7_SIGNER_INFO 13
+#define PKCS7_SIGNED_ISSUER 16
+#define PKCS7_SIGNED_SERIAL_NUMBER 17
+#define PKCS7_DIGEST_ALGORITHM 18
+#define PKCS7_AUTH_ATTRIBUTES 19
+#define PKCS7_DIGEST_ENC_ALGORITHM 21
+#define PKCS7_ENCRYPTED_DIGEST 22
-#define PKCS7_DIGEST_ALG 3
-#define PKCS7_SIGNED_CONTENT_INFO 5
-#define PKCS7_SIGNED_CERT 7
-#define PKCS7_SIGNER_INFO 13
-#define PKCS7_SIGNED_ISSUER 16
-#define PKCS7_SIGNED_SERIAL_NUMBER 17
-#define PKCS7_DIGEST_ALGORITHM 18
-#define PKCS7_AUTH_ATTRIBUTES 19
-#define PKCS7_DIGEST_ENC_ALGORITHM 21
-#define PKCS7_ENCRYPTED_DIGEST 22
-#define PKCS7_SIGNED_ROOF 26
-
-/* ASN.1 definition of the PKCS#7 envelopedData type */
-
+/**
+ * ASN.1 definition of the PKCS#7 envelopedData type
+ */
static const asn1Object_t envelopedDataObjects[] = {
- { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
- { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
- { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
- { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */
+ { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
+ { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
+ { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
+ { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
+ { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
+ { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
+ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
+ { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
+ { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
+ { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
+ { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY }, /* 14 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define PKCS7_ENVELOPED_VERSION 1
+#define PKCS7_RECIPIENT_INFO_VERSION 4
+#define PKCS7_ISSUER 6
+#define PKCS7_SERIAL_NUMBER 7
+#define PKCS7_ENCRYPTION_ALG 8
+#define PKCS7_ENCRYPTED_KEY 9
+#define PKCS7_CONTENT_TYPE 12
+#define PKCS7_CONTENT_ENC_ALGORITHM 13
+#define PKCS7_ENCRYPTED_CONTENT 14
+#define PKCS7_ENVELOPED_ROOF 15
-#define PKCS7_ENVELOPED_VERSION 1
-#define PKCS7_RECIPIENT_INFO_VERSION 4
-#define PKCS7_ISSUER 6
-#define PKCS7_SERIAL_NUMBER 7
-#define PKCS7_ENCRYPTION_ALG 8
-#define PKCS7_ENCRYPTED_KEY 9
-#define PKCS7_CONTENT_TYPE 12
-#define PKCS7_CONTENT_ENC_ALGORITHM 13
-#define PKCS7_ENCRYPTED_CONTENT 14
-#define PKCS7_ENVELOPED_ROOF 15
-
-/* PKCS7 contentInfo OIDs */
+/**
+ * PKCS7 contentInfo OIDs
+ */
static u_char ASN1_pkcs7_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
};
static u_char ASN1_pkcs7_signed_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
};
static u_char ASN1_pkcs7_enveloped_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
};
static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
};
static u_char ASN1_pkcs7_digested_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
};
static char ASN1_pkcs7_encrypted_data_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
};
static const chunk_t ASN1_pkcs7_data_oid =
- strchunk(ASN1_pkcs7_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_data_oid_str);
static const chunk_t ASN1_pkcs7_signed_data_oid =
- strchunk(ASN1_pkcs7_signed_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_signed_data_oid_str);
static const chunk_t ASN1_pkcs7_enveloped_data_oid =
- strchunk(ASN1_pkcs7_enveloped_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_enveloped_data_oid_str);
static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid =
- strchunk(ASN1_pkcs7_signed_enveloped_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_signed_enveloped_data_oid_str);
static const chunk_t ASN1_pkcs7_digested_data_oid =
- strchunk(ASN1_pkcs7_digested_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_digested_data_oid_str);
static const chunk_t ASN1_pkcs7_encrypted_data_oid =
- strchunk(ASN1_pkcs7_encrypted_data_oid_str);
+ chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str);
-/* 3DES and DES encryption OIDs */
+/**
+ * 3DES and DES encryption OIDs
+ */
static u_char ASN1_3des_ede_cbc_oid_str[] = {
- 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
+ 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
};
static u_char ASN1_des_cbc_oid_str[] = {
- 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x07
+ 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x07
};
static const chunk_t ASN1_3des_ede_cbc_oid =
- strchunk(ASN1_3des_ede_cbc_oid_str);
+ chunk_from_buf(ASN1_3des_ede_cbc_oid_str);
static const chunk_t ASN1_des_cbc_oid =
- strchunk(ASN1_des_cbc_oid_str);
+ chunk_from_buf(ASN1_des_cbc_oid_str);
-/* PKCS#7 attribute type OIDs */
+/**
+ * PKCS#7 attribute type OIDs
+ */
static u_char ASN1_contentType_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03
};
static u_char ASN1_messageDigest_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04
};
static const chunk_t ASN1_contentType_oid =
- strchunk(ASN1_contentType_oid_str);
+ chunk_from_buf(ASN1_contentType_oid_str);
static const chunk_t ASN1_messageDigest_oid =
- strchunk(ASN1_messageDigest_oid_str);
+ chunk_from_buf(ASN1_messageDigest_oid_str);
-/*
+/**
* Parse PKCS#7 ContentInfo object
*/
-bool
-pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
+bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0, contentInfo_t *cInfo)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
- while (objectID < PKCS7_INFO_ROOF)
- {
- if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
- return FALSE;
+ parser = asn1_parser_create(contentInfoObjects, blob);
+ parser->set_top_level(parser, level0);
- if (objectID == PKCS7_INFO_TYPE)
+ while (parser->iterate(parser, &objectID, &object))
{
- cInfo->type = known_oid(object);
- if (cInfo->type < OID_PKCS7_DATA
- || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
- {
- plog("unknown pkcs7 content type");
- return FALSE;
- }
- }
- else if (objectID == PKCS7_INFO_CONTENT)
- {
- cInfo->content = object;
+ if (objectID == PKCS7_INFO_TYPE)
+ {
+ cInfo->type = asn1_known_oid(object);
+ if (cInfo->type < OID_PKCS7_DATA
+ || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
+ {
+ DBG1("unknown pkcs7 content type");
+ goto end;
+ }
+ }
+ else if (objectID == PKCS7_INFO_CONTENT)
+ {
+ cInfo->content = object;
+ }
}
- objectID++;
- }
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
-/*
+/**
* Parse a PKCS#7 signedData object
*/
-bool
-pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert
-, chunk_t *attributes, const x509cert_t *cacert)
+bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data, x509cert_t **cert,
+ chunk_t *attributes, const x509cert_t *cacert)
{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int digest_alg = OID_UNKNOWN;
- int enc_alg = OID_UNKNOWN;
- int signerInfos = 0;
- int objectID = 0;
-
- contentInfo_t cInfo = empty_contentInfo;
- chunk_t encrypted_digest = empty_chunk;
-
- if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
- return FALSE;
-
- if (cInfo.type != OID_PKCS7_SIGNED_DATA)
- {
- plog("pkcs7 content type is not signedData");
- return FALSE;
- }
-
- asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
-
- while (objectID < PKCS7_SIGNED_ROOF)
- {
- if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case PKCS7_DIGEST_ALG:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_SIGNED_CONTENT_INFO:
- if (data != NULL)
- {
- pkcs7_parse_contentInfo(object, level, data);
- }
- break;
- case PKCS7_SIGNED_CERT:
- if (cert != NULL)
- {
- chunk_t cert_blob;
-
- x509cert_t *newcert = alloc_thing(x509cert_t
- , "pkcs7 wrapped x509cert");
-
- clonetochunk(cert_blob, object.ptr, object.len
- , "pkcs7 cert blob");
- *newcert = empty_x509cert;
-
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("parsing pkcs7-wrapped certificate")
- )
- if (parse_x509cert(cert_blob, level+1, newcert))
- {
- newcert->next = *cert;
- *cert = newcert;
- }
- else
- {
- free_x509cert(newcert);
- }
- }
- break;
- case PKCS7_SIGNER_INFO:
- signerInfos++;
- DBG(DBG_PARSING,
- DBG_log(" signer #%d", signerInfos)
- )
- break;
- case PKCS7_SIGNED_ISSUER:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case PKCS7_AUTH_ATTRIBUTES:
- if (attributes != NULL)
- {
- *attributes = object;
- *attributes->ptr = ASN1_SET;
- }
- break;
- case PKCS7_DIGEST_ALGORITHM:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_DIGEST_ENC_ALGORITHM:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_ENCRYPTED_DIGEST:
- encrypted_digest = object;
- }
- objectID++;
- }
-
- /* check the signature only if a cacert is available */
- if (cacert != NULL)
- {
- if (signerInfos == 0)
+ u_char buf[BUF_LEN];
+ asn1_parser_t *parser;
+ chunk_t object;
+ int digest_alg = OID_UNKNOWN;
+ int enc_alg = OID_UNKNOWN;
+ int signerInfos = 0;
+ int objectID;
+ bool success = FALSE;
+
+ contentInfo_t cInfo = empty_contentInfo;
+ chunk_t encrypted_digest = chunk_empty;
+
+ if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
{
- plog("no signerInfo object found");
- return FALSE;
+ return FALSE;
}
- else if (signerInfos > 1)
+ if (cInfo.type != OID_PKCS7_SIGNED_DATA)
{
- plog("more than one signerInfo object found");
- return FALSE;
+ DBG1("pkcs7 content type is not signedData");
+ return FALSE;
}
- if (attributes->ptr == NULL)
+
+ parser = asn1_parser_create(signedDataObjects, blob);
+ parser->set_top_level(parser, 2);
+
+ while (parser->iterate(parser, &objectID, &object))
{
- plog("no authenticatedAttributes object found");
- return FALSE;
+ u_int level = parser->get_level(parser);
+
+ switch (objectID)
+ {
+ case PKCS7_DIGEST_ALG:
+ digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case PKCS7_SIGNED_CONTENT_INFO:
+ if (data != NULL)
+ {
+ pkcs7_parse_contentInfo(object, level, data);
+ }
+ break;
+ case PKCS7_SIGNED_CERT:
+ if (cert != NULL)
+ {
+ chunk_t cert_blob = chunk_clone(object);
+ x509cert_t *newcert = malloc_thing(x509cert_t);
+
+ *newcert = empty_x509cert;
+
+ DBG2(" parsing pkcs7-wrapped certificate");
+ if (parse_x509cert(cert_blob, level+1, newcert))
+ {
+ newcert->next = *cert;
+ *cert = newcert;
+ }
+ else
+ {
+ free_x509cert(newcert);
+ }
+ }
+ break;
+ case PKCS7_SIGNER_INFO:
+ signerInfos++;
+ DBG2(" signer #%d", signerInfos);
+ break;
+ case PKCS7_SIGNED_ISSUER:
+ dntoa(buf, BUF_LEN, object);
+ DBG2(" '%s'",buf);
+ break;
+ case PKCS7_AUTH_ATTRIBUTES:
+ if (attributes != NULL)
+ {
+ *attributes = object;
+ *attributes->ptr = ASN1_SET;
+ }
+ break;
+ case PKCS7_DIGEST_ALGORITHM:
+ digest_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case PKCS7_DIGEST_ENC_ALGORITHM:
+ enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case PKCS7_ENCRYPTED_DIGEST:
+ encrypted_digest = object;
+ }
}
- if (!check_signature(*attributes, encrypted_digest, digest_alg
- , enc_alg, cacert))
+ success = parser->success(parser);
+ parser->destroy(parser);
+ if (!success)
{
- plog("invalid signature");
- return FALSE;
+ return FALSE;
}
- else
+
+ /* check the signature only if a cacert is available */
+ if (cacert != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("signature is valid")
- )
+ public_key_t *key = cacert->public_key;
+ signature_scheme_t scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+
+ if (signerInfos == 0)
+ {
+ DBG1("no signerInfo object found");
+ return FALSE;
+ }
+ else if (signerInfos > 1)
+ {
+ DBG1("more than one signerInfo object found");
+ return FALSE;
+ }
+ if (attributes->ptr == NULL)
+ {
+ DBG1("no authenticatedAttributes object found");
+ return FALSE;
+ }
+ if (enc_alg != OID_RSA_ENCRYPTION)
+ {
+ DBG1("only RSA digest encryption supported");
+ return FALSE;
+ }
+
+ /* determine signature scheme */
+ scheme = signature_scheme_from_oid(digest_alg);
+
+ if (scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ if (key->verify(key, scheme, *attributes, encrypted_digest))
+ {
+ DBG2("signature is valid");
+ }
+ else
+ {
+ DBG1("invalid signature");
+ return FALSE;
+ }
}
- }
- return TRUE;
+ return TRUE;
}
-/*
+/**
* Parse a PKCS#7 envelopedData object
*/
-bool
-pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
-, chunk_t serialNumber, const RSA_private_key_t *key)
+bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
+ chunk_t serialNumber,
+ private_key_t *key)
{
- asn1_ctx_t ctx;
- chunk_t object;
- chunk_t iv = empty_chunk;
- chunk_t symmetric_key = empty_chunk;
- chunk_t encrypted_content = empty_chunk;
-
- u_char buf[BUF_LEN];
- u_int level;
- u_int total_keys = 3;
- int enc_alg = OID_UNKNOWN;
- int content_enc_alg = OID_UNKNOWN;
- int objectID = 0;
-
- contentInfo_t cInfo = empty_contentInfo;
- *data = empty_chunk;
-
- if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
- goto failed;
-
- if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
- {
- plog("pkcs7 content type is not envelopedData");
- return FALSE;
- }
-
- asn1_init(&ctx, cInfo.content, 2, FALSE, DBG_RAW);
-
- while (objectID < PKCS7_ENVELOPED_ROOF)
- {
- if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
- goto failed;
-
- switch (objectID)
- {
- case PKCS7_ENVELOPED_VERSION:
- if (*object.ptr != 0)
+ asn1_parser_t *parser;
+ chunk_t object;
+ chunk_t iv = chunk_empty;
+ chunk_t symmetric_key = chunk_empty;
+ chunk_t encrypted_content = chunk_empty;
+
+ crypter_t *crypter = NULL;
+
+ u_char buf[BUF_LEN];
+ int enc_alg = OID_UNKNOWN;
+ int content_enc_alg = OID_UNKNOWN;
+ int objectID;
+ bool success = FALSE;
+
+ contentInfo_t cInfo = empty_contentInfo;
+ *data = chunk_empty;
+
+ if (!pkcs7_parse_contentInfo(blob, 0, &cInfo))
{
- plog("envelopedData version is not 0");
- goto failed;
- }
- break;
- case PKCS7_RECIPIENT_INFO_VERSION:
- if (*object.ptr != 0)
- {
- plog("recipient info version is not 0");
- goto failed;
- }
- break;
- case PKCS7_ISSUER:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'", buf)
- )
- break;
- case PKCS7_SERIAL_NUMBER:
- if (!same_chunk(serialNumber, object))
- {
- plog("serial numbers do not match");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTION_ALG:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- if (enc_alg != OID_RSA_ENCRYPTION)
- {
- plog("only rsa encryption supported");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTED_KEY:
- if (!RSA_decrypt(key, object, &symmetric_key))
- {
- plog("symmetric key could not be decrypted with rsa");
- goto failed;
- }
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("symmetric key :", symmetric_key)
- )
- break;
- case PKCS7_CONTENT_TYPE:
- if (known_oid(object) != OID_PKCS7_DATA)
- {
- plog("encrypted content not of type pkcs7 data");
- goto failed;
- }
- break;
- case PKCS7_CONTENT_ENC_ALGORITHM:
- content_enc_alg = parse_algorithmIdentifier(object, level, &iv);
-
- switch (content_enc_alg)
- {
- case OID_DES_CBC:
- total_keys = 1;
- break;
- case OID_3DES_EDE_CBC:
- total_keys = 3;
- break;
- default:
- plog("Only DES and 3DES supported for symmetric encryption");
- goto failed;
- }
- if (symmetric_key.len != (total_keys * DES_CBC_BLOCK_SIZE))
- {
- plog("key length is not %d",(total_keys * DES_CBC_BLOCK_SIZE));
- goto failed;
- }
- if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
- {
- plog("IV could not be parsed");
goto failed;
- }
- if (iv.len != DES_CBC_BLOCK_SIZE)
- {
- plog("IV has wrong length");
+ }
+ if (cInfo.type != OID_PKCS7_ENVELOPED_DATA)
+ {
+ DBG1("pkcs7 content type is not envelopedData");
goto failed;
- }
- break;
- case PKCS7_ENCRYPTED_CONTENT:
- encrypted_content = object;
- break;
}
- objectID++;
- }
- /* decrypt the content */
- {
- u_int i;
- des_cblock des_key[3], des_iv;
- des_key_schedule key_s[3];
+ parser = asn1_parser_create(envelopedDataObjects, cInfo.content);
+ parser->set_top_level(parser, 2);
- memcpy((char *)des_key, symmetric_key.ptr, symmetric_key.len);
- memcpy((char *)des_iv, iv.ptr, iv.len);
-
- for (i = 0; i < total_keys; i++)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (des_set_key(&des_key[i], key_s[i]))
- {
- plog("des key schedule failed");
- goto failed;
- }
- }
+ u_int level = parser->get_level(parser);
- data->len = encrypted_content.len;
- data->ptr = alloc_bytes(data->len, "decrypted data");
+ switch (objectID)
+ {
+ case PKCS7_ENVELOPED_VERSION:
+ if (*object.ptr != 0)
+ {
+ DBG1("envelopedData version is not 0");
+ goto end;
+ }
+ break;
+ case PKCS7_RECIPIENT_INFO_VERSION:
+ if (*object.ptr != 0)
+ {
+ DBG1("recipient info version is not 0");
+ goto end;
+ }
+ break;
+ case PKCS7_ISSUER:
+ dntoa(buf, BUF_LEN, object);
+ DBG2(" '%s'", buf);
+ break;
+ case PKCS7_SERIAL_NUMBER:
+ if (!chunk_equals(serialNumber, object))
+ {
+ DBG1("serial numbers do not match");
+ goto end;
+ }
+ break;
+ case PKCS7_ENCRYPTION_ALG:
+ enc_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (enc_alg != OID_RSA_ENCRYPTION)
+ {
+ DBG1("only rsa encryption supported");
+ goto end;
+ }
+ break;
+ case PKCS7_ENCRYPTED_KEY:
+ if (!key->decrypt(key, object, &symmetric_key))
+ {
+ DBG1("symmetric key could not be decrypted with rsa");
+ goto end;
+ }
+ DBG4("symmetric key %B", &symmetric_key);
+ break;
+ case PKCS7_CONTENT_TYPE:
+ if (asn1_known_oid(object) != OID_PKCS7_DATA)
+ {
+ DBG1("encrypted content not of type pkcs7 data");
+ goto end;
+ }
+ break;
+ case PKCS7_CONTENT_ENC_ALGORITHM:
+ content_enc_alg = asn1_parse_algorithmIdentifier(object, level, &iv);
+
+ if (content_enc_alg == OID_UNKNOWN)
+ {
+ DBG1("unknown content encryption algorithm");
+ goto end;
+ }
+ if (!asn1_parse_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
+ {
+ DBG1("IV could not be parsed");
+ goto end;
+ }
+ break;
+ case PKCS7_ENCRYPTED_CONTENT:
+ encrypted_content = object;
+ break;
+ }
+ }
+ success = parser->success(parser);
- switch (content_enc_alg)
+end:
+ parser->destroy(parser);
+ if (!success)
{
- case OID_DES_CBC:
- des_cbc_encrypt((des_cblock*)encrypted_content.ptr
- , (des_cblock*)data->ptr, data->len
- , key_s[0], &des_iv, DES_DECRYPT);
- break;
- case OID_3DES_EDE_CBC:
- des_ede3_cbc_encrypt( (des_cblock*)encrypted_content.ptr
- , (des_cblock*)data->ptr, data->len
- , key_s[0], key_s[1], key_s[2]
- , &des_iv, DES_DECRYPT);
+ goto failed;
}
- DBG(DBG_PRIVATE,
- DBG_dump_chunk("decrypted content with padding:\n", *data)
- )
- }
-
- /* remove the padding */
- {
- u_char *pos = data->ptr + data->len - 1;
- u_char pattern = *pos;
- size_t padding = pattern;
-
- if (padding > data->len)
+ success = FALSE;
+
+ /* decrypt the content */
{
- plog("padding greater than data length");
- goto failed;
+ encryption_algorithm_t alg;
+ size_t key_size;
+ crypter_t *crypter;
+
+ alg = encryption_algorithm_from_oid(content_enc_alg, &key_size);
+ if (alg == ENCR_UNDEFINED)
+ {
+ DBG1("unsupported content encryption algorithm");
+ goto failed;
+ }
+ crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
+ if (crypter == NULL)
+ {
+ DBG1("crypter %N not available", encryption_algorithm_names, alg);
+ goto failed;
+ }
+ if (symmetric_key.len != crypter->get_key_size(crypter))
+ {
+ DBG1("symmetric key length %d is wrong", symmetric_key.len);
+ goto failed;
+ }
+ if (iv.len != crypter->get_block_size(crypter))
+ {
+ DBG1("IV length %d is wrong", iv.len);
+ goto failed;
+ }
+ crypter->set_key(crypter, symmetric_key);
+ crypter->decrypt(crypter, encrypted_content, iv, data);
+ DBG4("decrypted content with padding: %B", data);
}
- data->len -= padding;
- while (padding-- > 0)
+ /* remove the padding */
{
- if (*pos-- != pattern)
- {
- plog("wrong padding pattern");
- goto failed;
- }
+ u_char *pos = data->ptr + data->len - 1;
+ u_char pattern = *pos;
+ size_t padding = pattern;
+
+ if (padding > data->len)
+ {
+ DBG1("padding greater than data length");
+ goto failed;
+ }
+ data->len -= padding;
+
+ while (padding-- > 0)
+ {
+ if (*pos-- != pattern)
+ {
+ DBG1("wrong padding pattern");
+ goto failed;
+ }
+ }
}
- }
- freeanychunk(symmetric_key);
- return TRUE;
+ success = TRUE;
failed:
- freeanychunk(symmetric_key);
- pfreeany(data->ptr);
- return FALSE;
+ DESTROY_IF(crypter);
+ chunk_clear(&symmetric_key);
+ if (!success)
+ {
+ free(data->ptr);
+ }
+ return success;
}
/**
@@ -577,12 +576,11 @@ failed:
*
* @return ASN.1 encoded contentType attribute
*/
-chunk_t
-pkcs7_contentType_attribute(void)
+chunk_t pkcs7_contentType_attribute(void)
{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_contentType_oid
- , asn1_simple_object(ASN1_SET, ASN1_pkcs7_data_oid));
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_contentType_oid
+ , asn1_simple_object(ASN1_SET, ASN1_pkcs7_data_oid));
}
/**
@@ -594,269 +592,228 @@ pkcs7_contentType_attribute(void)
* @return ASN.1 encoded messageDigest attribute
*
*/
-chunk_t
-pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
+chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg)
{
- u_char digest_buf[MAX_DIGEST_LEN];
- chunk_t digest = { digest_buf, MAX_DIGEST_LEN };
-
- compute_digest(content, digest_alg, &digest);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_messageDigest_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_OCTET_STRING, digest)
- )
- );
+ chunk_t digest;
+ hash_algorithm_t hash_alg;
+ hasher_t *hasher;
+
+ hash_alg = hasher_algorithm_from_oid(digest_alg);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ hasher->allocate_hash(hasher, content, &digest);
+ hasher->destroy(hasher);
+
+ return asn1_wrap(ASN1_SEQUENCE, "cm",
+ ASN1_messageDigest_oid,
+ asn1_wrap(ASN1_SET, "m",
+ asn1_wrap(ASN1_OCTET_STRING, "m", digest)
+ )
+ );
}
-/*
+
+/**
* build a DER-encoded contentInfo object
*/
-static chunk_t
-pkcs7_build_contentInfo(contentInfo_t *cInfo)
+static chunk_t pkcs7_build_contentInfo(contentInfo_t *cInfo)
{
- chunk_t content_type;
-
- /* select DER-encoded OID for pkcs7 contentInfo type */
- switch(cInfo->type)
- {
- case OID_PKCS7_DATA:
- content_type = ASN1_pkcs7_data_oid;
- break;
- case OID_PKCS7_SIGNED_DATA:
- content_type = ASN1_pkcs7_signed_data_oid;
- break;
- case OID_PKCS7_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_enveloped_data_oid;
- break;
- case OID_PKCS7_SIGNED_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_signed_enveloped_data_oid;
- break;
- case OID_PKCS7_DIGESTED_DATA:
- content_type = ASN1_pkcs7_digested_data_oid;
- break;
- case OID_PKCS7_ENCRYPTED_DATA:
- content_type = ASN1_pkcs7_encrypted_data_oid;
- break;
- case OID_UNKNOWN:
- default:
- fprintf(stderr, "invalid pkcs7 contentInfo type");
- return empty_chunk;
- }
-
- return (cInfo->content.ptr == NULL)
- ? asn1_simple_object(ASN1_SEQUENCE, content_type)
- : asn1_wrap(ASN1_SEQUENCE, "cm"
- , content_type
- , asn1_simple_object(ASN1_CONTEXT_C_0, cInfo->content)
- );
+ chunk_t content_type;
+
+ /* select DER-encoded OID for pkcs7 contentInfo type */
+ switch(cInfo->type)
+ {
+ case OID_PKCS7_DATA:
+ content_type = ASN1_pkcs7_data_oid;
+ break;
+ case OID_PKCS7_SIGNED_DATA:
+ content_type = ASN1_pkcs7_signed_data_oid;
+ break;
+ case OID_PKCS7_ENVELOPED_DATA:
+ content_type = ASN1_pkcs7_enveloped_data_oid;
+ break;
+ case OID_PKCS7_SIGNED_ENVELOPED_DATA:
+ content_type = ASN1_pkcs7_signed_enveloped_data_oid;
+ break;
+ case OID_PKCS7_DIGESTED_DATA:
+ content_type = ASN1_pkcs7_digested_data_oid;
+ break;
+ case OID_PKCS7_ENCRYPTED_DATA:
+ content_type = ASN1_pkcs7_encrypted_data_oid;
+ break;
+ case OID_UNKNOWN:
+ default:
+ DBG1("invalid pkcs7 contentInfo type");
+ return chunk_empty;
+ }
+
+ return (cInfo->content.ptr == NULL)
+ ? asn1_simple_object(ASN1_SEQUENCE, content_type)
+ : asn1_wrap(ASN1_SEQUENCE, "cm"
+ , content_type
+ , asn1_simple_object(ASN1_CONTEXT_C_0, cInfo->content)
+ );
}
-/*
+/**
* build issuerAndSerialNumber object
*/
-chunk_t
-pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
+chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert)
{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , cert->issuer
- , asn1_simple_object(ASN1_INTEGER, cert->serialNumber));
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , cert->issuer
+ , asn1_integer("c", cert->serialNumber));
}
-/*
+/**
* create a signed pkcs7 contentInfo object
*/
-chunk_t
-pkcs7_build_signedData(chunk_t data, chunk_t attributes, const x509cert_t *cert
-, int digest_alg, const RSA_private_key_t *key)
+chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
+ const x509cert_t *cert, int digest_alg,
+ private_key_t *key)
{
- contentInfo_t pkcs7Data, signedData;
- chunk_t authenticatedAttributes, encryptedDigest, signerInfo, cInfo;
-
- chunk_t digestAlgorithm = asn1_algorithmIdentifier(digest_alg);
-
- if (attributes.ptr != NULL)
- {
- encryptedDigest = pkcs1_build_signature(attributes, digest_alg
- , key, FALSE);
- clonetochunk(authenticatedAttributes, attributes.ptr, attributes.len
- , "authenticatedAttributes");
- *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
- }
- else
- {
- encryptedDigest = (data.ptr == NULL)? empty_chunk
- : pkcs1_build_signature(data, digest_alg, key, FALSE);
- authenticatedAttributes = empty_chunk;
- }
-
- signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm"
- , ASN1_INTEGER_1
- , pkcs7_build_issuerAndSerialNumber(cert)
- , digestAlgorithm
- , authenticatedAttributes
- , ASN1_rsaEncryption_id
- , encryptedDigest);
-
- pkcs7Data.type = OID_PKCS7_DATA;
- pkcs7Data.content = (data.ptr == NULL)? empty_chunk
- : asn1_simple_object(ASN1_OCTET_STRING, data);
-
- signedData.type = OID_PKCS7_SIGNED_DATA;
- signedData.content = asn1_wrap(ASN1_SEQUENCE, "cmmmm"
- , ASN1_INTEGER_1
- , asn1_simple_object(ASN1_SET, digestAlgorithm)
- , pkcs7_build_contentInfo(&pkcs7Data)
- , asn1_simple_object(ASN1_CONTEXT_C_0, cert->certificate)
- , asn1_wrap(ASN1_SET, "m", signerInfo));
-
- cInfo = pkcs7_build_contentInfo(&signedData);
- DBG(DBG_RAW,
- DBG_dump_chunk("signedData:\n", cInfo)
- )
-
- freeanychunk(pkcs7Data.content);
- freeanychunk(signedData.content);
- return cInfo;
+ contentInfo_t pkcs7Data, signedData;
+ chunk_t authenticatedAttributes, encryptedDigest, signerInfo, cInfo;
+
+ chunk_t digestAlgorithm = asn1_algorithmIdentifier(digest_alg);
+
+ if (attributes.ptr != NULL)
+ {
+ encryptedDigest = x509_build_signature(attributes, digest_alg, key,
+ FALSE);
+ authenticatedAttributes = chunk_clone(attributes);
+ *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
+ }
+ else
+ {
+ encryptedDigest = (data.ptr == NULL)? chunk_empty
+ : x509_build_signature(data, digest_alg, key, FALSE);
+ authenticatedAttributes = chunk_empty;
+ }
+
+ signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm"
+ , ASN1_INTEGER_1
+ , pkcs7_build_issuerAndSerialNumber(cert)
+ , digestAlgorithm
+ , authenticatedAttributes
+ , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
+ , encryptedDigest);
+
+ pkcs7Data.type = OID_PKCS7_DATA;
+ pkcs7Data.content = (data.ptr == NULL)? chunk_empty
+ : asn1_simple_object(ASN1_OCTET_STRING, data);
+
+ signedData.type = OID_PKCS7_SIGNED_DATA;
+ signedData.content = asn1_wrap(ASN1_SEQUENCE, "cmmmm"
+ , ASN1_INTEGER_1
+ , asn1_simple_object(ASN1_SET, digestAlgorithm)
+ , pkcs7_build_contentInfo(&pkcs7Data)
+ , asn1_simple_object(ASN1_CONTEXT_C_0, cert->certificate)
+ , asn1_wrap(ASN1_SET, "m", signerInfo));
+
+ cInfo = pkcs7_build_contentInfo(&signedData);
+ DBG3("signedData %B", &cInfo);
+
+ free(pkcs7Data.content.ptr);
+ free(signedData.content.ptr);
+ return cInfo;
}
-/*
+/**
* create a symmetrically encrypted pkcs7 contentInfo object
*/
-chunk_t
-pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int cipher)
+chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert, int enc_alg)
{
- bool des_check_key_save;
- des_key_schedule ks[3];
- des_cblock key[3], des_iv, des_iv_buf;
-
- chunk_t iv = { (u_char *)des_iv_buf, DES_CBC_BLOCK_SIZE };
- chunk_t out;
- chunk_t cipher_oid;
-
- u_int total_keys, i;
- size_t padding = pad_up(data.len, DES_CBC_BLOCK_SIZE);
-
- RSA_public_key_t public_key;
-
- init_RSA_public_key(&public_key, cert->publicExponent
- , cert->modulus);
-
- if (padding == 0)
- padding += DES_CBC_BLOCK_SIZE;
-
- out.len = data.len + padding;
- out.ptr = alloc_bytes(out.len, "DES-encrypted output");
-
- DBG(DBG_CONTROL,
- DBG_log("padding %d bytes of data to multiple DES block size of %d bytes"
- , (int)data.len, (int)out.len)
- )
-
- /* copy data */
- memcpy(out.ptr, data.ptr, data.len);
- /* append padding */
- memset(out.ptr + data.len, padding, padding);
-
- DBG(DBG_RAW,
- DBG_dump_chunk("Padded unencrypted data:\n", out)
- )
-
- /* select OID and keylength for specified cipher */
- switch (cipher)
- {
- case OID_DES_CBC:
- total_keys = 1;
- cipher_oid = ASN1_des_cbc_oid;
- break;
- case OID_3DES_EDE_CBC:
- default:
- total_keys = 3;
- cipher_oid = ASN1_3des_ede_cbc_oid;
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs7 encryption cipher: %s", oid_names[cipher].name)
- )
-
- /* generate a strong random key for DES/3DES */
- des_check_key_save = des_check_key;
- des_check_key = TRUE;
- for (i = 0; i < total_keys;i++)
- {
- for (;;)
+ encryption_algorithm_t alg;
+ size_t alg_key_size;
+ chunk_t symmetricKey, protectedKey, iv, in, out;
+ crypter_t *crypter;
+
+ alg = encryption_algorithm_from_oid(enc_alg, &alg_key_size);
+ crypter = lib->crypto->create_crypter(lib->crypto, alg,
+ alg_key_size/BITS_PER_BYTE);
+ if (crypter == NULL)
{
- get_rnd_bytes((char*)key[i], DES_CBC_BLOCK_SIZE);
- des_set_odd_parity(&key[i]);
- if (!des_set_key(&key[i], ks[i]))
- break;
- plog("weak DES key discarded - we try again");
+ DBG1("crypter for %N not available", encryption_algorithm_names, alg);
+ return chunk_empty;
+ }
+
+ /* generate a true random symmetric encryption key and a pseudo-random iv */
+ {
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
+ rng->allocate_bytes(rng, crypter->get_key_size(crypter), &symmetricKey);
+ DBG4("symmetric encryption key %B", &symmetricKey);
+ rng->destroy(rng);
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ rng->allocate_bytes(rng, crypter->get_block_size(crypter), &iv);
+ DBG4("initialization vector: %B", &iv);
+ rng->destroy(rng);
+ }
+
+ /* pad the data to a multiple of the block size */
+ {
+ size_t block_size = crypter->get_block_size(crypter);
+ size_t padding = block_size - data.len % block_size;
+
+ in.len = data.len + padding;
+ in.ptr = malloc(in.len);
+
+ DBG2("padding %u bytes of data to multiple block size of %u bytes",
+ data.len, in.len);
+
+ /* copy data */
+ memcpy(in.ptr, data.ptr, data.len);
+ /* append padding */
+ memset(in.ptr + data.len, padding, padding);
+ }
+ DBG3("padded unencrypted data %B", &in);
+
+ /* symmetric encryption of data object */
+ crypter->set_key(crypter, symmetricKey);
+ crypter->encrypt(crypter, in, iv, &out);
+ crypter->destroy(crypter);
+ DBG3("encrypted data %B", &out);
+
+ cert->public_key->encrypt(cert->public_key, symmetricKey, &protectedKey);
+
+ /* build pkcs7 enveloped data object */
+ {
+
+ chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "mm"
+ , asn1_build_known_oid(enc_alg)
+ , asn1_simple_object(ASN1_OCTET_STRING, iv));
+
+ chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm"
+ , ASN1_pkcs7_data_oid
+ , contentEncryptionAlgorithm
+ , asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
+
+ chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m"
+ , protectedKey);
+
+ chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm"
+ , ASN1_INTEGER_0
+ , pkcs7_build_issuerAndSerialNumber(cert)
+ , asn1_algorithmIdentifier(OID_RSA_ENCRYPTION)
+ , encryptedKey);
+
+ chunk_t cInfo;
+ contentInfo_t envelopedData;
+
+ envelopedData.type = OID_PKCS7_ENVELOPED_DATA;
+ envelopedData.content = asn1_wrap(ASN1_SEQUENCE, "cmm"
+ , ASN1_INTEGER_0
+ , asn1_wrap(ASN1_SET, "m", recipientInfo)
+ , encryptedContentInfo);
+
+ cInfo = pkcs7_build_contentInfo(&envelopedData);
+ DBG3("envelopedData %B", &cInfo);
+
+ free(envelopedData.content.ptr);
+ free(symmetricKey.ptr);
+ free(in.ptr);
+ free(iv.ptr);
+ return cInfo;
}
- DBG(DBG_PRIVATE,
- DBG_dump("DES key:", key[i], 8)
- )
- }
- des_check_key = des_check_key_save;
-
- /* generate an iv for DES/3DES CBC */
- get_rnd_bytes(des_iv, DES_CBC_BLOCK_SIZE);
- memcpy(iv.ptr, des_iv, DES_CBC_BLOCK_SIZE);
- DBG(DBG_RAW,
- DBG_dump_chunk("DES IV :", iv)
- )
-
- /* encryption using specified cipher */
- switch (cipher)
- {
- case OID_DES_CBC:
- des_cbc_encrypt((des_cblock*)out.ptr, (des_cblock*)out.ptr, out.len
- , ks[0], &des_iv, DES_ENCRYPT);
- break;
- case OID_3DES_EDE_CBC:
- default:
- des_ede3_cbc_encrypt((des_cblock*)out.ptr, (des_cblock*)out.ptr, out.len
- , ks[0], ks[1], ks[2], &des_iv, DES_ENCRYPT);
- }
- DBG(DBG_RAW,
- DBG_dump_chunk("Encrypted data:\n", out));
-
- /* build pkcs7 enveloped data object */
- {
- chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm"
- , cipher_oid
- , asn1_simple_object(ASN1_OCTET_STRING, iv));
-
- chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_pkcs7_data_oid
- , contentEncryptionAlgorithm
- , asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
-
- chunk_t plainKey = { (u_char *)key, DES_CBC_BLOCK_SIZE * total_keys };
-
- chunk_t encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m"
- , RSA_encrypt(&public_key, plainKey));
-
- chunk_t recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm"
- , ASN1_INTEGER_0
- , pkcs7_build_issuerAndSerialNumber(cert)
- , ASN1_rsaEncryption_id
- , encryptedKey);
-
- chunk_t cInfo;
- contentInfo_t envelopedData;
-
- envelopedData.type = OID_PKCS7_ENVELOPED_DATA;
- envelopedData.content = asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_INTEGER_0
- , asn1_wrap(ASN1_SET, "m", recipientInfo)
- , encryptedContentInfo);
-
- cInfo = pkcs7_build_contentInfo(&envelopedData);
- DBG(DBG_RAW,
- DBG_dump_chunk("envelopedData:\n", cInfo)
- )
-
- free_RSA_public_content(&public_key);
- freeanychunk(envelopedData.content);
- return cInfo;
- }
}
diff --git a/src/pluto/pkcs7.h b/src/pluto/pkcs7.h
index a577f8022..028822dfe 100644
--- a/src/pluto/pkcs7.h
+++ b/src/pluto/pkcs7.h
@@ -1,6 +1,7 @@
/* Support of PKCS#7 data structures
* Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2005 Andreas Steffen
+ * Copyright (C) 2002-2009 Andreas Steffen
+ *
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
@@ -12,15 +13,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: pkcs7.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _PKCS7_H
#define _PKCS7_H
+#include <crypto/crypters/crypter.h>
+#include <credentials/keys/private_key.h>
#include "defs.h"
-#include "pkcs1.h"
#include "x509.h"
/* Access structure for a PKCS#7 ContentInfo object */
@@ -28,24 +28,24 @@
typedef struct contentInfo contentInfo_t;
struct contentInfo {
- int type;
- chunk_t content;
+ int type;
+ chunk_t content;
};
extern const contentInfo_t empty_contentInfo;
-extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0
- , contentInfo_t *cInfo);
-extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data
- , x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert);
-extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data
- , chunk_t serialNumber, const RSA_private_key_t *key);
+extern bool pkcs7_parse_contentInfo(chunk_t blob, u_int level0,
+ contentInfo_t *cInfo);
+extern bool pkcs7_parse_signedData(chunk_t blob, contentInfo_t *data,
+ x509cert_t **cert, chunk_t *attributes, const x509cert_t *cacert);
+extern bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
+ chunk_t serialNumber, private_key_t *key);
extern chunk_t pkcs7_contentType_attribute(void);
extern chunk_t pkcs7_messageDigest_attribute(chunk_t content, int digest_alg);
extern chunk_t pkcs7_build_issuerAndSerialNumber(const x509cert_t *cert);
-extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes
- ,const x509cert_t *cert, int digest_alg, const RSA_private_key_t *key);
-extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert
- , int cipher);
+extern chunk_t pkcs7_build_signedData(chunk_t data, chunk_t attributes,
+ const x509cert_t *cert, int digest_alg, private_key_t *key);
+extern chunk_t pkcs7_build_envelopedData(chunk_t data, const x509cert_t *cert,
+ int enc_alg);
#endif /* _PKCS7_H */
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index a39934f1f..39367cafa 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -1,6 +1,7 @@
/* Pluto main program
* Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: plutomain.c 4313 2008-08-29 09:24:14Z martin $
*/
#include <stdio.h>
@@ -27,7 +26,7 @@
#include <fcntl.h>
#include <getopt.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <sys/prctl.h>
#include <pwd.h>
@@ -39,6 +38,16 @@
#include <freeswan.h>
+#include <library.h>
+#include <debug.h>
+#include <utils/enumerator.h>
+#include <utils/optionsfrom.h>
+
+#ifdef INTEGRITY_TEST
+#include <fips/fips.h>
+#include <fips/fips_signature.h>
+#endif /* INTEGRITY_TEST */
+
#include <pfkeyv2.h>
#include <pfkey.h>
@@ -51,91 +60,88 @@
#include "connections.h"
#include "foodgroups.h"
#include "packet.h"
-#include "demux.h" /* needs packet.h */
+#include "demux.h" /* needs packet.h */
#include "server.h"
#include "kernel.h"
#include "log.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "rnd.h"
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "state.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "ocsp.h"
#include "crl.h"
#include "fetch.h"
#include "xauth.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
#include "nat_traversal.h"
#include "virtual.h"
+#include "timer.h"
+#include "vendor.h"
-static void
-usage(const char *mess)
+static void usage(const char *mess)
{
- if (mess != NULL && *mess != '\0')
- fprintf(stderr, "%s\n", mess);
- fprintf(stderr
- , "Usage: pluto"
- " [--help]"
- " [--version]"
- " [--optionsfrom <filename>]"
- " \\\n\t"
- "[--nofork]"
- " [--stderrlog]"
- " [--noklips]"
- " [--nocrsend]"
- " \\\n\t"
- "[--strictcrlpolicy]"
- " [--crlcheckinterval <interval>]"
- " [--cachecrls]"
- " [--uniqueids]"
- " \\\n\t"
- "[--interface <ifname>]"
- " [--ikeport <port-number>]"
- " \\\n\t"
- "[--ctlbase <path>]"
- " \\\n\t"
- "[--perpeerlogbase <path>] [--perpeerlog]"
- " \\\n\t"
- "[--secretsfile <secrets-file>]"
- " [--policygroupsdir <policygroups-dir>]"
- " \\\n\t"
- "[--adns <pathname>]"
- "[--pkcs11module <path>]"
- "[--pkcs11keepstate]"
- "[--pkcs11initargs <string>]"
+ if (mess != NULL && *mess != '\0')
+ fprintf(stderr, "%s\n", mess);
+ fprintf(stderr
+ , "Usage: pluto"
+ " [--help]"
+ " [--version]"
+ " [--optionsfrom <filename>]"
+ " \\\n\t"
+ "[--nofork]"
+ " [--stderrlog]"
+ " [--noklips]"
+ " [--nocrsend]"
+ " \\\n\t"
+ "[--strictcrlpolicy]"
+ " [--crlcheckinterval <interval>]"
+ " [--cachecrls]"
+ " [--uniqueids]"
+ " \\\n\t"
+ "[--interface <ifname>]"
+ " [--ikeport <port-number>]"
+ " \\\n\t"
+ "[--ctlbase <path>]"
+ " \\\n\t"
+ "[--perpeerlogbase <path>] [--perpeerlog]"
+ " \\\n\t"
+ "[--secretsfile <secrets-file>]"
+ " [--policygroupsdir <policygroups-dir>]"
+ " \\\n\t"
+ "[--adns <pathname>]"
+ "[--pkcs11module <path>]"
+ "[--pkcs11keepstate]"
+ "[--pkcs11initargs <string>]"
#ifdef DEBUG
- " \\\n\t"
- "[--debug-none]"
- " [--debug-all]"
- " \\\n\t"
- "[--debug-raw]"
- " [--debug-crypt]"
- " [--debug-parsing]"
- " [--debug-emitting]"
- " \\\n\t"
- "[--debug-control]"
- " [--debug-lifecycle]"
- " [--debug-klips]"
- " [--debug-dns]"
- " \\\n\t"
- "[--debug-oppo]"
- " [--debug-controlmore]"
- " [--debug-private]"
+ " \\\n\t"
+ "[--debug-none]"
+ " [--debug-all]"
+ " \\\n\t"
+ "[--debug-raw]"
+ " [--debug-crypt]"
+ " [--debug-parsing]"
+ " [--debug-emitting]"
+ " \\\n\t"
+ "[--debug-control]"
+ " [--debug-lifecycle]"
+ " [--debug-klips]"
+ " [--debug-dns]"
+ " \\\n\t"
+ "[--debug-oppo]"
+ " [--debug-controlmore]"
+ " [--debug-private]"
+ " [--debug-natt]"
#endif
- " [ --debug-natt]"
- " \\\n\t"
- "[--nat_traversal] [--keep_alive <delay_sec>]"
- " \\\n\t"
- "[--force_keepalive] [--disable_port_floating]"
- " \\\n\t"
- "[--virtual_private <network_list>]"
- "\n"
- "strongSwan %s\n"
- , ipsec_version_code());
- exit_pluto(mess == NULL? 0 : 1);
+ " \\\n\t"
+ "[--nat_traversal] [--keep_alive <delay_sec>]"
+ " \\\n\t"
+ "[--force_keepalive] [--disable_port_floating]"
+ " \\\n\t"
+ "[--virtual_private <network_list>]"
+ "\n"
+ "strongSwan "VERSION"\n");
+ exit_pluto(mess == NULL? 0 : 1);
}
@@ -150,53 +156,51 @@ static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
static bool pluto_lock_created = FALSE;
/* create lockfile, or die in the attempt */
-static int
-create_lock(void)
+static int create_lock(void)
{
- int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
- , S_IRUSR | S_IRGRP | S_IROTH);
+ int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
+ , S_IRUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
- {
- if (errno == EEXIST)
+ if (fd < 0)
{
- fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
- , pluto_lock);
- exit_pluto(10);
+ if (errno == EEXIST)
+ {
+ fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
+ , pluto_lock);
+ exit_pluto(10);
+ }
+ else
+ {
+ fprintf(stderr
+ , "pluto: unable to create lock file \"%s\" (%d %s)\n"
+ , pluto_lock, errno, strerror(errno));
+ exit_pluto(1);
+ }
}
- else
- {
- fprintf(stderr
- , "pluto: unable to create lock file \"%s\" (%d %s)\n"
- , pluto_lock, errno, strerror(errno));
- exit_pluto(1);
- }
- }
- pluto_lock_created = TRUE;
- return fd;
+ pluto_lock_created = TRUE;
+ return fd;
}
-static bool
-fill_lock(int lockfd, pid_t pid)
+static bool fill_lock(int lockfd, pid_t pid)
{
- char buf[30]; /* holds "<pid>\n" */
- int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
- bool ok = len > 0 && write(lockfd, buf, len) == len;
+ char buf[30]; /* holds "<pid>\n" */
+ int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
+ bool ok = len > 0 && write(lockfd, buf, len) == len;
- close(lockfd);
- return ok;
+ close(lockfd);
+ return ok;
}
-static void
-delete_lock(void)
+static void delete_lock(void)
{
- if (pluto_lock_created)
- {
- delete_ctl_socket();
- unlink(pluto_lock); /* is noting failure useful? */
- }
+ if (pluto_lock_created)
+ {
+ delete_ctl_socket();
+ unlink(pluto_lock); /* is noting failure useful? */
+ }
}
+
/* by default pluto sends certificate requests to its peers */
bool no_cr_send = FALSE;
@@ -223,459 +227,504 @@ bool pkcs11_proxy = FALSE;
*/
static const char *pkcs11_init_args = NULL;
-int
-main(int argc, char **argv)
+/* options read by optionsfrom */
+options_t *options;
+
+/**
+ * Log loaded plugins
+ */
+static void print_plugins()
+{
+ char buf[BUF_LEN], *plugin;
+ int len = 0;
+ enumerator_t *enumerator;
+
+ buf[0] = '\0';
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
+ {
+ len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin);
+ }
+ enumerator->destroy(enumerator);
+ DBG1("loaded plugins: %s", buf);
+}
+
+int main(int argc, char **argv)
{
- bool fork_desired = TRUE;
- bool log_to_stderr_desired = FALSE;
- bool nat_traversal = FALSE;
- bool nat_t_spf = TRUE; /* support port floating */
- unsigned int keep_alive = 0;
- bool force_keepalive = FALSE;
- char *virtual_private = NULL;
- int lockfd;
+ bool fork_desired = TRUE;
+ bool log_to_stderr_desired = FALSE;
+ bool nat_traversal = FALSE;
+ bool nat_t_spf = TRUE; /* support port floating */
+ unsigned int keep_alive = 0;
+ bool force_keepalive = FALSE;
+ char *virtual_private = NULL;
+ int lockfd;
#ifdef CAPABILITIES
- cap_t caps;
- int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
+ cap_t caps;
+ int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */
- /* handle arguments */
- for (;;)
- {
-# define DBG_OFFSET 256
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "nofork", no_argument, NULL, 'd' },
- { "stderrlog", no_argument, NULL, 'e' },
- { "noklips", no_argument, NULL, 'n' },
- { "nocrsend", no_argument, NULL, 'c' },
- { "strictcrlpolicy", no_argument, NULL, 'r' },
- { "crlcheckinterval", required_argument, NULL, 'x'},
- { "cachecrls", no_argument, NULL, 'C' },
- { "uniqueids", no_argument, NULL, 'u' },
- { "interface", required_argument, NULL, 'i' },
- { "ikeport", required_argument, NULL, 'p' },
- { "ctlbase", required_argument, NULL, 'b' },
- { "secretsfile", required_argument, NULL, 's' },
- { "foodgroupsdir", required_argument, NULL, 'f' },
- { "perpeerlogbase", required_argument, NULL, 'P' },
- { "perpeerlog", no_argument, NULL, 'l' },
- { "policygroupsdir", required_argument, NULL, 'f' },
+ /* initialize library and optionsfrom */
+ library_init(STRONGSWAN_CONF);
+ options = options_create();
+
+ /* handle arguments */
+ for (;;)
+ {
+# define DBG_OFFSET 256
+ static const struct option long_opts[] = {
+ /* name, has_arg, flag, val */
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "optionsfrom", required_argument, NULL, '+' },
+ { "nofork", no_argument, NULL, 'd' },
+ { "stderrlog", no_argument, NULL, 'e' },
+ { "noklips", no_argument, NULL, 'n' },
+ { "nocrsend", no_argument, NULL, 'c' },
+ { "strictcrlpolicy", no_argument, NULL, 'r' },
+ { "crlcheckinterval", required_argument, NULL, 'x'},
+ { "cachecrls", no_argument, NULL, 'C' },
+ { "uniqueids", no_argument, NULL, 'u' },
+ { "interface", required_argument, NULL, 'i' },
+ { "ikeport", required_argument, NULL, 'p' },
+ { "ctlbase", required_argument, NULL, 'b' },
+ { "secretsfile", required_argument, NULL, 's' },
+ { "foodgroupsdir", required_argument, NULL, 'f' },
+ { "perpeerlogbase", required_argument, NULL, 'P' },
+ { "perpeerlog", no_argument, NULL, 'l' },
+ { "policygroupsdir", required_argument, NULL, 'f' },
#ifdef USE_LWRES
- { "lwdnsq", required_argument, NULL, 'a' },
+ { "lwdnsq", required_argument, NULL, 'a' },
#else /* !USE_LWRES */
- { "adns", required_argument, NULL, 'a' },
+ { "adns", required_argument, NULL, 'a' },
#endif /* !USE_LWRES */
- { "pkcs11module", required_argument, NULL, 'm' },
- { "pkcs11keepstate", no_argument, NULL, 'k' },
- { "pkcs11initargs", required_argument, NULL, 'z' },
- { "pkcs11proxy", no_argument, NULL, 'y' },
- { "nat_traversal", no_argument, NULL, '1' },
- { "keep_alive", required_argument, NULL, '2' },
- { "force_keepalive", no_argument, NULL, '3' },
- { "disable_port_floating", no_argument, NULL, '4' },
- { "debug-natt", no_argument, NULL, '5' },
- { "virtual_private", required_argument, NULL, '6' },
+ { "pkcs11module", required_argument, NULL, 'm' },
+ { "pkcs11keepstate", no_argument, NULL, 'k' },
+ { "pkcs11initargs", required_argument, NULL, 'z' },
+ { "pkcs11proxy", no_argument, NULL, 'y' },
+ { "nat_traversal", no_argument, NULL, '1' },
+ { "keep_alive", required_argument, NULL, '2' },
+ { "force_keepalive", no_argument, NULL, '3' },
+ { "disable_port_floating", no_argument, NULL, '4' },
+ { "debug-natt", no_argument, NULL, '5' },
+ { "virtual_private", required_argument, NULL, '6' },
#ifdef DEBUG
- { "debug-none", no_argument, NULL, 'N' },
- { "debug-all", no_argument, NULL, 'A' },
- { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
- { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
- { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
- { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
- { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
- { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
- { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
- { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
- { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
- { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
- { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
-
- { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
- { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
- { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
- { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
+ { "debug-none", no_argument, NULL, 'N' },
+ { "debug-all", no_argument, NULL, 'A' },
+ { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET },
+ { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET },
+ { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET },
+ { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET },
+ { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET },
+ { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET },
+ { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET },
+ { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET },
+ { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET },
+ { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET },
+ { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET },
+
+ { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET },
+ { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET },
+ { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET },
+ { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET },
#endif
- { 0,0,0,0 }
- };
- /* Note: we don't like the way short options get parsed
- * by getopt_long, so we simply pass an empty string as
- * the list. It could be "hvdenp:l:s:" "NARXPECK".
- */
- int c = getopt_long(argc, argv, "", long_opts, NULL);
-
- /* Note: "breaking" from case terminates loop */
- switch (c)
- {
- case EOF: /* end of flags */
- break;
-
- case 0: /* long option already handled */
- continue;
-
- case ':': /* diagnostic already printed by getopt_long */
- case '?': /* diagnostic already printed by getopt_long */
- usage("");
- break; /* not actually reached */
-
- case 'h': /* --help */
- usage(NULL);
- break; /* not actually reached */
-
- case 'v': /* --version */
- {
- const char **sp = ipsec_copyright_notice();
-
- printf("%s%s\n", ipsec_version_string(),
- compile_time_interop_options);
- for (; *sp != NULL; sp++)
- puts(*sp);
- }
- exit_pluto(0);
- break; /* not actually reached */
-
- case '+': /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- case 'd': /* --nofork*/
- fork_desired = FALSE;
- continue;
-
- case 'e': /* --stderrlog */
- log_to_stderr_desired = TRUE;
- continue;
-
- case 'n': /* --noklips */
- no_klips = TRUE;
- continue;
-
- case 'c': /* --nocrsend */
- no_cr_send = TRUE;
- continue;
-
- case 'r': /* --strictcrlpolicy */
- strict_crl_policy = TRUE;
- continue;
-
- case 'x': /* --crlcheckinterval <time>*/
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing interval time");
-
- {
- char *endptr;
- long interval = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || interval <= 0)
- usage("<interval-time> must be a positive number");
- crl_check_interval = interval;
- }
- continue;
-
- case 'C': /* --cachecrls */
- cache_crls = TRUE;
- continue;
-
- case 'u': /* --uniqueids */
- uniqueIDs = TRUE;
- continue;
-
- case 'i': /* --interface <ifname> */
- if (!use_interface(optarg))
- usage("too many --interface specifications");
- continue;
-
- case 'p': /* --port <portnumber> */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing port number");
-
- {
- char *endptr;
- long port = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || port <= 0 || port > 0x10000)
- usage("<port-number> must be a number between 1 and 65535");
- pluto_port = port;
- }
- continue;
-
- case 'b': /* --ctlbase <path> */
- if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
- , "%s%s", optarg, CTL_SUFFIX) == -1)
- usage("<path>" CTL_SUFFIX " too long for sun_path");
- if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
- , "%s%s", optarg, INFO_SUFFIX) == -1)
- usage("<path>" INFO_SUFFIX " too long for sun_path");
- if (snprintf(pluto_lock, sizeof(pluto_lock)
- , "%s%s", optarg, LOCK_SUFFIX) == -1)
- usage("<path>" LOCK_SUFFIX " must fit");
- continue;
-
- case 's': /* --secretsfile <secrets-file> */
- shared_secrets_file = optarg;
- continue;
-
- case 'f': /* --policygroupsdir <policygroups-dir> */
- policygroups_dir = optarg;
- continue;
-
- case 'a': /* --adns <pathname> */
- pluto_adns_option = optarg;
- continue;
-
- case 'm': /* --pkcs11module <pathname> */
- pkcs11_module_path = optarg;
- continue;
-
- case 'k': /* --pkcs11keepstate */
- pkcs11_keep_state = TRUE;
- continue;
-
- case 'y': /* --pkcs11proxy */
- pkcs11_proxy = TRUE;
- continue;
-
- case 'z': /* --pkcs11initargs */
- pkcs11_init_args = optarg;
- continue;
+ { 0,0,0,0 }
+ };
+ /* Note: we don't like the way short options get parsed
+ * by getopt_long, so we simply pass an empty string as
+ * the list. It could be "hvdenp:l:s:" "NARXPECK".
+ */
+ int c = getopt_long(argc, argv, "", long_opts, NULL);
+
+ /* Note: "breaking" from case terminates loop */
+ switch (c)
+ {
+ case EOF: /* end of flags */
+ break;
+
+ case 0: /* long option already handled */
+ continue;
+
+ case ':': /* diagnostic already printed by getopt_long */
+ case '?': /* diagnostic already printed by getopt_long */
+ usage("");
+ break; /* not actually reached */
+
+ case 'h': /* --help */
+ usage(NULL);
+ break; /* not actually reached */
+
+ case 'v': /* --version */
+ {
+ const char **sp = ipsec_copyright_notice();
+
+ printf("strongSwan "VERSION"%s\n", compile_time_interop_options);
+ for (; *sp != NULL; sp++)
+ puts(*sp);
+ }
+ exit_pluto(0);
+ break; /* not actually reached */
+
+ case '+': /* --optionsfrom <filename> */
+ if (!options->from(options, optarg, &argc, &argv, optind))
+ {
+ exit_pluto(1);
+ }
+ continue;
+
+ case 'd': /* --nofork*/
+ fork_desired = FALSE;
+ continue;
+
+ case 'e': /* --stderrlog */
+ log_to_stderr_desired = TRUE;
+ continue;
+
+ case 'n': /* --noklips */
+ no_klips = TRUE;
+ continue;
+
+ case 'c': /* --nocrsend */
+ no_cr_send = TRUE;
+ continue;
+
+ case 'r': /* --strictcrlpolicy */
+ strict_crl_policy = TRUE;
+ continue;
+
+ case 'x': /* --crlcheckinterval <time>*/
+ if (optarg == NULL || !isdigit(optarg[0]))
+ usage("missing interval time");
+
+ {
+ char *endptr;
+ long interval = strtol(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg
+ || interval <= 0)
+ usage("<interval-time> must be a positive number");
+ crl_check_interval = interval;
+ }
+ continue;
+
+ case 'C': /* --cachecrls */
+ cache_crls = TRUE;
+ continue;
+
+ case 'u': /* --uniqueids */
+ uniqueIDs = TRUE;
+ continue;
+
+ case 'i': /* --interface <ifname> */
+ if (!use_interface(optarg))
+ usage("too many --interface specifications");
+ continue;
+
+ case 'p': /* --port <portnumber> */
+ if (optarg == NULL || !isdigit(optarg[0]))
+ usage("missing port number");
+
+ {
+ char *endptr;
+ long port = strtol(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg
+ || port <= 0 || port > 0x10000)
+ usage("<port-number> must be a number between 1 and 65535");
+ pluto_port = port;
+ }
+ continue;
+
+ case 'b': /* --ctlbase <path> */
+ if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
+ , "%s%s", optarg, CTL_SUFFIX) == -1)
+ usage("<path>" CTL_SUFFIX " too long for sun_path");
+ if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path)
+ , "%s%s", optarg, INFO_SUFFIX) == -1)
+ usage("<path>" INFO_SUFFIX " too long for sun_path");
+ if (snprintf(pluto_lock, sizeof(pluto_lock)
+ , "%s%s", optarg, LOCK_SUFFIX) == -1)
+ usage("<path>" LOCK_SUFFIX " must fit");
+ continue;
+
+ case 's': /* --secretsfile <secrets-file> */
+ shared_secrets_file = optarg;
+ continue;
+
+ case 'f': /* --policygroupsdir <policygroups-dir> */
+ policygroups_dir = optarg;
+ continue;
+
+ case 'a': /* --adns <pathname> */
+ pluto_adns_option = optarg;
+ continue;
+
+ case 'm': /* --pkcs11module <pathname> */
+ pkcs11_module_path = optarg;
+ continue;
+
+ case 'k': /* --pkcs11keepstate */
+ pkcs11_keep_state = TRUE;
+ continue;
+
+ case 'y': /* --pkcs11proxy */
+ pkcs11_proxy = TRUE;
+ continue;
+
+ case 'z': /* --pkcs11initargs */
+ pkcs11_init_args = optarg;
+ continue;
#ifdef DEBUG
- case 'N': /* --debug-none */
- base_debugging = DBG_NONE;
- continue;
+ case 'N': /* --debug-none */
+ base_debugging = DBG_NONE;
+ continue;
- case 'A': /* --debug-all */
- base_debugging = DBG_ALL;
- continue;
+ case 'A': /* --debug-all */
+ base_debugging = DBG_ALL;
+ continue;
#endif
- case 'P': /* --perpeerlogbase */
- base_perpeer_logdir = optarg;
- continue;
-
- case 'l':
- log_to_perpeer = TRUE;
- continue;
-
- case '1': /* --nat_traversal */
- nat_traversal = TRUE;
- continue;
- case '2': /* --keep_alive */
- keep_alive = atoi(optarg);
- continue;
- case '3': /* --force_keepalive */
- force_keepalive = TRUE;
- continue;
- case '4': /* --disable_port_floating */
- nat_t_spf = FALSE;
- continue;
- case '5': /* --debug-nat_t */
- base_debugging |= DBG_NATT;
- continue;
- case '6': /* --virtual_private */
- virtual_private = optarg;
- continue;
-
- default:
+ case 'P': /* --perpeerlogbase */
+ base_perpeer_logdir = optarg;
+ continue;
+
+ case 'l':
+ log_to_perpeer = TRUE;
+ continue;
+
+ case '1': /* --nat_traversal */
+ nat_traversal = TRUE;
+ continue;
+ case '2': /* --keep_alive */
+ keep_alive = atoi(optarg);
+ continue;
+ case '3': /* --force_keepalive */
+ force_keepalive = TRUE;
+ continue;
+ case '4': /* --disable_port_floating */
+ nat_t_spf = FALSE;
+ continue;
+ case '5': /* --debug-nat_t */
+ base_debugging |= DBG_NATT;
+ continue;
+ case '6': /* --virtual_private */
+ virtual_private = optarg;
+ continue;
+
+ default:
#ifdef DEBUG
- if (c >= DBG_OFFSET)
- {
- base_debugging |= c - DBG_OFFSET;
- continue;
- }
-# undef DBG_OFFSET
+ if (c >= DBG_OFFSET)
+ {
+ base_debugging |= c - DBG_OFFSET;
+ continue;
+ }
+# undef DBG_OFFSET
#endif
- bad_case(c);
+ bad_case(c);
+ }
+ break;
}
- break;
- }
- if (optind != argc)
- usage("unexpected argument");
- reset_debugging();
- lockfd = create_lock();
+ if (optind != argc)
+ usage("unexpected argument");
+ reset_debugging();
+ lockfd = create_lock();
- /* select between logging methods */
+ /* select between logging methods */
- if (log_to_stderr_desired)
- log_to_syslog = FALSE;
- else
- log_to_stderr = FALSE;
+ if (log_to_stderr_desired)
+ {
+ log_to_syslog = FALSE;
+ }
+ else
+ {
+ log_to_stderr = FALSE;
+ }
- /* set the logging function of pfkey debugging */
+ /* set the logging function of pfkey debugging */
#ifdef DEBUG
- pfkey_debug_func = DBG_log;
+ pfkey_debug_func = DBG_log;
#else
- pfkey_debug_func = NULL;
+ pfkey_debug_func = NULL;
#endif
- /* create control socket.
- * We must create it before the parent process returns so that
- * there will be no race condition in using it. The easiest
- * place to do this is before the daemon fork.
- */
- {
- err_t ugh = init_ctl_socket();
-
- if (ugh != NULL)
+ /* create control socket.
+ * We must create it before the parent process returns so that
+ * there will be no race condition in using it. The easiest
+ * place to do this is before the daemon fork.
+ */
{
- fprintf(stderr, "pluto: %s", ugh);
- exit_pluto(1);
+ err_t ugh = init_ctl_socket();
+
+ if (ugh != NULL)
+ {
+ fprintf(stderr, "pluto: %s", ugh);
+ exit_pluto(1);
+ }
}
- }
- /* If not suppressed, do daemon fork */
+ /* If not suppressed, do daemon fork */
- if (fork_desired)
- {
+ if (fork_desired)
{
- pid_t pid = fork();
+ {
+ pid_t pid = fork();
+
+ if (pid < 0)
+ {
+ int e = errno;
+
+ fprintf(stderr, "pluto: fork failed (%d %s)\n",
+ errno, strerror(e));
+ exit_pluto(1);
+ }
+
+ if (pid != 0)
+ {
+ /* parent: die, after filling PID into lock file.
+ * must not use exit_pluto: lock would be removed!
+ */
+ exit(fill_lock(lockfd, pid)? 0 : 1);
+ }
+ }
+
+ if (setsid() < 0)
+ {
+ int e = errno;
+
+ fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
+ errno, strerror(e));
+ exit_pluto(1);
+ }
+ }
+ else
+ {
+ /* no daemon fork: we have to fill in lock file */
+ (void) fill_lock(lockfd, getpid());
+ fprintf(stdout, "Pluto initialized\n");
+ fflush(stdout);
+ }
- if (pid < 0)
- {
- int e = errno;
+ /* Close everything but ctl_fd and (if needed) stderr.
+ * There is some danger that a library that we don't know
+ * about is using some fd that we don't know about.
+ * I guess we'll soon find out.
+ */
+ {
+ int i;
+
+ for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
+ {
+ if ((!log_to_stderr || i != 2) && i != ctl_fd)
+ close(i);
+ }
+
+ /* make sure that stdin, stdout, stderr are reserved */
+ if (open("/dev/null", O_RDONLY) != 0)
+ abort();
+ if (dup2(0, 1) != 1)
+ abort();
+ if (!log_to_stderr && dup2(0, 2) != 2)
+ abort();
+ }
- fprintf(stderr, "pluto: fork failed (%d %s)\n",
- errno, strerror(e));
- exit_pluto(1);
- }
+ init_constants();
+ init_log("pluto");
- if (pid != 0)
- {
- /* parent: die, after filling PID into lock file.
- * must not use exit_pluto: lock would be removed!
- */
- exit(fill_lock(lockfd, pid)? 0 : 1);
- }
- }
+ /* Note: some scripts may look for this exact message -- don't change
+ * ipsec barf was one, but it no longer does.
+ */
+ plog("Starting IKEv1 pluto daemon (strongSwan "VERSION")%s",
+ compile_time_interop_options);
- if (setsid() < 0)
- {
- int e = errno;
+ /* load plugins, further infrastructure may need it */
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "pluto.load", PLUGINS));
+ print_plugins();
- fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",
- errno, strerror(e));
- exit_pluto(1);
+#ifdef INTEGRITY_TEST
+ DBG1("integrity test of libstrongswan code");
+ if (fips_verify_hmac_signature(hmac_key, hmac_signature))
+ {
+ DBG1(" integrity test passed");
}
- }
- else
- {
- /* no daemon fork: we have to fill in lock file */
- (void) fill_lock(lockfd, getpid());
- fprintf(stdout, "Pluto initialized\n");
- fflush(stdout);
- }
-
- /* Close everything but ctl_fd and (if needed) stderr.
- * There is some danger that a library that we don't know
- * about is using some fd that we don't know about.
- * I guess we'll soon find out.
- */
- {
- int i;
-
- for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */
+ else
{
- if ((!log_to_stderr || i != 2) && i != ctl_fd)
- close(i);
+ DBG1(" integrity test failed");
+ abort();
}
-
- /* make sure that stdin, stdout, stderr are reserved */
- if (open("/dev/null", O_RDONLY) != 0)
- abort();
- if (dup2(0, 1) != 1)
- abort();
- if (!log_to_stderr && dup2(0, 2) != 2)
- abort();
- }
-
- init_constants();
- init_log("pluto");
-
- /* Note: some scripts may look for this exact message -- don't change
- * ipsec barf was one, but it no longer does.
- */
- plog("Starting Pluto (strongSwan Version %s%s)"
- , ipsec_version_code()
- , compile_time_interop_options);
-
- init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
- init_virtual_ip(virtual_private);
- scx_init(pkcs11_module_path, pkcs11_init_args); /* load and initialize PKCS #11 module */
- xauth_init(); /* load and initialize XAUTH module */
- init_rnd_pool();
- init_secret();
- init_states();
- init_crypto();
- init_demux();
- init_kernel();
- init_adns();
- init_id();
- init_fetch();
-
- /* drop unneeded capabilities and change UID/GID */
-
- prctl(PR_SET_KEEPCAPS, 1);
-
+#endif /* INTEGRITY_TEST */
+
+ init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
+ init_virtual_ip(virtual_private);
+ scx_init(pkcs11_module_path, pkcs11_init_args);
+ xauth_init();
+ init_secret();
+ init_states();
+ init_crypto();
+ init_demux();
+ init_kernel();
+ init_adns();
+ init_id();
+ init_fetch();
+
+ /* drop unneeded capabilities and change UID/GID */
+ prctl(PR_SET_KEEPCAPS, 1);
+
#ifdef IPSEC_GROUP
- {
- struct group group, *grp;
- char buf[1024];
-
- if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
- grp == NULL || setgid(grp->gr_gid) != 0)
{
- plog("unable to change daemon group");
- abort();
+ struct group group, *grp;
+ char buf[1024];
+
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
+ grp == NULL || setgid(grp->gr_gid) != 0)
+ {
+ plog("unable to change daemon group");
+ abort();
+ }
}
- }
#endif
#ifdef IPSEC_USER
- {
- struct passwd passwd, *pwp;
- char buf[1024];
-
- if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
- pwp == NULL || setuid(pwp->pw_uid) != 0)
{
- plog("unable to change daemon user");
- abort();
- }
- }
+ struct passwd passwd, *pwp;
+ char buf[1024];
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
+ pwp == NULL || setuid(pwp->pw_uid) != 0)
+ {
+ plog("unable to change daemon user");
+ abort();
+ }
+ }
#endif
#ifdef CAPABILITIES
- caps = cap_init();
- cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
- cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
- cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
- if (cap_set_proc(caps) != 0)
- {
- plog("unable to drop daemon capabilities");
- abort();
- }
- cap_free(caps);
+ caps = cap_init();
+ cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
+ cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
+ cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
+ if (cap_set_proc(caps) != 0)
+ {
+ plog("unable to drop daemon capabilities");
+ abort();
+ }
+ cap_free(caps);
#endif /* CAPABILITIES */
- /* loading X.509 CA certificates */
- load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
- /* loading X.509 AA certificates */
- load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
- /* loading X.509 OCSP certificates */
- load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
- /* loading X.509 CRLs */
- load_crls();
- /* loading attribute certificates (experimental) */
- load_acerts();
-
- daily_log_event();
- call_server();
- return -1; /* Shouldn't ever reach this */
+ /* loading X.509 CA certificates */
+ load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
+ /* loading X.509 AA certificates */
+ load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
+ /* loading X.509 OCSP certificates */
+ load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
+ /* loading X.509 CRLs */
+ load_crls();
+ /* loading attribute certificates (experimental) */
+ load_acerts();
+
+ daily_log_event();
+ call_server();
+ return -1; /* Shouldn't ever reach this */
}
/* leave pluto, with status.
@@ -686,31 +735,33 @@ main(int argc, char **argv)
* 1 general discomfort
* 10 lock file exists
*/
-void
-exit_pluto(int status)
+void exit_pluto(int status)
{
- reset_globals(); /* needed because we may be called in odd state */
- free_preshared_secrets();
- free_remembered_public_keys();
- delete_every_connection();
- free_crl_fetch(); /* free chain of crl fetch requests */
- free_ocsp_fetch(); /* free chain of ocsp fetch requests */
- free_authcerts(); /* free chain of X.509 authority certificates */
- free_crls(); /* free chain of X.509 CRLs */
- free_acerts(); /* free chain of X.509 attribute certificates */
- free_ca_infos(); /* free chain of X.509 CA information records */
- free_ocsp(); /* free ocsp cache */
- free_ifaces();
- scx_finalize(); /* finalize and unload PKCS #11 module */
- xauth_finalize(); /* finalize and unload XAUTH module */
- stop_adns();
- free_md_pool();
- delete_lock();
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- exit(status);
+ reset_globals(); /* needed because we may be called in odd state */
+ free_preshared_secrets();
+ free_remembered_public_keys();
+ delete_every_connection();
+ free_crl_fetch(); /* free chain of crl fetch requests */
+ free_ocsp_fetch(); /* free chain of ocsp fetch requests */
+ free_authcerts(); /* free chain of X.509 authority certificates */
+ free_crls(); /* free chain of X.509 CRLs */
+ free_acerts(); /* free chain of X.509 attribute certificates */
+ free_ca_infos(); /* free chain of X.509 CA information records */
+ free_ocsp(); /* free ocsp cache */
+ free_ifaces();
+ scx_finalize(); /* finalize and unload PKCS #11 module */
+ xauth_finalize(); /* finalize and unload XAUTH module */
+ stop_adns();
+ free_md_pool();
+ free_crypto();
+ free_id(); /* free myids */
+ free_events(); /* free remaining events */
+ free_vendorid(); /* free all vendor id records */
+ delete_lock();
+ options->destroy(options);
+ library_deinit();
+ close_log();
+ exit(status);
}
/*
diff --git a/src/pluto/primegen.c b/src/pluto/primegen.c
deleted file mode 100644
index 159490345..000000000
--- a/src/pluto/primegen.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/* primegen.c - prime number generator
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * ***********************************************************************
- * The algorithm used to generate practically save primes is due to
- * Lim and Lee as described in the CRYPTO '97 proceedings (ISBN3540633847)
- * page 260.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "log.h"
-#include "rnd.h"
-#include "gcryptfix.h"
-#else /*! PLUTO */
-/* #include <assert.h> */
-/* #include <config.h> */
-/* #include "util.h" */
-/* #include "mpi.h" */
-/* #include "cipher.h" */
-#endif /* !PLUTO */
-
-static int no_of_small_prime_numbers;
-static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
-static int check_prime( MPI prime, MPI val_2 );
-static int is_prime( MPI n, unsigned steps, int *count );
-static void m_out_of_n( char *array, int m, int n );
-
-
-static void
-progress( int c )
-{
- fputc( c, stderr );
-}
-
-
-/****************
- * Generate a prime number (stored in secure memory)
- */
-MPI
-generate_secret_prime( unsigned nbits )
-{
- MPI prime;
-
- prime = gen_prime( nbits, 1, 2 );
- progress('\n');
- return prime;
-}
-
-MPI
-generate_public_prime( unsigned nbits )
-{
- MPI prime;
-
- prime = gen_prime( nbits, 0, 2 );
- progress('\n');
- return prime;
-}
-
-
-/****************
- * We do not need to use the strongest RNG because we gain no extra
- * security from it - The prime number is public and we could also
- * offer the factors for those who are willing to check that it is
- * indeed a strong prime.
- *
- * mode 0: Standard
- * 1: Make sure that at least one factor is of size qbits.
- */
-MPI
-generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
- MPI g, MPI **ret_factors )
-{
- int n; /* number of factors */
- int m; /* number of primes in pool */
- unsigned fbits; /* length of prime factors */
- MPI *factors; /* current factors */
- MPI *pool; /* pool of primes */
- MPI q; /* first prime factor (variable)*/
- MPI prime; /* prime test value */
- MPI q_factor; /* used for mode 1 */
- byte *perms = NULL;
- int i, j;
- int count1, count2;
- unsigned nprime;
- unsigned req_qbits = qbits; /* the requested q bits size */
- MPI val_2 = mpi_alloc_set_ui( 2 );
-
- /* find number of needed prime factors */
- for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
- ;
- n--;
- if( !n || (mode==1 && n < 2) )
- log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
- if( mode == 1 ) {
- n--;
- fbits = (pbits - 2*req_qbits -1) / n;
- qbits = pbits - req_qbits - n*fbits;
- }
- else {
- fbits = (pbits - req_qbits -1) / n;
- qbits = pbits - n*fbits;
- }
- if( DBG_CIPHER )
- log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
- pbits, req_qbits, qbits, fbits, n );
- prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
- q = gen_prime( qbits, 0, 1 );
- q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
-
- /* allocate an array to hold the factors + 2 for later usage */
-#ifdef PLUTO
- m_alloc_ptrs_clear(factors, n+2);
-#else
- factors = m_alloc_clear( (n+2) * sizeof *factors );
-#endif
-
- /* make a pool of 3n+5 primes (this is an arbitrary value) */
- m = n*3+5;
- if( mode == 1 )
- m += 5; /* need some more for DSA */
- if( m < 25 )
- m = 25;
-#ifdef PLUTO
- m_alloc_ptrs_clear(pool, m);
-#else
- pool = m_alloc_clear( m * sizeof *pool );
-#endif
-
- /* permutate over the pool of primes */
- count1=count2=0;
- do {
- next_try:
- if( !perms ) {
- /* allocate new primes */
- for(i=0; i < m; i++ ) {
- mpi_free(pool[i]);
- pool[i] = NULL;
- }
- /* init m_out_of_n() */
-#ifdef PLUTO
- perms = alloc_bytes( m, "perms" );
-#else
- perms = m_alloc_clear( m );
-#endif
- for(i=0; i < n; i++ ) {
- perms[i] = 1;
- pool[i] = gen_prime( fbits, 0, 1 );
- factors[i] = pool[i];
- }
- }
- else {
- m_out_of_n( perms, n, m );
- for(i=j=0; i < m && j < n ; i++ )
- if( perms[i] ) {
- if( !pool[i] )
- pool[i] = gen_prime( fbits, 0, 1 );
- factors[j++] = pool[i];
- }
- if( i == n ) {
- m_free(perms); perms = NULL;
- progress('!');
- goto next_try; /* allocate new primes */
- }
- }
-
- mpi_set( prime, q );
- mpi_mul_ui( prime, prime, 2 );
- if( mode == 1 )
- mpi_mul( prime, prime, q_factor );
- for(i=0; i < n; i++ )
- mpi_mul( prime, prime, factors[i] );
- mpi_add_ui( prime, prime, 1 );
- nprime = mpi_get_nbits(prime);
- if( nprime < pbits ) {
- if( ++count1 > 20 ) {
- count1 = 0;
- qbits++;
- progress('>');
- q = gen_prime( qbits, 0, 1 );
- goto next_try;
- }
- }
- else
- count1 = 0;
- if( nprime > pbits ) {
- if( ++count2 > 20 ) {
- count2 = 0;
- qbits--;
- progress('<');
- q = gen_prime( qbits, 0, 1 );
- goto next_try;
- }
- }
- else
- count2 = 0;
- } while( !(nprime == pbits && check_prime( prime, val_2 )) );
-
- if( DBG_CIPHER ) {
- progress('\n');
- log_mpidump( "prime : ", prime );
- log_mpidump( "factor q: ", q );
- if( mode == 1 )
- log_mpidump( "factor q0: ", q_factor );
- for(i=0; i < n; i++ )
- log_mpidump( "factor pi: ", factors[i] );
- log_debug("bit sizes: prime=%u, q=%u", mpi_get_nbits(prime), mpi_get_nbits(q) );
- if( mode == 1 )
- fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
- for(i=0; i < n; i++ )
- fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
- progress('\n');
- }
-
- if( ret_factors ) { /* caller wants the factors */
-#ifdef PLUTO
- m_alloc_ptrs_clear(*ret_factors, n+2);
-#else
- *ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors);
-#endif
- if( mode == 1 ) {
- i = 0;
- (*ret_factors)[i++] = mpi_copy( q_factor );
- for(; i <= n; i++ )
- (*ret_factors)[i] = mpi_copy( factors[i] );
- }
- else {
- for(; i < n; i++ )
- (*ret_factors)[i] = mpi_copy( factors[i] );
- }
- }
-
- if( g ) { /* create a generator (start with 3)*/
- MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
- MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
- MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
-
- if( mode == 1 )
- BUG(); /* not yet implemented */
- factors[n] = q;
- factors[n+1] = mpi_alloc_set_ui(2);
- mpi_sub_ui( pmin1, prime, 1 );
- mpi_set_ui(g,2);
- do {
- mpi_add_ui(g, g, 1);
- if( DBG_CIPHER ) {
-#ifdef PLUTO
- log_mpidump("checking g: ", g);
-#else
- log_debug("checking g: ");
- mpi_print( stderr, g, 1 );
-#endif
- }
- else
- progress('^');
- for(i=0; i < n+2; i++ ) {
- /*fputc('~', stderr);*/
- mpi_fdiv_q(tmp, pmin1, factors[i] );
- /* (no mpi_pow(), but it is okay to use this with mod prime) */
- mpi_powm(b, g, tmp, prime );
- if( !mpi_cmp_ui(b, 1) )
- break;
- }
- if( DBG_CIPHER )
- progress('\n');
- } while( i < n+2 );
- mpi_free(factors[n+1]);
- mpi_free(tmp);
- mpi_free(b);
- mpi_free(pmin1);
- }
- if( !DBG_CIPHER )
- progress('\n');
-
- m_free( factors ); /* (factors are shallow copies) */
- for(i=0; i < m; i++ )
- mpi_free( pool[i] );
- m_free( pool );
- m_free(perms);
- mpi_free(val_2);
- return prime;
-}
-
-
-
-static MPI
-gen_prime( unsigned nbits, int secret, int randomlevel )
-{
- unsigned nlimbs;
- MPI prime, ptest, pminus1, val_2, val_3, result;
- int i;
- unsigned x, step;
- unsigned count1, count2;
- int *mods;
-
- if( 0 && DBG_CIPHER )
- log_debug("generate a prime of %u bits ", nbits );
-
- if( !no_of_small_prime_numbers ) {
- for(i=0; small_prime_numbers[i]; i++ )
- no_of_small_prime_numbers++;
- }
- mods = m_alloc( no_of_small_prime_numbers * sizeof *mods );
- /* make nbits fit into MPI implementation */
- nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB;
- val_2 = mpi_alloc_set_ui( 2 );
- val_3 = mpi_alloc_set_ui( 3);
- prime = secret? mpi_alloc_secure( nlimbs ): mpi_alloc( nlimbs );
- result = mpi_alloc_like( prime );
- pminus1= mpi_alloc_like( prime );
- ptest = mpi_alloc_like( prime );
- count1 = count2 = 0;
- for(;;) { /* try forvever */
- int dotcount=0;
-
- /* generate a random number */
- { char *p = get_random_bits( nbits, randomlevel, secret );
- mpi_set_buffer( prime, p, (nbits+7)/8, 0 );
- m_free(p);
- }
-
- /* set high order bit to 1, set low order bit to 1 */
- mpi_set_highbit( prime, nbits-1 );
- mpi_set_bit( prime, 0 );
-
- /* calculate all remainders */
- for(i=0; (x = small_prime_numbers[i]); i++ )
- mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
-
- /* now try some primes starting with prime */
- for(step=0; step < 20000; step += 2 ) {
- /* check against all the small primes we have in mods */
- count1++;
- for(i=0; (x = small_prime_numbers[i]); i++ ) {
- while( mods[i] + step >= x )
- mods[i] -= x;
- if( !(mods[i] + step) )
- break;
- }
- if( x )
- continue; /* found a multiple of an already known prime */
-
- mpi_add_ui( ptest, prime, step );
-
- /* do a faster Fermat test */
- count2++;
- mpi_sub_ui( pminus1, ptest, 1);
- mpi_powm( result, val_2, pminus1, ptest );
- if( !mpi_cmp_ui( result, 1 ) ) { /* not composite */
- /* perform stronger tests */
- if( is_prime(ptest, 5, &count2 ) ) {
- if( !mpi_test_bit( ptest, nbits-1 ) ) {
- progress('\n');
- log_debug("overflow in prime generation\n");
- break; /* step loop, continue with a new prime */
- }
-
- mpi_free(val_2);
- mpi_free(val_3);
- mpi_free(result);
- mpi_free(pminus1);
- mpi_free(prime);
- m_free(mods);
- return ptest;
- }
- }
- if( ++dotcount == 10 ) {
- progress('.');
- dotcount = 0;
- }
- }
- progress(':'); /* restart with a new random value */
- }
-}
-
-/****************
- * Returns: true if this may be a prime
- */
-static int
-check_prime( MPI prime, MPI val_2 )
-{
- int i;
- unsigned x;
- int count=0;
-
- /* check against small primes */
- for(i=0; (x = small_prime_numbers[i]); i++ ) {
- if( mpi_divisible_ui( prime, x ) )
- return 0;
- }
-
- /* a quick fermat test */
- {
- MPI result = mpi_alloc_like( prime );
- MPI pminus1 = mpi_alloc_like( prime );
- mpi_sub_ui( pminus1, prime, 1);
- mpi_powm( result, val_2, pminus1, prime );
- mpi_free( pminus1 );
- if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
- mpi_free( result );
- progress('.');
- return 0;
- }
- mpi_free( result );
- }
-
- /* perform stronger tests */
- if( is_prime(prime, 5, &count ) )
- return 1; /* is probably a prime */
- progress('.');
- return 0;
-}
-
-
-/****************
- * Return true if n is probably a prime
- */
-static int
-is_prime( MPI n, unsigned steps, int *count )
-{
- MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI z = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
- MPI a2 = mpi_alloc_set_ui( 2 );
- MPI q;
- unsigned i, j, k;
- int rc = 0;
- unsigned nbits = mpi_get_nbits( n );
-
- mpi_sub_ui( nminus1, n, 1 );
-
- /* find q and k, so that n = 1 + 2^k * q */
- q = mpi_copy( nminus1 );
- k = mpi_trailing_zeros( q );
- mpi_tdiv_q_2exp(q, q, k);
-
- for(i=0 ; i < steps; i++ ) {
- ++*count;
- if( !i ) {
- mpi_set_ui( x, 2 );
- }
- else {
- /*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/
- { char *p = get_random_bits( nbits, 0, 0 );
- mpi_set_buffer( x, p, (nbits+7)/8, 0 );
- m_free(p);
- }
- /* make sure that the number is smaller than the prime
- * and keep the randomness of the high bit */
- if( mpi_test_bit( x, nbits-2 ) ) {
- mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
- }
- else {
- mpi_set_highbit( x, nbits-2 );
- mpi_clear_bit( x, nbits-2 );
- }
- assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
- }
- mpi_powm( y, x, q, n);
- if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
- for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
- mpi_powm(y, y, a2, n);
- if( !mpi_cmp_ui( y, 1 ) )
- goto leave; /* not a prime */
- }
- if( mpi_cmp( y, nminus1 ) )
- goto leave; /* not a prime */
- }
- progress('+');
- }
- rc = 1; /* may be a prime */
-
- leave:
- mpi_free( x );
- mpi_free( y );
- mpi_free( z );
- mpi_free( nminus1 );
- mpi_free( q );
-
- return rc;
-}
-
-
-static void
-m_out_of_n( char *array, int m, int n )
-{
- int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
-
- if( !m || m >= n )
- return;
-
- if( m == 1 ) { /* special case */
- for(i=0; i < n; i++ )
- if( array[i] ) {
- array[i++] = 0;
- if( i >= n )
- i = 0;
- array[i] = 1;
- return;
- }
- BUG();
- }
-
- for(j=1; j < n; j++ ) {
- if( array[n-1] == array[n-j-1] )
- continue;
- j1 = j;
- break;
- }
-
- if( m & 1 ) { /* m is odd */
- if( array[n-1] ) {
- if( j1 & 1 ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- goto scan;
- }
- k2 = n - j1 - 1;
- if( k2 == 0 ) {
- k1 = i;
- k2 = n - j1;
- }
- else if( array[k2] && array[k2-1] )
- k1 = n;
- else
- k1 = k2 + 1;
- }
- else { /* m is even */
- if( !array[n-1] ) {
- k1 = n - j1;
- k2 = k1 + 1;
- goto leave;
- }
-
- if( !(j1 & 1) ) {
- k1 = n - j1;
- k2 = k1+2;
- if( k2 > n )
- k2 = n;
- goto leave;
- }
- scan:
- jp = n - j1 - 1;
- for(i=1; i <= jp; i++ ) {
- i1 = jp + 2 - i;
- if( array[i1-1] ) {
- if( array[i1-2] ) {
- k1 = i1 - 1;
- k2 = n - j1;
- }
- else {
- k1 = i1 - 1;
- k2 = n + 1 - j1;
- }
- goto leave;
- }
- }
- k1 = 1;
- k2 = n + 1 - m;
- }
- leave:
- array[k1-1] = !array[k1-1];
- array[k2-1] = !array[k2-1];
-}
-
diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c
index 00fed63ea..013deb446 100644
--- a/src/pluto/rcv_whack.c
+++ b/src/pluto/rcv_whack.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: rcv_whack.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <fcntl.h>
@@ -42,17 +40,17 @@
#include "smartcard.h"
#include "connections.h"
#include "foodgroups.h"
-#include "whack.h" /* needs connections.h */
+#include "whack.h" /* needs connections.h */
#include "packet.h"
-#include "demux.h" /* needs packet.h */
+#include "demux.h" /* needs packet.h */
#include "state.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "kernel.h"
#include "rcv_whack.h"
#include "log.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
#include "server.h"
#include "fetch.h"
#include "ocsp.h"
@@ -63,186 +61,186 @@
/* helper variables and function to decode strings from whack message */
static char *next_str
- , *str_roof;
+ , *str_roof;
static bool
unpack_str(char **p)
{
- char *end = memchr(next_str, '\0', str_roof - next_str);
-
- if (end == NULL)
- {
- return FALSE; /* fishy: no end found */
- }
- else
- {
- *p = next_str == end? NULL : next_str;
- next_str = end + 1;
- return TRUE;
- }
+ char *end = memchr(next_str, '\0', str_roof - next_str);
+
+ if (end == NULL)
+ {
+ return FALSE; /* fishy: no end found */
+ }
+ else
+ {
+ *p = next_str == end? NULL : next_str;
+ next_str = end + 1;
+ return TRUE;
+ }
}
/* bits loading keys from asynchronous DNS */
enum key_add_attempt {
- ka_TXT,
+ ka_TXT,
#ifdef USE_KEYRR
- ka_KEY,
+ ka_KEY,
#endif
- ka_roof /* largest value + 1 */
+ ka_roof /* largest value + 1 */
};
struct key_add_common {
- int refCount;
- char *diag[ka_roof];
- int whack_fd;
- bool success;
+ int refCount;
+ char *diag[ka_roof];
+ int whack_fd;
+ bool success;
};
struct key_add_continuation {
- struct adns_continuation ac; /* common prefix */
- struct key_add_common *common; /* common data */
- enum key_add_attempt lookingfor;
+ struct adns_continuation ac; /* common prefix */
+ struct key_add_common *common; /* common data */
+ enum key_add_attempt lookingfor;
};
static void
key_add_ugh(const struct id *keyid, err_t ugh)
{
- char name[BUF_LEN]; /* longer IDs will be truncated in message */
+ char name[BUF_LEN]; /* longer IDs will be truncated in message */
- (void)idtoa(keyid, name, sizeof(name));
- loglog(RC_NOKEY
- , "failure to fetch key for %s from DNS: %s", name, ugh);
+ (void)idtoa(keyid, name, sizeof(name));
+ loglog(RC_NOKEY
+ , "failure to fetch key for %s from DNS: %s", name, ugh);
}
/* last one out: turn out the lights */
static void
key_add_merge(struct key_add_common *oc, const struct id *keyid)
{
- if (oc->refCount == 0)
- {
- enum key_add_attempt kaa;
-
- /* if no success, print all diagnostics */
- if (!oc->success)
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- key_add_ugh(keyid, oc->diag[kaa]);
+ if (oc->refCount == 0)
+ {
+ enum key_add_attempt kaa;
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- pfreeany(oc->diag[kaa]);
+ /* if no success, print all diagnostics */
+ if (!oc->success)
+ for (kaa = ka_TXT; kaa != ka_roof; kaa++)
+ key_add_ugh(keyid, oc->diag[kaa]);
- close(oc->whack_fd);
- pfree(oc);
- }
+ for (kaa = ka_TXT; kaa != ka_roof; kaa++)
+ {
+ free(oc->diag[kaa]);
+ }
+ close(oc->whack_fd);
+ free(oc);
+ }
}
static void
key_add_continue(struct adns_continuation *ac, err_t ugh)
{
- struct key_add_continuation *kc = (void *) ac;
- struct key_add_common *oc = kc->common;
-
- passert(whack_log_fd == NULL_FD);
- whack_log_fd = oc->whack_fd;
-
- if (ugh != NULL)
- {
- oc->diag[kc->lookingfor] = clone_str(ugh, "key add error");
- }
- else
- {
- oc->success = TRUE;
- transfer_to_public_keys(kc->ac.gateways_from_dns
+ struct key_add_continuation *kc = (void *) ac;
+ struct key_add_common *oc = kc->common;
+
+ passert(whack_log_fd == NULL_FD);
+ whack_log_fd = oc->whack_fd;
+
+ if (ugh != NULL)
+ {
+ oc->diag[kc->lookingfor] = clone_str(ugh);
+ }
+ else
+ {
+ oc->success = TRUE;
+ transfer_to_public_keys(kc->ac.gateways_from_dns
#ifdef USE_KEYRR
- , &kc->ac.keys_from_dns
+ , &kc->ac.keys_from_dns
#endif /* USE_KEYRR */
- );
- }
+ );
+ }
- oc->refCount--;
- key_add_merge(oc, &ac->id);
- whack_log_fd = NULL_FD;
+ oc->refCount--;
+ key_add_merge(oc, &ac->id);
+ whack_log_fd = NULL_FD;
}
static void
key_add_request(const whack_message_t *msg)
{
- struct id keyid;
- err_t ugh = atoid(msg->keyid, &keyid, FALSE);
-
- if (ugh != NULL)
- {
- loglog(RC_BADID, "bad --keyid \"%s\": %s", msg->keyid, ugh);
- }
- else
- {
- if (!msg->whack_addkey)
- delete_public_keys(&keyid, msg->pubkey_alg
- , empty_chunk, empty_chunk);
-
- if (msg->keyval.len == 0)
- {
- struct key_add_common *oc
- = alloc_thing(struct key_add_common
- , "key add common things");
- enum key_add_attempt kaa;
-
- /* initialize state shared by queries */
- oc->refCount = 0;
- oc->whack_fd = dup_any(whack_log_fd);
- oc->success = FALSE;
-
- for (kaa = ka_TXT; kaa != ka_roof; kaa++)
- {
- struct key_add_continuation *kc
- = alloc_thing(struct key_add_continuation
- , "key add continuation");
-
- oc->diag[kaa] = NULL;
- oc->refCount++;
- kc->common = oc;
- kc->lookingfor = kaa;
- switch (kaa)
+ struct id keyid;
+ err_t ugh = atoid(msg->keyid, &keyid, FALSE);
+
+ if (ugh != NULL)
+ {
+ loglog(RC_BADID, "bad --keyid \"%s\": %s", msg->keyid, ugh);
+ }
+ else
+ {
+ if (!msg->whack_addkey)
+ delete_public_keys(&keyid, msg->pubkey_alg
+ , chunk_empty, chunk_empty);
+
+ if (msg->keyval.len == 0)
{
- case ka_TXT:
- ugh = start_adns_query(&keyid
- , &keyid /* same */
- , T_TXT
- , key_add_continue
- , &kc->ac);
- break;
+ struct key_add_common *oc = malloc_thing(struct key_add_common);
+ enum key_add_attempt kaa;
+
+ /* initialize state shared by queries */
+ oc->refCount = 0;
+ oc->whack_fd = dup_any(whack_log_fd);
+ oc->success = FALSE;
+
+ for (kaa = ka_TXT; kaa != ka_roof; kaa++)
+ {
+ struct key_add_continuation *kc;
+
+ oc->diag[kaa] = NULL;
+ oc->refCount++;
+ kc = malloc_thing(struct key_add_continuation);
+ kc->common = oc;
+ kc->lookingfor = kaa;
+
+ switch (kaa)
+ {
+ case ka_TXT:
+ ugh = start_adns_query(&keyid
+ , &keyid /* same */
+ , T_TXT
+ , key_add_continue
+ , &kc->ac);
+ break;
#ifdef USE_KEYRR
- case ka_KEY:
- ugh = start_adns_query(&keyid
- , NULL
- , T_KEY
- , key_add_continue
- , &kc->ac);
- break;
+ case ka_KEY:
+ ugh = start_adns_query(&keyid
+ , NULL
+ , T_KEY
+ , key_add_continue
+ , &kc->ac);
+ break;
#endif /* USE_KEYRR */
- default:
- bad_case(kaa); /* suppress gcc warning */
+ default:
+ bad_case(kaa); /* suppress gcc warning */
+ }
+ if (ugh != NULL)
+ {
+ oc->diag[kaa] = clone_str(ugh);
+ oc->refCount--;
+ }
+ }
+
+ /* Done launching queries.
+ * Handle total failure case.
+ */
+ key_add_merge(oc, &keyid);
}
- if (ugh != NULL)
+ else
{
- oc->diag[kaa] = clone_str(ugh, "early key add failure");
- oc->refCount--;
+ if (!add_public_key(&keyid, DAL_LOCAL, msg->pubkey_alg, msg->keyval,
+ &pubkeys))
+ {
+ loglog(RC_LOG_SERIOUS, "failed to add public key");
+ }
}
- }
-
- /* Done launching queries.
- * Handle total failure case.
- */
- key_add_merge(oc, &keyid);
}
- else
- {
- ugh = add_public_key(&keyid, DAL_LOCAL, msg->pubkey_alg
- , &msg->keyval, &pubkeys);
- if (ugh != NULL)
- loglog(RC_LOG_SERIOUS, "%s", ugh);
- }
- }
}
/* Handle a kernel request. Supposedly, there's a message in
@@ -251,430 +249,431 @@ key_add_request(const whack_message_t *msg)
void
whack_handle(int whackctlfd)
{
- whack_message_t msg;
- struct sockaddr_un whackaddr;
- int whackaddrlen = sizeof(whackaddr);
- int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
- /* Note: actual value in n should fit in int. To print, cast to int. */
- ssize_t n;
-
- if (whackfd < 0)
- {
- log_errno((e, "accept() failed in whack_handle()"));
- return;
- }
- if (fcntl(whackfd, F_SETFD, FD_CLOEXEC) < 0)
- {
- log_errno((e, "failed to set CLOEXEC in whack_handle()"));
- close(whackfd);
- return;
- }
+ whack_message_t msg;
+ struct sockaddr_un whackaddr;
+ int whackaddrlen = sizeof(whackaddr);
+ int whackfd = accept(whackctlfd, (struct sockaddr *)&whackaddr, &whackaddrlen);
+ /* Note: actual value in n should fit in int. To print, cast to int. */
+ ssize_t n;
+
+ if (whackfd < 0)
+ {
+ log_errno((e, "accept() failed in whack_handle()"));
+ return;
+ }
+ if (fcntl(whackfd, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ log_errno((e, "failed to set CLOEXEC in whack_handle()"));
+ close(whackfd);
+ return;
+ }
- n = read(whackfd, &msg, sizeof(msg));
+ n = read(whackfd, &msg, sizeof(msg));
- if (n == -1)
- {
- log_errno((e, "read() failed in whack_handle()"));
- close(whackfd);
- return;
- }
+ if (n == -1)
+ {
+ log_errno((e, "read() failed in whack_handle()"));
+ close(whackfd);
+ return;
+ }
- whack_log_fd = whackfd;
+ whack_log_fd = whackfd;
- /* sanity check message */
- {
- err_t ugh = NULL;
+ /* sanity check message */
+ {
+ err_t ugh = NULL;
- next_str = msg.string;
- str_roof = (char *)&msg + n;
+ next_str = msg.string;
+ str_roof = (char *)&msg + n;
- if ((size_t)n < offsetof(whack_message_t, whack_shutdown) + sizeof(msg.whack_shutdown))
+ if ((size_t)n < offsetof(whack_message_t, whack_shutdown) + sizeof(msg.whack_shutdown))
+ {
+ ugh = builddiag("ignoring runt message from whack: got %d bytes", (int)n);
+ }
+ else if (msg.magic != WHACK_MAGIC)
+ {
+ if (msg.magic == WHACK_BASIC_MAGIC)
+ {
+ /* Only shutdown command. Simpler inter-version compatability. */
+ if (msg.whack_shutdown)
+ {
+ plog("shutting down");
+ exit_pluto(0); /* delete lock and leave, with 0 status */
+ }
+ ugh = ""; /* bail early, but without complaint */
+ }
+ else
+ {
+ ugh = builddiag("ignoring message from whack with bad magic %d; should be %d; probably wrong version"
+ , msg.magic, WHACK_MAGIC);
+ }
+ }
+ else if (next_str > str_roof)
+ {
+ ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
+ , (int) n, (unsigned) sizeof(msg));
+ }
+ else if (!unpack_str(&msg.name) /* string 1 */
+ || !unpack_str(&msg.left.id) /* string 2 */
+ || !unpack_str(&msg.left.cert) /* string 3 */
+ || !unpack_str(&msg.left.ca) /* string 4 */
+ || !unpack_str(&msg.left.groups) /* string 5 */
+ || !unpack_str(&msg.left.updown) /* string 6 */
+ || !unpack_str(&msg.left.virt) /* string 7 */
+ || !unpack_str(&msg.right.id) /* string 8 */
+ || !unpack_str(&msg.right.cert) /* string 9 */
+ || !unpack_str(&msg.right.ca) /* string 10 */
+ || !unpack_str(&msg.right.groups) /* string 11 */
+ || !unpack_str(&msg.right.updown) /* string 12 */
+ || !unpack_str(&msg.right.virt) /* string 13 */
+ || !unpack_str(&msg.keyid) /* string 14 */
+ || !unpack_str(&msg.myid) /* string 15 */
+ || !unpack_str(&msg.cacert) /* string 16 */
+ || !unpack_str(&msg.ldaphost) /* string 17 */
+ || !unpack_str(&msg.ldapbase) /* string 18 */
+ || !unpack_str(&msg.crluri) /* string 19 */
+ || !unpack_str(&msg.crluri2) /* string 20 */
+ || !unpack_str(&msg.ocspuri) /* string 21 */
+ || !unpack_str(&msg.ike) /* string 22 */
+ || !unpack_str(&msg.esp) /* string 23 */
+ || !unpack_str(&msg.sc_data) /* string 24 */
+ || str_roof - next_str != (ptrdiff_t)msg.keyval.len) /* check chunk */
+ {
+ ugh = "message from whack contains bad string";
+ }
+ else
+ {
+ msg.keyval.ptr = next_str; /* grab chunk */
+ }
+
+ if (ugh != NULL)
+ {
+ if (*ugh != '\0')
+ loglog(RC_BADWHACKMESSAGE, "%s", ugh);
+ whack_log_fd = NULL_FD;
+ close(whackfd);
+ return;
+ }
+ }
+
+ if (msg.whack_options)
{
- ugh = builddiag("ignoring runt message from whack: got %d bytes", (int)n);
+#ifdef DEBUG
+ if (msg.name == NULL)
+ {
+ /* we do a two-step so that if either old or new would
+ * cause the message to print, it will be printed.
+ */
+ cur_debugging |= msg.debugging;
+ DBG(DBG_CONTROL
+ , DBG_log("base debugging = %s"
+ , bitnamesof(debug_bit_names, msg.debugging)));
+ cur_debugging = base_debugging = msg.debugging;
+ }
+ else if (!msg.whack_connection)
+ {
+ struct connection *c = con_by_name(msg.name, TRUE);
+
+ if (c != NULL)
+ {
+ c->extra_debugging = msg.debugging;
+ DBG(DBG_CONTROL
+ , DBG_log("\"%s\" extra_debugging = %s"
+ , c->name
+ , bitnamesof(debug_bit_names, c->extra_debugging)));
+ }
+ }
+#endif
+ }
+
+ if (msg.whack_myid)
+ set_myid(MYID_SPECIFIED, msg.myid);
+
+ /* Deleting combined with adding a connection works as replace.
+ * To make this more useful, in only this combination,
+ * delete will silently ignore the lack of the connection.
+ */
+ if (msg.whack_delete)
+ {
+ if (msg.whack_ca)
+ find_ca_info_by_name(msg.name, TRUE);
+ else
+ delete_connections_by_name(msg.name, !msg.whack_connection);
}
- else if (msg.magic != WHACK_MAGIC)
+
+ if (msg.whack_deletestate)
{
- if (msg.magic == WHACK_BASIC_MAGIC)
- {
- /* Only shutdown command. Simpler inter-version compatability. */
- if (msg.whack_shutdown)
+ struct state *st = state_with_serialno(msg.whack_deletestateno);
+
+ if (st == NULL)
+ {
+ loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
+ , msg.whack_deletestateno);
+ }
+ else
{
- plog("shutting down");
- exit_pluto(0); /* delete lock and leave, with 0 status */
+ delete_state(st);
}
- ugh = ""; /* bail early, but without complaint */
- }
- else
- {
- ugh = builddiag("ignoring message from whack with bad magic %d; should be %d; probably wrong version"
- , msg.magic, WHACK_MAGIC);
- }
- }
- else if (next_str > str_roof)
- {
- ugh = builddiag("ignoring truncated message from whack: got %d bytes; expected %u"
- , (int) n, (unsigned) sizeof(msg));
- }
- else if (!unpack_str(&msg.name) /* string 1 */
- || !unpack_str(&msg.left.id) /* string 2 */
- || !unpack_str(&msg.left.cert) /* string 3 */
- || !unpack_str(&msg.left.ca) /* string 4 */
- || !unpack_str(&msg.left.groups) /* string 5 */
- || !unpack_str(&msg.left.updown) /* string 6 */
- || !unpack_str(&msg.left.virt) /* string 7 */
- || !unpack_str(&msg.right.id) /* string 8 */
- || !unpack_str(&msg.right.cert) /* string 9 */
- || !unpack_str(&msg.right.ca) /* string 10 */
- || !unpack_str(&msg.right.groups) /* string 11 */
- || !unpack_str(&msg.right.updown) /* string 12 */
- || !unpack_str(&msg.right.virt) /* string 13 */
- || !unpack_str(&msg.keyid) /* string 14 */
- || !unpack_str(&msg.myid) /* string 15 */
- || !unpack_str(&msg.cacert) /* string 16 */
- || !unpack_str(&msg.ldaphost) /* string 17 */
- || !unpack_str(&msg.ldapbase) /* string 18 */
- || !unpack_str(&msg.crluri) /* string 19 */
- || !unpack_str(&msg.crluri2) /* string 20 */
- || !unpack_str(&msg.ocspuri) /* string 21 */
- || !unpack_str(&msg.ike) /* string 22 */
- || !unpack_str(&msg.esp) /* string 23 */
- || !unpack_str(&msg.sc_data) /* string 24 */
- || str_roof - next_str != (ptrdiff_t)msg.keyval.len) /* check chunk */
- {
- ugh = "message from whack contains bad string";
}
- else
+
+ if (msg.whack_crash)
+ delete_states_by_peer(&msg.whack_crash_peer);
+
+ if (msg.whack_connection)
+ add_connection(&msg);
+
+ if (msg.whack_ca && msg.cacert != NULL)
+ add_ca_info(&msg);
+
+ /* process "listen" before any operation that could require it */
+ if (msg.whack_listen)
+ {
+ close_peerlog(); /* close any open per-peer logs */
+ plog("listening for IKE messages");
+ listening = TRUE;
+ daily_log_reset();
+ reset_adns_restart_count();
+ set_myFQDN();
+ find_ifaces();
+ load_preshared_secrets(NULL_FD);
+ load_groups();
+ }
+ if (msg.whack_unlisten)
{
- msg.keyval.ptr = next_str; /* grab chunk */
+ plog("no longer listening for IKE messages");
+ listening = FALSE;
}
- if (ugh != NULL)
+ if (msg.whack_reread & REREAD_SECRETS)
{
- if (*ugh != '\0')
- loglog(RC_BADWHACKMESSAGE, "%s", ugh);
- whack_log_fd = NULL_FD;
- close(whackfd);
- return;
+ load_preshared_secrets(whackfd);
}
- }
- if (msg.whack_options)
- {
-#ifdef DEBUG
- if (msg.name == NULL)
- {
- /* we do a two-step so that if either old or new would
- * cause the message to print, it will be printed.
- */
- cur_debugging |= msg.debugging;
- DBG(DBG_CONTROL
- , DBG_log("base debugging = %s"
- , bitnamesof(debug_bit_names, msg.debugging)));
- cur_debugging = base_debugging = msg.debugging;
- }
- else if (!msg.whack_connection)
- {
- struct connection *c = con_by_name(msg.name, TRUE);
-
- if (c != NULL)
- {
- c->extra_debugging = msg.debugging;
- DBG(DBG_CONTROL
- , DBG_log("\"%s\" extra_debugging = %s"
- , c->name
- , bitnamesof(debug_bit_names, c->extra_debugging)));
- }
+ if (msg.whack_reread & REREAD_CACERTS)
+ {
+ load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
}
-#endif
- }
-
- if (msg.whack_myid)
- set_myid(MYID_SPECIFIED, msg.myid);
-
- /* Deleting combined with adding a connection works as replace.
- * To make this more useful, in only this combination,
- * delete will silently ignore the lack of the connection.
- */
- if (msg.whack_delete)
- {
- if (msg.whack_ca)
- find_ca_info_by_name(msg.name, TRUE);
- else
- delete_connections_by_name(msg.name, !msg.whack_connection);
- }
- if (msg.whack_deletestate)
- {
- struct state *st = state_with_serialno(msg.whack_deletestateno);
+ if (msg.whack_reread & REREAD_AACERTS)
+ {
+ load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
+ }
- if (st == NULL)
+ if (msg.whack_reread & REREAD_OCSPCERTS)
{
- loglog(RC_UNKNOWN_NAME, "no state #%lu to delete"
- , msg.whack_deletestateno);
+ load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
}
- else
+
+ if (msg.whack_reread & REREAD_ACERTS)
{
- delete_state(st);
- }
- }
-
- if (msg.whack_crash)
- delete_states_by_peer(&msg.whack_crash_peer);
-
- if (msg.whack_connection)
- add_connection(&msg);
-
- if (msg.whack_ca && msg.cacert != NULL)
- add_ca_info(&msg);
-
- /* process "listen" before any operation that could require it */
- if (msg.whack_listen)
- {
- close_peerlog(); /* close any open per-peer logs */
- plog("listening for IKE messages");
- listening = TRUE;
- daily_log_reset();
- reset_adns_restart_count();
- set_myFQDN();
- find_ifaces();
- load_preshared_secrets(NULL_FD);
- load_groups();
- }
- if (msg.whack_unlisten)
- {
- plog("no longer listening for IKE messages");
- listening = FALSE;
- }
-
- if (msg.whack_reread & REREAD_SECRETS)
- {
- load_preshared_secrets(whackfd);
- }
-
- if (msg.whack_reread & REREAD_CACERTS)
- {
- load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
- }
-
- if (msg.whack_reread & REREAD_AACERTS)
- {
- load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
- }
-
- if (msg.whack_reread & REREAD_OCSPCERTS)
- {
- load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
- }
-
- if (msg.whack_reread & REREAD_ACERTS)
- {
- load_acerts();
- }
-
- if (msg.whack_reread & REREAD_CRLS)
- {
- load_crls();
- }
-
- if (msg.whack_purgeocsp)
- {
- free_ocsp_fetch();
- free_ocsp_cache();
- }
-
- if (msg.whack_list & LIST_ALGS)
- {
- ike_alg_list();
- kernel_alg_list();
- }
+ load_acerts();
+ }
+
+ if (msg.whack_reread & REREAD_CRLS)
+ {
+ load_crls();
+ }
+
+ if (msg.whack_purgeocsp)
+ {
+ free_ocsp_fetch();
+ free_ocsp_cache();
+ }
+
if (msg.whack_list & LIST_PUBKEYS)
- {
- list_public_keys(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CERTS)
- {
- list_certs(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CACERTS)
- {
- list_authcerts("CA", AUTH_CA, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_AACERTS)
- {
- list_authcerts("AA", AUTH_AA, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_OCSPCERTS)
- {
- list_authcerts("OCSP", AUTH_OCSP, msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_ACERTS)
- {
- list_acerts(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_GROUPS)
- {
- list_groups(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CAINFOS)
- {
- list_ca_infos(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CRLS)
- {
- list_crls(msg.whack_utc, strict_crl_policy);
- list_crl_fetch_requests(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_OCSP)
- {
- list_ocsp_cache(msg.whack_utc, strict_crl_policy);
- list_ocsp_fetch_requests(msg.whack_utc);
- }
-
- if (msg.whack_list & LIST_CARDS)
- {
- scx_list(msg.whack_utc);
- }
-
- if (msg.whack_key)
- {
- /* add a public key */
- key_add_request(&msg);
- }
-
- if (msg.whack_route)
- {
- if (!listening)
- {
- whack_log(RC_DEAF, "need --listen before --route");
- }
- if (msg.name == NULL)
- {
- whack_log(RC_UNKNOWN_NAME
- , "whack --route requires a connection name");
+ {
+ list_public_keys(msg.whack_utc);
}
- else
+
+ if (msg.whack_list & LIST_CERTS)
{
- struct connection *c = con_by_name(msg.name, TRUE);
+ list_certs(msg.whack_utc);
+ }
- if (c != NULL && c->ikev1)
- {
- set_cur_connection(c);
- if (!oriented(*c))
- whack_log(RC_ORIENT
- , "we have no ipsecN interface for either end of this connection");
- else if (c->policy & POLICY_GROUP)
- route_group(c);
- else if (!trap_connection(c))
- whack_log(RC_ROUTE, "could not route");
- reset_cur_connection();
- }
+ if (msg.whack_list & LIST_CACERTS)
+ {
+ list_authcerts("CA", AUTH_CA, msg.whack_utc);
}
- }
- if (msg.whack_unroute)
- {
- if (msg.name == NULL)
+ if (msg.whack_list & LIST_AACERTS)
{
- whack_log(RC_UNKNOWN_NAME
- , "whack --unroute requires a connection name");
+ list_authcerts("AA", AUTH_AA, msg.whack_utc);
}
- else
+
+ if (msg.whack_list & LIST_OCSPCERTS)
{
- struct connection *c = con_by_name(msg.name, TRUE);
+ list_authcerts("OCSP", AUTH_OCSP, msg.whack_utc);
+ }
- if (c != NULL && c->ikev1)
- {
- struct spd_route *sr;
- int fail = 0;
+ if (msg.whack_list & LIST_ACERTS)
+ {
+ list_acerts(msg.whack_utc);
+ }
- set_cur_connection(c);
+ if (msg.whack_list & LIST_GROUPS)
+ {
+ list_groups(msg.whack_utc);
+ }
- for (sr = &c->spd; sr != NULL; sr = sr->next)
- {
- if (sr->routing >= RT_ROUTED_TUNNEL)
- fail++;
- }
- if (fail > 0)
- whack_log(RC_RTBUSY, "cannot unroute: route busy");
- else if (c->policy & POLICY_GROUP)
- unroute_group(c);
- else
- unroute_connection(c);
- reset_cur_connection();
- }
+ if (msg.whack_list & LIST_CAINFOS)
+ {
+ list_ca_infos(msg.whack_utc);
}
- }
- if (msg.whack_initiate)
- {
- if (!listening)
+ if (msg.whack_list & LIST_CRLS)
{
- whack_log(RC_DEAF, "need --listen before --initiate");
+ list_crls(msg.whack_utc, strict_crl_policy);
+ list_crl_fetch_requests(msg.whack_utc);
}
- else if (msg.name == NULL)
+
+ if (msg.whack_list & LIST_OCSP)
{
- whack_log(RC_UNKNOWN_NAME
- , "whack --initiate requires a connection name");
+ list_ocsp_cache(msg.whack_utc, strict_crl_policy);
+ list_ocsp_fetch_requests(msg.whack_utc);
}
- else
+
+ if (msg.whack_list & LIST_CARDS)
{
- initiate_connection(msg.name
- , msg.whack_async? NULL_FD : dup_any(whackfd));
+ scx_list(msg.whack_utc);
}
- }
- if (msg.whack_oppo_initiate)
- {
- if (!listening)
- whack_log(RC_DEAF, "need --listen before opportunistic initiation");
- else
- initiate_opportunistic(&msg.oppo_my_client, &msg.oppo_peer_client, 0
- , FALSE
- , msg.whack_async? NULL_FD : dup_any(whackfd));
- }
+ if (msg.whack_list & LIST_ALGS)
+ {
+ ike_alg_list();
+ kernel_alg_list();
+ }
- if (msg.whack_terminate)
- {
- if (msg.name == NULL)
+ if (msg.whack_key)
{
- whack_log(RC_UNKNOWN_NAME
- , "whack --terminate requires a connection name");
+ /* add a public key */
+ key_add_request(&msg);
}
- else
+
+ if (msg.whack_route)
{
- terminate_connection(msg.name);
+ if (!listening)
+ {
+ whack_log(RC_DEAF, "need --listen before --route");
+ }
+ if (msg.name == NULL)
+ {
+ whack_log(RC_UNKNOWN_NAME
+ , "whack --route requires a connection name");
+ }
+ else
+ {
+ struct connection *c = con_by_name(msg.name, TRUE);
+
+ if (c != NULL && c->ikev1)
+ {
+ set_cur_connection(c);
+ if (!oriented(*c))
+ whack_log(RC_ORIENT
+ , "we have no ipsecN interface for either end of this connection");
+ else if (c->policy & POLICY_GROUP)
+ route_group(c);
+ else if (!trap_connection(c))
+ whack_log(RC_ROUTE, "could not route");
+ reset_cur_connection();
+ }
+ }
}
- }
- if (msg.whack_status)
- show_status(msg.whack_statusall, msg.name);
+ if (msg.whack_unroute)
+ {
+ if (msg.name == NULL)
+ {
+ whack_log(RC_UNKNOWN_NAME
+ , "whack --unroute requires a connection name");
+ }
+ else
+ {
+ struct connection *c = con_by_name(msg.name, TRUE);
+
+ if (c != NULL && c->ikev1)
+ {
+ struct spd_route *sr;
+ int fail = 0;
+
+ set_cur_connection(c);
+
+ for (sr = &c->spd; sr != NULL; sr = sr->next)
+ {
+ if (sr->routing >= RT_ROUTED_TUNNEL)
+ fail++;
+ }
+ if (fail > 0)
+ whack_log(RC_RTBUSY, "cannot unroute: route busy");
+ else if (c->policy & POLICY_GROUP)
+ unroute_group(c);
+ else
+ unroute_connection(c);
+ reset_cur_connection();
+ }
+ }
+ }
- if (msg.whack_shutdown)
- {
- plog("shutting down");
- exit_pluto(0); /* delete lock and leave, with 0 status */
- }
+ if (msg.whack_initiate)
+ {
+ if (!listening)
+ {
+ whack_log(RC_DEAF, "need --listen before --initiate");
+ }
+ else if (msg.name == NULL)
+ {
+ whack_log(RC_UNKNOWN_NAME
+ , "whack --initiate requires a connection name");
+ }
+ else
+ {
+ initiate_connection(msg.name
+ , msg.whack_async? NULL_FD : dup_any(whackfd));
+ }
+ }
- if (msg.whack_sc_op != SC_OP_NONE)
- {
- if (pkcs11_proxy)
- scx_op_via_whack(msg.sc_data, msg.inbase, msg.outbase
- , msg.whack_sc_op, msg.keyid, whackfd);
- else
- plog("pkcs11 access to smartcard not allowed (set pkcs11proxy=yes)");
- }
+ if (msg.whack_oppo_initiate)
+ {
+ if (!listening)
+ whack_log(RC_DEAF, "need --listen before opportunistic initiation");
+ else
+ initiate_opportunistic(&msg.oppo_my_client, &msg.oppo_peer_client, 0
+ , FALSE
+ , msg.whack_async? NULL_FD : dup_any(whackfd));
+ }
+
+ if (msg.whack_terminate)
+ {
+ if (msg.name == NULL)
+ {
+ whack_log(RC_UNKNOWN_NAME
+ , "whack --terminate requires a connection name");
+ }
+ else
+ {
+ terminate_connection(msg.name);
+ }
+ }
+
+ if (msg.whack_status)
+ show_status(msg.whack_statusall, msg.name);
+
+ if (msg.whack_shutdown)
+ {
+ plog("shutting down");
+ exit_pluto(0); /* delete lock and leave, with 0 status */
+ }
- whack_log_fd = NULL_FD;
- close(whackfd);
+ if (msg.whack_sc_op != SC_OP_NONE)
+ {
+ if (pkcs11_proxy)
+ scx_op_via_whack(msg.sc_data, msg.inbase, msg.outbase
+ , msg.whack_sc_op, msg.keyid, whackfd);
+ else
+ plog("pkcs11 access to smartcard not allowed (set pkcs11proxy=yes)");
+ }
+
+ whack_log_fd = NULL_FD;
+ close(whackfd);
}
/*
diff --git a/src/pluto/rcv_whack.h b/src/pluto/rcv_whack.h
index e0582202f..66edaaf80 100644
--- a/src/pluto/rcv_whack.h
+++ b/src/pluto/rcv_whack.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: rcv_whack.h 3252 2007-10-06 21:24:50Z andreas $
*/
extern void whack_handle(int kernelfd);
diff --git a/src/pluto/rnd.c b/src/pluto/rnd.c
deleted file mode 100644
index 7941034d8..000000000
--- a/src/pluto/rnd.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* randomness machinery
- * Copyright (C) 1997 Angelos D. Keromytis.
- * Copyright (C) 1998-2001 D. Hugh Redelmeier.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * RCSID $Id: rnd.c 3252 2007-10-06 21:24:50Z andreas $
- */
-
-/* A true random number generator (we hope)
- *
- * Under LINUX ("linux" predefined), use /dev/urandom.
- * Under OpenBSD ("__OpenBSD__" predefined), use arc4random().
- * Otherwise use our own random number generator based on clock skew.
- * I (ADK) first heard of the idea from John Ioannidis, who heard it
- * from Matt Blaze and/or Jack Lacy.
- * ??? Why is mixing need for linux but not OpenBSD?
- */
-
-/* Pluto's uses of randomness:
- *
- * - Setting up the "secret_of_the_day". This changes every hour! 20
- * bytes a shot. It is used in building responder cookies.
- *
- * - generating initiator cookies (8 bytes, once per Phase 1 initiation).
- *
- * - 32 bytes per DH local secret. Once per Main Mode exchange and once
- * per Quick Mode Exchange with PFS. (Size is our choice, with
- * tradeoffs.)
- *
- * - 16 bytes per nonce we generate. Once per Main Mode exchange and
- * once per Quick Mode exchange. (Again, we choose the size.)
- *
- * - 4 bytes per SPI number that we generate. We choose the SPIs for all
- * inbound SPIs, one to three per IPSEC SA (one for AH (rare, probably)
- * one for ESP (almost always), and one for tunnel (very common)).
- * I don't actually know how the kernel would generate these numbers --
- * currently Pluto generates them; this isn't the way things will be
- * done in the future.
- *
- * - 4 bytes per Message ID we need to generate. One per Quick Mode
- * exchange. Eventually, one per informational exchange.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-#include <freeswan.h>
-
-#include "sha1.h"
-#include "constants.h"
-#include "defs.h"
-#include "rnd.h"
-#include "log.h"
-#include "timer.h"
-
-#ifdef linux
-# define USE_DEV_RANDOM 1
-# define RANDOM_PATH DEV_URANDOM
-#else
-# ifdef __OpenBSD__
-# define USE_ARC4RANDOM
-# else
-# define USE_CLOCK_SLEW
-# endif
-#endif
-
-#ifdef USE_ARC4RANDOM
-
-#define get_rnd_byte() (arc4random() % 256)
-
-#else /**** start of large #else ****/
-
-#ifdef USE_DEV_RANDOM
-static int random_fd = NULL_FD;
-#endif
-
-#define RANDOM_POOL_SIZE SHA1_DIGEST_SIZE
-static u_char random_pool[RANDOM_POOL_SIZE];
-
-#ifdef USE_DEV_RANDOM
-
-/* Generate (what we hope is) a true random byte using /dev/urandom */
-static u_char
-generate_rnd_byte(void)
-{
- u_char c;
-
- if (read(random_fd, &c, sizeof(c)) == -1)
- exit_log_errno((e, "read() failed in get_rnd_byte()"));
-
- return c;
-}
-
-#else /* !USE_DEV_RANDOM */
-
-/* Generate (what we hope is) a true random byte using the clock skew trick.
- * Note: this code is not maintained! In particular, LINUX signal(2)
- * semantics changed with glibc2 (and not for the better). It isn't clear
- * that this code will work. We keep the code because someday it might
- * come in handy.
- */
-# error "This code is not maintained. Please define USE_DEV_RANDOM."
-
-static volatile sig_atomic_t i, j, k;
-
-/* timer signal handler */
-static void
-rnd_handler(int ignore_me UNUSED)
-{
- k <<= 1; /* Shift left by 1 */
- j++;
- k |= (i & 0x1); /* Get lsbit of counter */
-
- if (j != 8)
- signal(SIGVTALRM, rnd_handler);
-}
-
-static u_char
-generate_rnd_byte(void)
-{
- struct itimerval tmval, ntmval;
-
-# ifdef NEVER /* ??? */
-# ifdef linux
- int mask = siggetmask();
-
- mask |= SIGVTALRM;
- sigsetmask(mask);
-# endif
-# endif
-
- i = 0;
- j = 0;
-
- ntmval.it_interval.tv_sec = 0;
- ntmval.it_interval.tv_usec = 1;
- ntmval.it_value.tv_sec = 0;
- ntmval.it_value.tv_usec = 1;
- signal(SIGVTALRM, rnd_handler);
- setitimer(ITIMER_VIRTUAL, &ntmval, &tmval);
-
- while (j != 8)
- i++;
-
- setitimer(ITIMER_VIRTUAL, &tmval, &ntmval);
- signal(SIGVTALRM, SIG_IGN);
-
-# ifdef NEVER /* ??? */
-# ifdef linux
- mask ^= SIGVTALRM;
- sigsetmask(mask);
-# endif
-# endif
-
- return k;
-}
-
-#endif /* !USE_DEV_RANDOM */
-
-static void
-mix_pool(void)
-{
- SHA1_CTX ctx;
-
- SHA1Init(&ctx);
- SHA1Update(&ctx, random_pool, RANDOM_POOL_SIZE);
- SHA1Final(random_pool, &ctx);
-}
-
-/*
- * Get a single random byte.
- */
-static u_char
-get_rnd_byte(void)
-{
- random_pool[RANDOM_POOL_SIZE - 1] = generate_rnd_byte();
- random_pool[0] = generate_rnd_byte();
- mix_pool();
- return random_pool[0];
-}
-
-#endif /* !USE_ARC4RANDOM */ /**** end of large #else ****/
-
-void
-get_rnd_bytes(u_char *buffer, int length)
-{
- int i;
-
- for (i = 0; i < length; i++)
- buffer[i] = get_rnd_byte();
-}
-
-/*
- * Initialize the random pool.
- */
-void
-init_rnd_pool(void)
-{
-#ifndef USE_ARC4RANDOM
-# ifdef USE_DEV_RANDOM
- DBG(DBG_KLIPS, DBG_log("opening %s", RANDOM_PATH));
- random_fd = open(RANDOM_PATH, O_RDONLY);
- if (random_fd == -1)
- exit_log_errno((e, "open of %s failed in init_rnd_pool()", RANDOM_PATH));
- fcntl(random_fd, F_SETFD, FD_CLOEXEC);
-# endif
-
- get_rnd_bytes(random_pool, RANDOM_POOL_SIZE);
- mix_pool();
-#endif /* !USE_ARC4RANDOM */
-
- /* start of rand(3) on the right foot */
- {
- unsigned int seed;
-
- get_rnd_bytes((void *)&seed, sizeof(seed));
- srand(seed);
- }
-}
-
-u_char secret_of_the_day[SHA1_DIGEST_SIZE];
-
-#ifndef NO_PLUTO
-
-void
-init_secret(void)
-{
- /*
- * Generate the secret value for responder cookies, and
- * schedule an event for refresh.
- */
- get_rnd_bytes(secret_of_the_day, sizeof(secret_of_the_day));
- event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
-}
-
-#endif /* NO_PLUTO */
diff --git a/src/pluto/server.c b/src/pluto/server.c
index b0e158503..21f65f4f8 100644
--- a/src/pluto/server.c
+++ b/src/pluto/server.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: server.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#ifdef SOLARIS
-# include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
+# include <sys/sockio.h> /* for Solaris 2.6: defines SIOCGIFCONF */
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -38,7 +36,7 @@
#include <net/if.h>
#include <sys/ioctl.h>
#include <resolv.h>
-#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
+#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <freeswan.h>
@@ -55,9 +53,9 @@
#include "demux.h" /* needs packet.h */
#include "rcv_whack.h"
#include "keys.h"
-#include "adns.h" /* needs <resolv.h> */
-#include "dnskey.h" /* needs keys.h and adns.h */
-#include "whack.h" /* for RC_LOG_SERIOUS */
+#include "adns.h" /* needs <resolv.h> */
+#include "dnskey.h" /* needs keys.h and adns.h */
+#include "whack.h" /* for RC_LOG_SERIOUS */
#include <pfkeyv2.h>
#include <pfkey.h>
@@ -68,10 +66,10 @@
* Server main loop and socket initialization routines.
*/
-static const int on = TRUE; /* by-reference parameter; constant, we hope */
+static const int on = TRUE; /* by-reference parameter; constant, we hope */
/* control (whack) socket */
-int ctl_fd = NULL_FD; /* file descriptor of control (whack) socket */
+int ctl_fd = NULL_FD; /* file descriptor of control (whack) socket */
struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
/* info (showpolicy) socket */
@@ -86,121 +84,121 @@ struct sockaddr_un info_addr= { AF_UNIX, DEFAULT_CTLBASE INFO_SUFFIX };
err_t
init_ctl_socket(void)
{
- err_t failed = NULL;
-
- delete_ctl_socket(); /* preventative medicine */
- ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ctl_fd == -1)
- failed = "create";
- else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
- failed = "fcntl FD+CLOEXEC";
- else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
- failed = "setsockopt";
- else
- {
- /* to keep control socket secure, use umask */
- mode_t ou = umask(~S_IRWXU);
-
- if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
- , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- failed = "bind";
- umask(ou);
- }
-
- /* 5 is a haphazardly chosen limit for the backlog.
- * Rumour has it that this is the max on BSD systems.
- */
- if (failed == NULL && listen(ctl_fd, 5) < 0)
- failed = "listen() on";
-
- return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
- , failed, errno, strerror(errno));
+ err_t failed = NULL;
+
+ delete_ctl_socket(); /* preventative medicine */
+ ctl_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ctl_fd == -1)
+ failed = "create";
+ else if (fcntl(ctl_fd, F_SETFD, FD_CLOEXEC) == -1)
+ failed = "fcntl FD+CLOEXEC";
+ else if (setsockopt(ctl_fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
+ failed = "setsockopt";
+ else
+ {
+ /* to keep control socket secure, use umask */
+ mode_t ou = umask(~S_IRWXU);
+
+ if (bind(ctl_fd, (struct sockaddr *)&ctl_addr
+ , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
+ failed = "bind";
+ umask(ou);
+ }
+
+ /* 5 is a haphazardly chosen limit for the backlog.
+ * Rumour has it that this is the max on BSD systems.
+ */
+ if (failed == NULL && listen(ctl_fd, 5) < 0)
+ failed = "listen() on";
+
+ return failed == NULL? NULL : builddiag("could not %s control socket: %d %s"
+ , failed, errno, strerror(errno));
}
void
delete_ctl_socket(void)
{
- /* Is noting failure useful? Not when used as preventative medicine. */
- unlink(ctl_addr.sun_path);
+ /* Is noting failure useful? Not when used as preventative medicine. */
+ unlink(ctl_addr.sun_path);
}
-bool listening = FALSE; /* should we pay attention to IKE messages? */
+bool listening = FALSE; /* should we pay attention to IKE messages? */
-struct iface *interfaces = NULL; /* public interfaces */
+struct iface *interfaces = NULL; /* public interfaces */
/* Initialize the interface sockets. */
static void
mark_ifaces_dead(void)
{
- struct iface *p;
+ struct iface *p;
- for (p = interfaces; p != NULL; p = p->next)
- p->change = IFN_DELETE;
+ for (p = interfaces; p != NULL; p = p->next)
+ p->change = IFN_DELETE;
}
static void
free_dead_ifaces(void)
{
- struct iface *p;
- bool some_dead = FALSE
- , some_new = FALSE;
+ struct iface *p;
+ bool some_dead = FALSE
+ , some_new = FALSE;
- for (p = interfaces; p != NULL; p = p->next)
- {
- if (p->change == IFN_DELETE)
- {
- plog("shutting down interface %s/%s %s"
- , p->vname, p->rname, ip_str(&p->addr));
- some_dead = TRUE;
- }
- else if (p->change == IFN_ADD)
+ for (p = interfaces; p != NULL; p = p->next)
{
- some_new = TRUE;
+ if (p->change == IFN_DELETE)
+ {
+ plog("shutting down interface %s/%s %s"
+ , p->vname, p->rname, ip_str(&p->addr));
+ some_dead = TRUE;
+ }
+ else if (p->change == IFN_ADD)
+ {
+ some_new = TRUE;
+ }
}
- }
-
- if (some_dead)
- {
- struct iface **pp;
- release_dead_interfaces();
- for (pp = &interfaces; (p = *pp) != NULL; )
+ if (some_dead)
{
- if (p->change == IFN_DELETE)
- {
- *pp = p->next; /* advance *pp */
- pfree(p->vname);
- pfree(p->rname);
- close(p->fd);
- pfree(p);
- }
- else
- {
- pp = &p->next; /* advance pp */
- }
+ struct iface **pp;
+
+ release_dead_interfaces();
+ for (pp = &interfaces; (p = *pp) != NULL; )
+ {
+ if (p->change == IFN_DELETE)
+ {
+ *pp = p->next; /* advance *pp */
+ free(p->vname);
+ free(p->rname);
+ close(p->fd);
+ free(p);
+ }
+ else
+ {
+ pp = &p->next; /* advance pp */
+ }
+ }
}
- }
-
- /* this must be done after the release_dead_interfaces
- * in case some to the newly unoriented connections can
- * become oriented here.
- */
- if (some_dead || some_new)
- check_orientations();
+
+ /* this must be done after the release_dead_interfaces
+ * in case some to the newly unoriented connections can
+ * become oriented here.
+ */
+ if (some_dead || some_new)
+ check_orientations();
}
void
free_ifaces(void)
{
- mark_ifaces_dead();
- free_dead_ifaces();
+ mark_ifaces_dead();
+ free_dead_ifaces();
}
struct raw_iface {
- ip_address addr;
- char name[IFNAMSIZ + 20]; /* what would be a safe size? */
- struct raw_iface *next;
+ ip_address addr;
+ char name[IFNAMSIZ + 20]; /* what would be a safe size? */
+ struct raw_iface *next;
};
/* Called to handle --interface <ifname>
@@ -212,15 +210,15 @@ static int pluto_ifn_roof = 0;
bool
use_interface(const char *rifn)
{
- if (pluto_ifn_roof >= (int)elemsof(pluto_ifn))
- {
- return FALSE;
- }
- else
- {
- pluto_ifn[pluto_ifn_roof++] = rifn;
- return TRUE;
- }
+ if (pluto_ifn_roof >= (int)countof(pluto_ifn))
+ {
+ return FALSE;
+ }
+ else
+ {
+ pluto_ifn[pluto_ifn_roof++] = rifn;
+ return TRUE;
+ }
}
#ifndef IPSECDEVPREFIX
@@ -230,538 +228,542 @@ use_interface(const char *rifn)
static struct raw_iface *
find_raw_ifaces4(void)
{
- int j; /* index into buf */
- struct ifconf ifconf;
- struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
- struct raw_iface *rifaces = NULL;
- int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
-
- /* get list of interfaces with assigned IPv4 addresses from system */
-
- if (master_sock == -1)
- exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
-
- if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
-
- /* bind the socket */
- {
- ip_address any;
-
- happy(anyaddr(AF_INET, &any));
- setportof(htons(pluto_port), &any);
- if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
- exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
- }
-
- /* Get local interfaces. See netdevice(7). */
- ifconf.ifc_len = sizeof(buf);
- ifconf.ifc_buf = (void *) buf;
- zero(buf);
-
- if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
- exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
- /* Add an entry to rifaces for each interesting interface. */
- for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
- {
- struct raw_iface ri;
- const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
- struct ifreq auxinfo;
-
- /* ignore all but AF_INET interfaces */
- if (rs->sin_family != AF_INET)
- continue; /* not interesting */
-
- /* build a NUL-terminated copy of the rname field */
- memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
- ri.name[IFNAMSIZ] = '\0';
-
- /* ignore if our interface names were specified, and this isn't one */
- if (pluto_ifn_roof != 0)
+ int j; /* index into buf */
+ struct ifconf ifconf;
+ struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
+ struct raw_iface *rifaces = NULL;
+ int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
+
+ /* get list of interfaces with assigned IPv4 addresses from system */
+
+ if (master_sock == -1)
+ exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));
+
+ if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR
+ , (const void *)&on, sizeof(on)) < 0)
+ exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));
+
+ /* bind the socket */
{
- int i;
+ ip_address any;
- for (i = 0; i != pluto_ifn_roof; i++)
- if (streq(ri.name, pluto_ifn[i]))
- break;
- if (i == pluto_ifn_roof)
- continue; /* not found -- skip */
+ happy(anyaddr(AF_INET, &any));
+ setportof(htons(pluto_port), &any);
+ if (bind(master_sock, sockaddrof(&any), sockaddrlenof(&any)) < 0)
+ exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
}
- /* Find out stuff about this interface. See netdevice(7). */
- zero(&auxinfo); /* paranoia */
- memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
- if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
- exit_log_errno((e
- , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
- , ri.name));
- if (!(auxinfo.ifr_flags & IFF_UP))
- continue; /* ignore an interface that isn't UP */
+ /* Get local interfaces. See netdevice(7). */
+ ifconf.ifc_len = sizeof(buf);
+ ifconf.ifc_buf = (void *) buf;
+ zero(buf);
- /* ignore unconfigured interfaces */
- if (rs->sin_addr.s_addr == 0)
- continue;
+ if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
+ exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
- happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
- , AF_INET, &ri.addr));
+ /* Add an entry to rifaces for each interesting interface. */
+ for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
+ {
+ struct raw_iface ri;
+ const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
+ struct ifreq auxinfo;
- DBG(DBG_CONTROL, DBG_log("found %s with address %s"
- , ri.name, ip_str(&ri.addr)));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
+ /* ignore all but AF_INET interfaces */
+ if (rs->sin_family != AF_INET)
+ continue; /* not interesting */
- close(master_sock);
+ /* build a NUL-terminated copy of the rname field */
+ memcpy(ri.name, buf[j].ifr_name, IFNAMSIZ);
+ ri.name[IFNAMSIZ] = '\0';
- return rifaces;
+ /* ignore if our interface names were specified, and this isn't one */
+ if (pluto_ifn_roof != 0)
+ {
+ int i;
+
+ for (i = 0; i != pluto_ifn_roof; i++)
+ if (streq(ri.name, pluto_ifn[i]))
+ break;
+ if (i == pluto_ifn_roof)
+ continue; /* not found -- skip */
+ }
+
+ /* Find out stuff about this interface. See netdevice(7). */
+ zero(&auxinfo); /* paranoia */
+ memcpy(auxinfo.ifr_name, buf[j].ifr_name, IFNAMSIZ);
+ if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1)
+ exit_log_errno((e
+ , "ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()"
+ , ri.name));
+ if (!(auxinfo.ifr_flags & IFF_UP))
+ continue; /* ignore an interface that isn't UP */
+
+ /* ignore unconfigured interfaces */
+ if (rs->sin_addr.s_addr == 0)
+ continue;
+
+ happy(initaddr((const void *)&rs->sin_addr, sizeof(struct in_addr)
+ , AF_INET, &ri.addr));
+
+ DBG(DBG_CONTROL, DBG_log("found %s with address %s"
+ , ri.name, ip_str(&ri.addr)));
+ ri.next = rifaces;
+ rifaces = clone_thing(ri);
+ }
+
+ close(master_sock);
+
+ return rifaces;
}
static struct raw_iface *
find_raw_ifaces6(void)
{
- /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
- *
- * Documentation of format?
- * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
- * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
- *
- * Sample from Gerhard's laptop:
- * 00000000000000000000000000000001 01 80 10 80 lo
- * 30490009000000000000000000010002 02 40 00 80 ipsec0
- * 30490009000000000000000000010002 07 40 00 80 eth0
- * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
- * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
- *
- * Each line contains:
- * - IPv6 address: 16 bytes, in hex, no punctuation
- * - ifindex: 1 byte, in hex
- * - prefix_len: 1 byte, in hex
- * - scope (e.g. global, link local): 1 byte, in hex
- * - flags: 1 byte, in hex
- * - device name: string, followed by '\n'
- */
- struct raw_iface *rifaces = NULL;
- static const char proc_name[] = "/proc/net/if_inet6";
- FILE *proc_sock = fopen(proc_name, "r");
-
- if (proc_sock == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
- }
- else
- {
- for (;;)
+ /* Get list of interfaces with IPv6 addresses from system from /proc/net/if_inet6).
+ *
+ * Documentation of format?
+ * RTFS: linux-2.2.16/net/ipv6/addrconf.c:iface_proc_info()
+ * linux-2.4.9-13/net/ipv6/addrconf.c:iface_proc_info()
+ *
+ * Sample from Gerhard's laptop:
+ * 00000000000000000000000000000001 01 80 10 80 lo
+ * 30490009000000000000000000010002 02 40 00 80 ipsec0
+ * 30490009000000000000000000010002 07 40 00 80 eth0
+ * fe80000000000000025004fffefd5484 02 0a 20 80 ipsec0
+ * fe80000000000000025004fffefd5484 07 0a 20 80 eth0
+ *
+ * Each line contains:
+ * - IPv6 address: 16 bytes, in hex, no punctuation
+ * - ifindex: 1 byte, in hex
+ * - prefix_len: 1 byte, in hex
+ * - scope (e.g. global, link local): 1 byte, in hex
+ * - flags: 1 byte, in hex
+ * - device name: string, followed by '\n'
+ */
+ struct raw_iface *rifaces = NULL;
+ static const char proc_name[] = "/proc/net/if_inet6";
+ FILE *proc_sock = fopen(proc_name, "r");
+
+ if (proc_sock == NULL)
{
- struct raw_iface ri;
- unsigned short xb[8]; /* IPv6 address as 8 16-bit chunks */
- char sb[8*5]; /* IPv6 address as string-with-colons */
- unsigned int if_idx; /* proc field, not used */
- unsigned int plen; /* proc field, not used */
- unsigned int scope; /* proc field, used to exclude link-local */
- unsigned int dad_status; /* proc field, not used */
- /* ??? I hate and distrust scanf -- DHR */
- int r = fscanf(proc_sock
- , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
- " %02x %02x %02x %02x %20s\n"
- , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
- , &if_idx, &plen, &scope, &dad_status, ri.name);
-
- /* ??? we should diagnose any problems */
- if (r != 13)
- break;
-
- /* ignore addresses with link local scope.
- * From linux-2.4.9-13/include/net/ipv6.h:
- * IPV6_ADDR_LINKLOCAL 0x0020U
- * IPV6_ADDR_SCOPE_MASK 0x00f0U
- */
- if ((scope & 0x00f0U) == 0x0020U)
- continue;
-
- snprintf(sb, sizeof(sb)
- , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
- , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
-
- happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
-
- if (!isunspecaddr(&ri.addr))
- {
- DBG(DBG_CONTROL
- , DBG_log("found %s with address %s"
- , ri.name, sb));
- ri.next = rifaces;
- rifaces = clone_thing(ri, "struct raw_iface");
- }
+ DBG(DBG_CONTROL, DBG_log("could not open %s", proc_name));
+ }
+ else
+ {
+ for (;;)
+ {
+ struct raw_iface ri;
+ unsigned short xb[8]; /* IPv6 address as 8 16-bit chunks */
+ char sb[8*5]; /* IPv6 address as string-with-colons */
+ unsigned int if_idx; /* proc field, not used */
+ unsigned int plen; /* proc field, not used */
+ unsigned int scope; /* proc field, used to exclude link-local */
+ unsigned int dad_status; /* proc field, not used */
+ /* ??? I hate and distrust scanf -- DHR */
+ int r = fscanf(proc_sock
+ , "%4hx%4hx%4hx%4hx%4hx%4hx%4hx%4hx"
+ " %02x %02x %02x %02x %20s\n"
+ , xb+0, xb+1, xb+2, xb+3, xb+4, xb+5, xb+6, xb+7
+ , &if_idx, &plen, &scope, &dad_status, ri.name);
+
+ /* ??? we should diagnose any problems */
+ if (r != 13)
+ break;
+
+ /* ignore addresses with link local scope.
+ * From linux-2.4.9-13/include/net/ipv6.h:
+ * IPV6_ADDR_LINKLOCAL 0x0020U
+ * IPV6_ADDR_SCOPE_MASK 0x00f0U
+ */
+ if ((scope & 0x00f0U) == 0x0020U)
+ continue;
+
+ snprintf(sb, sizeof(sb)
+ , "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
+ , xb[0], xb[1], xb[2], xb[3], xb[4], xb[5], xb[6], xb[7]);
+
+ happy(ttoaddr(sb, 0, AF_INET6, &ri.addr));
+
+ if (!isunspecaddr(&ri.addr))
+ {
+ DBG(DBG_CONTROL
+ , DBG_log("found %s with address %s"
+ , ri.name, sb));
+ ri.next = rifaces;
+ rifaces = clone_thing(ri);
+ }
+ }
+ fclose(proc_sock);
}
- fclose(proc_sock);
- }
- return rifaces;
+ return rifaces;
}
#if 1
static int
create_socket(struct raw_iface *ifp, const char *v_name, int port)
{
- int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
- int fcntl_flags;
+ int fd = socket(addrtypeof(&ifp->addr), SOCK_DGRAM, IPPROTO_UDP);
+ int fcntl_flags;
- if (fd < 0)
- {
- log_errno((e, "socket() in process_raw_ifaces()"));
- return -1;
- }
+ if (fd < 0)
+ {
+ log_errno((e, "socket() in process_raw_ifaces()"));
+ return -1;
+ }
#if 1
- /* Set socket Nonblocking */
- if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
- if (!(fcntl_flags & O_NONBLOCK)) {
- fcntl_flags |= O_NONBLOCK;
- fcntl(fd, F_SETFL, fcntl_flags);
+ /* Set socket Nonblocking */
+ if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
+ if (!(fcntl_flags & O_NONBLOCK)) {
+ fcntl_flags |= O_NONBLOCK;
+ fcntl(fd, F_SETFL, fcntl_flags);
+ }
}
- }
-#endif
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- {
- log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-
- /* To improve error reporting. See ip(7). */
-#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
- if (setsockopt(fd, SOL_IP, IP_RECVERR
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
-#endif
-
- /* With IPv6, there is no fragmentation after
- * it leaves our interface. PMTU discovery
- * is mandatory but doesn't work well with IKE (why?).
- * So we must set the IPV6_USE_MIN_MTU option.
- * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
- */
-#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
- if (addrtypeof(&ifp->addr) == AF_INET6
- && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
- , (const void *)&on, sizeof(on)) < 0)
- {
- log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
- close(fd);
- return -1;
- }
#endif
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- struct sadb_x_policy policy;
- int level, opt;
-
- policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- policy.sadb_x_policy_reserved = 0;
- policy.sadb_x_policy_id = 0;
- policy.sadb_x_policy_reserved2 = 0;
-
- if (addrtypeof(&ifp->addr) == AF_INET6)
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
{
- level = IPPROTO_IPV6;
- opt = IPV6_IPSEC_POLICY;
+ log_errno((e, "fcntl(,, FD_CLOEXEC) in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
- else
+
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR
+ , (const void *)&on, sizeof(on)) < 0)
{
- level = IPPROTO_IP;
- opt = IP_IPSEC_POLICY;
+ log_errno((e, "setsockopt SO_REUSEADDR in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
+ /* To improve error reporting. See ip(7). */
+#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)
+ if (setsockopt(fd, SOL_IP, IP_RECVERR
+ , (const void *)&on, sizeof(on)) < 0)
{
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
+ log_errno((e, "setsockopt IP_RECVERR in process_raw_ifaces()"));
+ close(fd);
+ return -1;
}
+#endif
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+ /* With IPv6, there is no fragmentation after
+ * it leaves our interface. PMTU discovery
+ * is mandatory but doesn't work well with IKE (why?).
+ * So we must set the IPV6_USE_MIN_MTU option.
+ * See draft-ietf-ipngwg-rfc2292bis-01.txt 11.1
+ */
+#ifdef IPV6_USE_MIN_MTU /* YUCK: not always defined */
+ if (addrtypeof(&ifp->addr) == AF_INET6
+ && setsockopt(fd, SOL_SOCKET, IPV6_USE_MIN_MTU
+ , (const void *)&on, sizeof(on)) < 0)
+ {
+ log_errno((e, "setsockopt IPV6_USE_MIN_MTU in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
+#endif
- if (setsockopt(fd, level, opt
- , &policy, sizeof(policy)) < 0)
+#if defined(linux) && defined(KERNEL26_SUPPORT)
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
{
- log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
- close(fd);
- return -1;
+ struct sadb_x_policy policy;
+ int level, opt;
+
+ policy.sadb_x_policy_len = sizeof(policy) / IPSEC_PFKEYv2_ALIGN;
+ policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
+ policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+ policy.sadb_x_policy_reserved = 0;
+ policy.sadb_x_policy_id = 0;
+ policy.sadb_x_policy_reserved2 = 0;
+
+ if (addrtypeof(&ifp->addr) == AF_INET6)
+ {
+ level = IPPROTO_IPV6;
+ opt = IPV6_IPSEC_POLICY;
+ }
+ else
+ {
+ level = IPPROTO_IP;
+ opt = IP_IPSEC_POLICY;
+ }
+
+ if (setsockopt(fd, level, opt
+ , &policy, sizeof(policy)) < 0)
+ {
+ log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
+
+ policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+
+ if (setsockopt(fd, level, opt
+ , &policy, sizeof(policy)) < 0)
+ {
+ log_errno((e, "setsockopt IPSEC_POLICY in process_raw_ifaces()"));
+ close(fd);
+ return -1;
+ }
}
- }
#endif
- setportof(htons(port), &ifp->addr);
- if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
- {
- log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
- , ifp->name, v_name
- , ip_str(&ifp->addr), (unsigned) port));
- close(fd);
- return -1;
- }
- setportof(htons(pluto_port), &ifp->addr);
- return fd;
+ setportof(htons(port), &ifp->addr);
+ if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
+ {
+ log_errno((e, "bind() for %s/%s %s:%u in process_raw_ifaces()"
+ , ifp->name, v_name
+ , ip_str(&ifp->addr), (unsigned) port));
+ close(fd);
+ return -1;
+ }
+ setportof(htons(pluto_port), &ifp->addr);
+ return fd;
}
#endif
static void
process_raw_ifaces(struct raw_iface *rifaces)
{
- struct raw_iface *ifp;
-
- /* Find all virtual/real interface pairs.
- * For each real interface...
- */
- for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
- {
- struct raw_iface *v = NULL; /* matching ipsecX interface */
- struct raw_iface fake_v;
- bool after = FALSE; /* has vfp passed ifp on the list? */
- bool bad = FALSE;
- struct raw_iface *vfp;
-
- /* ignore if virtual (ipsec*) interface */
- if (strncmp(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
- continue;
-
- for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
+ struct raw_iface *ifp;
+
+ /* Find all virtual/real interface pairs.
+ * For each real interface...
+ */
+ for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
{
- if (vfp == ifp)
- {
- after = TRUE;
- }
- else if (sameaddr(&ifp->addr, &vfp->addr))
- {
- /* Different entries with matching IP addresses.
- * Many interesting cases.
- */
- if (strncmp(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
+ struct raw_iface *v = NULL; /* matching ipsecX interface */
+ struct raw_iface fake_v;
+ bool after = FALSE; /* has vfp passed ifp on the list? */
+ bool bad = FALSE;
+ struct raw_iface *vfp;
+
+ /* ignore if virtual (ipsec*) interface */
+ if (strneq(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
{
- if (v != NULL && !streq(v->name, vfp->name))
- {
- loglog(RC_LOG_SERIOUS
- , "ipsec interfaces %s and %s share same address %s"
- , v->name, vfp->name, ip_str(&ifp->addr));
- bad = TRUE;
- }
- else
- {
- v = vfp; /* current winner */
- }
+ continue;
}
- else
+
+ for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
{
- /* ugh: a second real interface with the same IP address
- * "after" allows us to avoid double reporting.
- */
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- if (after)
+ if (vfp == ifp)
{
- bad = TRUE;
- break;
+ after = TRUE;
}
- continue;
- }
+ else if (sameaddr(&ifp->addr, &vfp->addr))
+ {
+ /* Different entries with matching IP addresses.
+ * Many interesting cases.
+ */
+ if (strneq(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
+ {
+ if (v != NULL && !streq(v->name, vfp->name))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "ipsec interfaces %s and %s share same address %s"
+ , v->name, vfp->name, ip_str(&ifp->addr));
+ bad = TRUE;
+ }
+ else
+ {
+ v = vfp; /* current winner */
+ }
+ }
+ else
+ {
+ /* ugh: a second real interface with the same IP address
+ * "after" allows us to avoid double reporting.
+ */
+#if defined(linux) && defined(KERNEL26_SUPPORT)
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
+ {
+ if (after)
+ {
+ bad = TRUE;
+ break;
+ }
+ continue;
+ }
#endif
- if (after)
- {
- loglog(RC_LOG_SERIOUS
- , "IP interfaces %s and %s share address %s!"
- , ifp->name, vfp->name, ip_str(&ifp->addr));
- }
- bad = TRUE;
+ if (after)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "IP interfaces %s and %s share address %s!"
+ , ifp->name, vfp->name, ip_str(&ifp->addr));
+ }
+ bad = TRUE;
+ }
+ }
}
- }
- }
- if (bad)
- continue;
+ if (bad)
+ continue;
#if defined(linux) && defined(KERNEL26_SUPPORT)
- if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
- {
- v = ifp;
- goto add_entry;
- }
+ if (!no_klips && kernel_ops->type == KERNEL_TYPE_LINUX)
+ {
+ v = ifp;
+ goto add_entry;
+ }
#endif
- /* what if we didn't find a virtual interface? */
- if (v == NULL)
- {
- if (no_klips)
- {
- /* kludge for testing: invent a virtual device */
- static const char fvp[] = "virtual";
- fake_v = *ifp;
- passert(sizeof(fake_v.name) > sizeof(fvp));
- strcpy(fake_v.name, fvp);
- addrtot(&ifp->addr, 0, fake_v.name + sizeof(fvp) - 1
- , sizeof(fake_v.name) - (sizeof(fvp) - 1));
- v = &fake_v;
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
- , ifp->name, ip_str(&ifp->addr)));
- continue;
- }
- }
+ /* what if we didn't find a virtual interface? */
+ if (v == NULL)
+ {
+ if (no_klips)
+ {
+ /* kludge for testing: invent a virtual device */
+ static const char fvp[] = "virtual";
+ fake_v = *ifp;
+ passert(sizeof(fake_v.name) > sizeof(fvp));
+ strcpy(fake_v.name, fvp);
+ addrtot(&ifp->addr, 0, fake_v.name + sizeof(fvp) - 1
+ , sizeof(fake_v.name) - (sizeof(fvp) - 1));
+ v = &fake_v;
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
+ , ifp->name, ip_str(&ifp->addr)));
+ continue;
+ }
+ }
- /* We've got all we need; see if this is a new thing:
- * search old interfaces list.
- */
+ /* We've got all we need; see if this is a new thing:
+ * search old interfaces list.
+ */
#if defined(linux) && defined(KERNEL26_SUPPORT)
add_entry:
#endif
- {
- struct iface **p = &interfaces;
-
- for (;;)
- {
- struct iface *q = *p;
-
- /* search is over if at end of list */
- if (q == NULL)
{
- /* matches nothing -- create a new entry */
- int fd = create_socket(ifp, v->name, pluto_port);
-
- if (fd < 0)
- break;
-
- if (nat_traversal_support_non_ike
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
- }
-
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- interfaces = q;
- plog("adding interface %s/%s %s:%d"
- , q->vname, q->rname, ip_str(&q->addr), pluto_port);
-
- if (nat_traversal_support_port_floating
- && addrtypeof(&ifp->addr) == AF_INET)
- {
- fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
- if (fd < 0)
- break;
- nat_traversal_espinudp_socket(fd,
- ESPINUDP_WITH_NON_ESP);
- q = alloc_thing(struct iface, "struct iface");
- q->rname = clone_str(ifp->name, "real device name");
- q->vname = clone_str(v->name, "virtual device name");
- q->addr = ifp->addr;
- setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
- q->fd = fd;
- q->next = interfaces;
- q->change = IFN_ADD;
- q->ike_float = TRUE;
- interfaces = q;
- plog("adding interface %s/%s %s:%d",
- q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
- }
- break;
- }
+ struct iface **p = &interfaces;
- /* search over if matching old entry found */
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr))
- {
- /* matches -- rejuvinate old entry */
- q->change = IFN_KEEP;
-
- /* look for other interfaces to keep (due to NAT-T) */
- for (q = q->next ; q ; q = q->next)
- {
- if (streq(q->rname, ifp->name)
- && streq(q->vname, v->name)
- && sameaddr(&q->addr, &ifp->addr))
+ for (;;)
{
- q->change = IFN_KEEP;
- }
- }
- break;
+ struct iface *q = *p;
+
+ /* search is over if at end of list */
+ if (q == NULL)
+ {
+ /* matches nothing -- create a new entry */
+ int fd = create_socket(ifp, v->name, pluto_port);
+
+ if (fd < 0)
+ break;
+
+ if (nat_traversal_support_non_ike
+ && addrtypeof(&ifp->addr) == AF_INET)
+ {
+ nat_traversal_espinudp_socket(fd, ESPINUDP_WITH_NON_IKE);
+ }
+
+ q = malloc_thing(struct iface);
+ zero(q);
+ q->rname = clone_str(ifp->name);
+ q->vname = clone_str(v->name);
+ q->addr = ifp->addr;
+ q->fd = fd;
+ q->next = interfaces;
+ q->change = IFN_ADD;
+ interfaces = q;
+ plog("adding interface %s/%s %s:%d"
+ , q->vname, q->rname, ip_str(&q->addr), pluto_port);
+
+ if (nat_traversal_support_port_floating
+ && addrtypeof(&ifp->addr) == AF_INET)
+ {
+ fd = create_socket(ifp, v->name, NAT_T_IKE_FLOAT_PORT);
+ if (fd < 0)
+ break;
+ nat_traversal_espinudp_socket(fd,
+ ESPINUDP_WITH_NON_ESP);
+ q = malloc_thing(struct iface);
+ zero(q);
+ q->rname = clone_str(ifp->name);
+ q->vname = clone_str(v->name);
+ q->addr = ifp->addr;
+ setportof(htons(NAT_T_IKE_FLOAT_PORT), &q->addr);
+ q->fd = fd;
+ q->next = interfaces;
+ q->change = IFN_ADD;
+ q->ike_float = TRUE;
+ interfaces = q;
+ plog("adding interface %s/%s %s:%d",
+ q->vname, q->rname, ip_str(&q->addr), NAT_T_IKE_FLOAT_PORT);
+ }
+ break;
+ }
+
+ /* search over if matching old entry found */
+ if (streq(q->rname, ifp->name)
+ && streq(q->vname, v->name)
+ && sameaddr(&q->addr, &ifp->addr))
+ {
+ /* matches -- rejuvinate old entry */
+ q->change = IFN_KEEP;
+
+ /* look for other interfaces to keep (due to NAT-T) */
+ for (q = q->next ; q ; q = q->next)
+ {
+ if (streq(q->rname, ifp->name)
+ && streq(q->vname, v->name)
+ && sameaddr(&q->addr, &ifp->addr))
+ {
+ q->change = IFN_KEEP;
+ }
+ }
+ break;
+ }
+
+ /* try again */
+ p = &q->next;
+ } /* for (;;) */
}
-
- /* try again */
- p = &q->next;
- } /* for (;;) */
}
- }
- /* delete the raw interfaces list */
- while (rifaces != NULL)
- {
- struct raw_iface *t = rifaces;
+ /* delete the raw interfaces list */
+ while (rifaces != NULL)
+ {
+ struct raw_iface *t = rifaces;
- rifaces = t->next;
- pfree(t);
- }
+ rifaces = t->next;
+ free(t);
+ }
}
void
find_ifaces(void)
{
- mark_ifaces_dead();
- process_raw_ifaces(find_raw_ifaces4());
- process_raw_ifaces(find_raw_ifaces6());
+ mark_ifaces_dead();
+ process_raw_ifaces(find_raw_ifaces4());
+ process_raw_ifaces(find_raw_ifaces6());
- free_dead_ifaces(); /* ditch remaining old entries */
+ free_dead_ifaces(); /* ditch remaining old entries */
- if (interfaces == NULL)
- loglog(RC_LOG_SERIOUS, "no public interfaces found");
+ if (interfaces == NULL)
+ loglog(RC_LOG_SERIOUS, "no public interfaces found");
}
void
show_ifaces_status(void)
{
- struct iface *p;
+ struct iface *p;
- for (p = interfaces; p != NULL; p = p->next)
- whack_log(RC_COMMENT, "interface %s/%s %s:%d"
- , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
+ for (p = interfaces; p != NULL; p = p->next)
+ whack_log(RC_COMMENT, "interface %s/%s %s:%d"
+ , p->vname, p->rname, ip_str(&p->addr), ntohs(portof(&p->addr)));
}
void
show_debug_status(void)
{
#ifdef DEBUG
- whack_log(RC_COMMENT, "debug %s"
- , bitnamesof(debug_bit_names, cur_debugging));
+ whack_log(RC_COMMENT, "debug options: %s"
+ , bitnamesof(debug_bit_names, cur_debugging));
#endif
}
@@ -770,7 +772,7 @@ static volatile sig_atomic_t sighupflag = FALSE;
static void
huphandler(int sig UNUSED)
{
- sighupflag = TRUE;
+ sighupflag = TRUE;
}
static volatile sig_atomic_t sigtermflag = FALSE;
@@ -778,7 +780,7 @@ static volatile sig_atomic_t sigtermflag = FALSE;
static void
termhandler(int sig UNUSED)
{
- sigtermflag = TRUE;
+ sigtermflag = TRUE;
}
/* call_server listens for incoming ISAKMP packets and Whack messages,
@@ -787,206 +789,206 @@ termhandler(int sig UNUSED)
void
call_server(void)
{
- struct iface *ifp;
+ struct iface *ifp;
- /* catch SIGHUP and SIGTERM */
- {
- int r;
- struct sigaction act;
+ /* catch SIGHUP and SIGTERM */
+ {
+ int r;
+ struct sigaction act;
+
+ act.sa_handler = &huphandler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
+ r = sigaction(SIGHUP, &act, NULL);
+ passert(r == 0);
+
+ act.sa_handler = &termhandler;
+ r = sigaction(SIGTERM, &act, NULL);
+ passert(r == 0);
+ }
- act.sa_handler = &huphandler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0; /* no SA_ONESHOT, no SA_RESTART, no nothing */
- r = sigaction(SIGHUP, &act, NULL);
- passert(r == 0);
+ for (;;)
+ {
+ fd_set readfds;
+ fd_set writefds;
+ int ndes;
- act.sa_handler = &termhandler;
- r = sigaction(SIGTERM, &act, NULL);
- passert(r == 0);
- }
+ /* wait for next interesting thing */
- for (;;)
- {
- fd_set readfds;
- fd_set writefds;
- int ndes;
+ for (;;)
+ {
+ long next_time = next_event(); /* time to any pending timer event */
+ int maxfd = ctl_fd;
- /* wait for next interesting thing */
+ if (sigtermflag)
+ exit_pluto(0);
- for (;;)
- {
- long next_time = next_event(); /* time to any pending timer event */
- int maxfd = ctl_fd;
-
- if (sigtermflag)
- exit_pluto(0);
-
- if (sighupflag)
- {
- /* Ignorant folks think poking any daemon with SIGHUP
- * is polite. We catch it and tell them otherwise.
- * There is one use: unsticking a hung recvfrom.
- * This sticking happens sometimes -- kernel bug?
- */
- sighupflag = FALSE;
- plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
- }
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_SET(ctl_fd, &readfds);
-
- /* the only write file-descriptor of interest */
- if (adns_qfd != NULL_FD && unsent_ADNS_queries)
- {
- if (maxfd < adns_qfd)
- maxfd = adns_qfd;
- FD_SET(adns_qfd, &writefds);
- }
-
- if (adns_afd != NULL_FD)
- {
- if (maxfd < adns_afd)
- maxfd = adns_afd;
- FD_SET(adns_afd, &readfds);
- }
+ if (sighupflag)
+ {
+ /* Ignorant folks think poking any daemon with SIGHUP
+ * is polite. We catch it and tell them otherwise.
+ * There is one use: unsticking a hung recvfrom.
+ * This sticking happens sometimes -- kernel bug?
+ */
+ sighupflag = FALSE;
+ plog("Pluto ignores SIGHUP -- perhaps you want \"whack --listen\"");
+ }
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_SET(ctl_fd, &readfds);
+
+ /* the only write file-descriptor of interest */
+ if (adns_qfd != NULL_FD && unsent_ADNS_queries)
+ {
+ if (maxfd < adns_qfd)
+ maxfd = adns_qfd;
+ FD_SET(adns_qfd, &writefds);
+ }
+
+ if (adns_afd != NULL_FD)
+ {
+ if (maxfd < adns_afd)
+ maxfd = adns_afd;
+ FD_SET(adns_afd, &readfds);
+ }
#ifdef KLIPS
- if (!no_klips)
- {
- int fd = *kernel_ops->async_fdp;
-
- if (kernel_ops->process_queue)
- kernel_ops->process_queue();
- if (maxfd < fd)
- maxfd = fd;
- passert(!FD_ISSET(fd, &readfds));
- FD_SET(fd, &readfds);
- }
+ if (!no_klips)
+ {
+ int fd = *kernel_ops->async_fdp;
+
+ if (kernel_ops->process_queue)
+ kernel_ops->process_queue();
+ if (maxfd < fd)
+ maxfd = fd;
+ passert(!FD_ISSET(fd, &readfds));
+ FD_SET(fd, &readfds);
+ }
#endif
- if (listening)
- {
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (maxfd < ifp->fd)
- maxfd = ifp->fd;
- passert(!FD_ISSET(ifp->fd, &readfds));
- FD_SET(ifp->fd, &readfds);
- }
- }
-
- if (next_time == -1)
- {
- /* select without timer */
-
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
- }
- else if (next_time == 0)
- {
- /* timer without select: there is a timer event pending,
- * and it should fire now so don't bother to do the select.
- */
- ndes = 0; /* signify timer expiration */
- }
- else
- {
- /* select with timer */
+ if (listening)
+ {
+ for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
+ {
+ if (maxfd < ifp->fd)
+ maxfd = ifp->fd;
+ passert(!FD_ISSET(ifp->fd, &readfds));
+ FD_SET(ifp->fd, &readfds);
+ }
+ }
- struct timeval tm;
+ if (next_time == -1)
+ {
+ /* select without timer */
- tm.tv_sec = next_time;
- tm.tv_usec = 0;
- ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
- }
+ ndes = select(maxfd + 1, &readfds, &writefds, NULL, NULL);
+ }
+ else if (next_time == 0)
+ {
+ /* timer without select: there is a timer event pending,
+ * and it should fire now so don't bother to do the select.
+ */
+ ndes = 0; /* signify timer expiration */
+ }
+ else
+ {
+ /* select with timer */
- if (ndes != -1)
- break; /* success */
+ struct timeval tm;
- if (errno != EINTR)
- exit_log_errno((e, "select() failed in call_server()"));
+ tm.tv_sec = next_time;
+ tm.tv_usec = 0;
+ ndes = select(maxfd + 1, &readfds, &writefds, NULL, &tm);
+ }
- /* retry if terminated by signal */
- }
+ if (ndes != -1)
+ break; /* success */
- /* figure out what is interesting */
+ if (errno != EINTR)
+ exit_log_errno((e, "select() failed in call_server()"));
- if (ndes == 0)
- {
- /* timer event */
+ /* retry if terminated by signal */
+ }
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*time to handle event"));
+ /* figure out what is interesting */
- handle_timer_event();
- passert(GLOBALS_ARE_RESET());
- }
- else
- {
- /* at least one file descriptor is ready */
-
- if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
- {
- passert(ndes > 0);
- send_unsent_ADNS_queries();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received adns message"));
- handle_adns_answer();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
+ if (ndes == 0)
+ {
+ /* timer event */
+
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*time to handle event"));
+
+ handle_timer_event();
+ passert(GLOBALS_ARE_RESET());
+ }
+ else
+ {
+ /* at least one file descriptor is ready */
+
+ if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
+ {
+ passert(ndes > 0);
+ send_unsent_ADNS_queries();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+
+ if (adns_afd != NULL_FD && FD_ISSET(adns_afd, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received adns message"));
+ handle_adns_answer();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
#ifdef KLIPS
- if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received kernel message"));
- kernel_ops->process_msg();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
+ if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received kernel message"));
+ kernel_ops->process_msg();
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
#endif
- for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
- {
- if (FD_ISSET(ifp->fd, &readfds))
- {
- /* comm_handle will print DBG_CONTROL intro,
- * with more info than we have here.
- */
-
- passert(ndes > 0);
- comm_handle(ifp);
- passert(GLOBALS_ARE_RESET());
- ndes--;
+ for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
+ {
+ if (FD_ISSET(ifp->fd, &readfds))
+ {
+ /* comm_handle will print DBG_CONTROL intro,
+ * with more info than we have here.
+ */
+
+ passert(ndes > 0);
+ comm_handle(ifp);
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+ }
+
+ if (FD_ISSET(ctl_fd, &readfds))
+ {
+ passert(ndes > 0);
+ DBG(DBG_CONTROL,
+ DBG_log(BLANK_FORMAT);
+ DBG_log("*received whack message"));
+ whack_handle(ctl_fd);
+ passert(GLOBALS_ARE_RESET());
+ ndes--;
+ }
+
+ passert(ndes == 0);
}
- }
-
- if (FD_ISSET(ctl_fd, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received whack message"));
- whack_handle(ctl_fd);
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-
- passert(ndes == 0);
}
- }
}
/*
diff --git a/src/pluto/server.h b/src/pluto/server.h
index d0d46a5f4..b8123f6dc 100644
--- a/src/pluto/server.h
+++ b/src/pluto/server.h
@@ -10,20 +10,18 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: server.h 3252 2007-10-06 21:24:50Z andreas $
*/
-extern int ctl_fd; /* file descriptor of control (whack) socket */
-extern struct sockaddr_un ctl_addr; /* address of control (whack) socket */
+extern int ctl_fd; /* file descriptor of control (whack) socket */
+extern struct sockaddr_un ctl_addr; /* address of control (whack) socket */
-extern int info_fd; /* file descriptor of control (info) socket */
-extern struct sockaddr_un info_addr; /* address of control (info) socket */
+extern int info_fd; /* file descriptor of control (info) socket */
+extern struct sockaddr_un info_addr; /* address of control (info) socket */
extern err_t init_ctl_socket(void);
extern void delete_ctl_socket(void);
-extern bool listening; /* should we pay attention to IKE messages? */
+extern bool listening; /* should we pay attention to IKE messages? */
/* interface: a terminal point for IKE traffic, IPsec transport mode
@@ -35,16 +33,16 @@ extern bool listening; /* should we pay attention to IKE messages? */
* Note: the port for IKE is always implicitly UDP/pluto_port.
*/
struct iface {
- char *vname; /* virtual (ipsec) device name */
- char *rname; /* real device name */
- ip_address addr; /* interface IP address */
- int fd; /* file descriptor of socket for IKE UDP messages */
- struct iface *next;
- bool ike_float;
- enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
+ char *vname; /* virtual (ipsec) device name */
+ char *rname; /* real device name */
+ ip_address addr; /* interface IP address */
+ int fd; /* file descriptor of socket for IKE UDP messages */
+ struct iface *next;
+ bool ike_float;
+ enum { IFN_ADD, IFN_KEEP, IFN_DELETE } change;
};
-extern struct iface *interfaces; /* public interfaces */
+extern struct iface *interfaces; /* public interfaces */
extern bool use_interface(const char *rifn);
extern void find_ifaces(void);
diff --git a/src/pluto/sha1.c b/src/pluto/sha1.c
deleted file mode 100644
index bbf062876..000000000
--- a/src/pluto/sha1.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-
-Test Vectors (from FIPS PUB 180-1)
-"abc"
- A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-A million repetitions of "a"
- 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
-/* #define SHA1HANDSOFF * Copies data before messing with it. */
-
-#define SHA1HANDSOFF
-
-#include <string.h>
-#include <sys/types.h> /* for u_int*_t */
-#include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
-
-#include "sha1.h"
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF))
-#elif BYTE_ORDER == BIG_ENDIAN
-#define blk0(i) block->l[i]
-#else
-#error "Endianness not defined!"
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
-{
-u_int32_t a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- u_int32_t l[16];
-} CHAR64LONG16;
-#ifdef SHA1HANDSOFF
-CHAR64LONG16 block[1]; /* use array to appear as a pointer */
- memcpy(block, buffer, 64);
-#else
- /* The following had better never be used because it causes the
- * pointer-to-const buffer to be cast into a pointer to non-const.
- * And the result is written through. I threw a "const" in, hoping
- * this will cause a diagnostic.
- */
-CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
-#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
-#ifdef SHA1HANDSOFF
- memset(block, '\0', sizeof(block));
-#endif
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void SHA1Init(SHA1_CTX* context)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/* Run your data through this. */
-
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
-{
-u_int32_t i;
-u_int32_t j;
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1]++;
- context->count[1] += (len>>29);
- j = (j >> 3) & 63;
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-
-/* Add padding and return the message digest. */
-
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-unsigned i;
-unsigned char finalcount[8];
-unsigned char c;
-
-#if 0 /* untested "improvement" by DHR */
- /* Convert context->count to a sequence of bytes
- * in finalcount. Second element first, but
- * big-endian order within element.
- * But we do it all backwards.
- */
- unsigned char *fcp = &finalcount[8];
-
- for (i = 0; i < 2; i++)
- {
- u_int32_t t = context->count[i];
- int j;
-
- for (j = 0; j < 4; t >>= 8, j++)
- *--fcp = (unsigned char) t
- }
-#else
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
-#endif
- c = 0200;
- SHA1Update(context, &c, 1);
- while ((context->count[0] & 504) != 448) {
- c = 0000;
- SHA1Update(context, &c, 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- /* Wipe variables */
- memset(context, '\0', sizeof(*context));
- memset(&finalcount, '\0', sizeof(finalcount));
-}
diff --git a/src/pluto/sha1.h b/src/pluto/sha1.h
deleted file mode 100644
index 64b3d2f5d..000000000
--- a/src/pluto/sha1.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-SHA-1 in C
-By Steve Reid <steve@edmweb.com>
-100% Public Domain
-*/
-
-typedef struct {
- u_int32_t state[5];
- u_int32_t count[2];
- unsigned char buffer[64];
-} SHA1_CTX;
-
-void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
-void SHA1Init(SHA1_CTX* context);
-void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
diff --git a/src/pluto/smallprime.c b/src/pluto/smallprime.c
deleted file mode 100644
index 87497d096..000000000
--- a/src/pluto/smallprime.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* smallprime.c - List of small primes
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifdef PLUTO
-#include <gmp.h>
-#include <freeswan.h>
-#include "constants.h"
-#include "defs.h"
-#include "gcryptfix.h"
-#else
-/* #include <config.h> */
-/* #include <stdio.h> */
-/* #include <stdlib.h> */
-/* #include "util.h" */
-/* #include "types.h" */
-#endif
-
-/* Note: 2 is not included because it can be tested more easily
- * by looking at bit 0. The last entry in this list is marked by a zero
- */
-ushort
-small_prime_numbers[] = {
- 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
- 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
- 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
- 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
- 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
- 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
- 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
- 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
- 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
- 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
- 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
- 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
- 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
- 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
- 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
- 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
- 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
- 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
- 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
- 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
- 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
- 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
- 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
- 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
- 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
- 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
- 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
- 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
- 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
- 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
- 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
- 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
- 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
- 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
- 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
- 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
- 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
- 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
- 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
- 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
- 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
- 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
- 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
- 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
- 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
- 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
- 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
- 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
- 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
- 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
- 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
- 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
- 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
- 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
- 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
- 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
- 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
- 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
- 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
- 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
- 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
- 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
- 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
- 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
- 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
- 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
- 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
- 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
- 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
- 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
- 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
- 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
- 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
- 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
- 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
- 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
- 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
- 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
- 4957, 4967, 4969, 4973, 4987, 4993, 4999,
- 0
-};
-
-
diff --git a/src/pluto/smartcard.c b/src/pluto/smartcard.c
index 937c3f93a..7e4452d89 100644
--- a/src/pluto/smartcard.c
+++ b/src/pluto/smartcard.c
@@ -6,7 +6,7 @@
* Copyright (C) 2005 Michael Joosten
*
* Copyright (C) 2005 Andreas Steffen
- * Hochschule für Technik Rapperswil, Switzerland
+ * Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,8 +17,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: smartcard.c 3686 2008-03-28 11:48:14Z martin $
*/
#include <stdio.h>
@@ -30,7 +28,9 @@
#include <dlfcn.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <asn1/asn1.h>
+#include <credentials/keys/public_key.h>
#include "constants.h"
@@ -40,7 +40,6 @@
#endif
#include "defs.h"
-#include "mp_defs.h"
#include "log.h"
#include "x509.h"
#include "ca.h"
@@ -50,7 +49,7 @@
#include "whack.h"
#include "fetch.h"
-#define DEFAULT_BASE 16
+#define DEFAULT_BASE 16
/* chained list of smartcard records */
static smartcard_t *smartcards = NULL;
@@ -59,30 +58,30 @@ static smartcard_t *smartcards = NULL;
static int sc_number = 0;
const smartcard_t empty_sc = {
- NULL , /* next */
- 0 , /* last_load */
- { CERT_NONE, {NULL} }, /* last_cert */
- 0 , /* count */
- 0 , /* number */
- 999999 , /* slot */
- NULL , /* id */
- NULL , /* label */
- { NULL, 0 } , /* pin */
- FALSE , /* pinpad */
- FALSE , /* valid */
- FALSE , /* session_opened */
- FALSE , /* logged_in */
- TRUE , /* any_slot */
- 0L , /* session */
+ NULL , /* next */
+ 0 , /* last_load */
+ { CERT_NONE, {NULL} }, /* last_cert */
+ 0 , /* count */
+ 0 , /* number */
+ 999999 , /* slot */
+ NULL , /* id */
+ NULL , /* label */
+ { NULL, 0 } , /* pin */
+ FALSE , /* pinpad */
+ FALSE , /* valid */
+ FALSE , /* session_opened */
+ FALSE , /* logged_in */
+ TRUE , /* any_slot */
+ 0L , /* session */
};
-#ifdef SMARTCARD /* compile with smartcard support */
+#ifdef SMARTCARD /* compile with smartcard support */
-#define SCX_MAGIC 0xd00bed00
+#define SCX_MAGIC 0xd00bed00
struct scx_pkcs11_module {
- u_int _magic;
- void *handle;
+ u_int _magic;
+ void *handle;
};
typedef struct scx_pkcs11_module scx_pkcs11_module_t;
@@ -95,292 +94,292 @@ static CK_FUNCTION_LIST_PTR pkcs11_functions = NULL_PTR;
/* crytoki v2.11 - return values of PKCS #11 functions*/
static const char *const pkcs11_return_name[] = {
- "CKR_OK",
- "CKR_CANCEL",
- "CKR_HOST_MEMORY",
- "CKR_SLOT_ID_INVALID",
- "CKR_FLAGS_INVALID",
- "CKR_GENERAL_ERROR",
- "CKR_FUNCTION_FAILED",
- "CKR_ARGUMENTS_BAD",
- "CKR_NO_EVENT",
- "CKR_NEED_TO_CREATE_THREADS",
- "CKR_CANT_LOCK"
- };
+ "CKR_OK",
+ "CKR_CANCEL",
+ "CKR_HOST_MEMORY",
+ "CKR_SLOT_ID_INVALID",
+ "CKR_FLAGS_INVALID",
+ "CKR_GENERAL_ERROR",
+ "CKR_FUNCTION_FAILED",
+ "CKR_ARGUMENTS_BAD",
+ "CKR_NO_EVENT",
+ "CKR_NEED_TO_CREATE_THREADS",
+ "CKR_CANT_LOCK"
+ };
static const char *const pkcs11_return_name_10[] = {
- "CKR_ATTRIBUTE_READ_ONLY",
- "CKR_ATTRIBUTE_SENSITIVE",
- "CKR_ATTRIBUTE_TYPE_INVALID",
- "CKR_ATTRIBUTE_VALUE_INVALID"
- };
+ "CKR_ATTRIBUTE_READ_ONLY",
+ "CKR_ATTRIBUTE_SENSITIVE",
+ "CKR_ATTRIBUTE_TYPE_INVALID",
+ "CKR_ATTRIBUTE_VALUE_INVALID"
+ };
static const char *const pkcs11_return_name_20[] = {
- "CKR_DATA_INVALID",
- "CKR_DATA_LEN_RANGE"
- };
+ "CKR_DATA_INVALID",
+ "CKR_DATA_LEN_RANGE"
+ };
static const char *const pkcs11_return_name_30[] = {
- "CKR_DEVICE_ERROR",
- "CKR_DEVICE_MEMORY",
- "CKR_DEVICE_REMOVED"
- };
+ "CKR_DEVICE_ERROR",
+ "CKR_DEVICE_MEMORY",
+ "CKR_DEVICE_REMOVED"
+ };
static const char *const pkcs11_return_name_40[] = {
- "CKR_ENCRYPTED_DATA_INVALID",
- "CKR_ENCRYPTED_DATA_LEN_RANGE"
- };
+ "CKR_ENCRYPTED_DATA_INVALID",
+ "CKR_ENCRYPTED_DATA_LEN_RANGE"
+ };
static const char *const pkcs11_return_name_50[] = {
- "CKR_FUNCTION_CANCELED",
- "CKR_FUNCTION_NOT_PARALLEL",
- "CKR_0x52_UNDEFINED",
- "CKR_0x53_UNDEFINED",
- "CKR_FUNCTION_NOT_SUPPORTED"
- };
+ "CKR_FUNCTION_CANCELED",
+ "CKR_FUNCTION_NOT_PARALLEL",
+ "CKR_0x52_UNDEFINED",
+ "CKR_0x53_UNDEFINED",
+ "CKR_FUNCTION_NOT_SUPPORTED"
+ };
static const char *const pkcs11_return_name_60[] = {
- "CKR_KEY_HANDLE_INVALID",
- "CKR_KEY_SENSITIVE",
- "CKR_KEY_SIZE_RANGE",
- "CKR_KEY_TYPE_INCONSISTENT",
- "CKR_KEY_NOT_NEEDED",
- "CKR_KEY_CHANGED",
- "CKR_KEY_NEEDED",
- "CKR_KEY_INDIGESTIBLE",
- "CKR_KEY_FUNCTION_NOT_PERMITTED",
- "CKR_KEY_NOT_WRAPPABLE",
- "CKR_KEY_UNEXTRACTABLE"
- };
+ "CKR_KEY_HANDLE_INVALID",
+ "CKR_KEY_SENSITIVE",
+ "CKR_KEY_SIZE_RANGE",
+ "CKR_KEY_TYPE_INCONSISTENT",
+ "CKR_KEY_NOT_NEEDED",
+ "CKR_KEY_CHANGED",
+ "CKR_KEY_NEEDED",
+ "CKR_KEY_INDIGESTIBLE",
+ "CKR_KEY_FUNCTION_NOT_PERMITTED",
+ "CKR_KEY_NOT_WRAPPABLE",
+ "CKR_KEY_UNEXTRACTABLE"
+ };
static const char *const pkcs11_return_name_70[] = {
- "CKR_MECHANISM_INVALID",
- "CKR_MECHANISM_PARAM_INVALID"
- };
+ "CKR_MECHANISM_INVALID",
+ "CKR_MECHANISM_PARAM_INVALID"
+ };
static const char *const pkcs11_return_name_80[] = {
- "CKR_OBJECT_HANDLE_INVALID"
- };
+ "CKR_OBJECT_HANDLE_INVALID"
+ };
static const char *const pkcs11_return_name_90[] = {
- "CKR_OPERATION_ACTIVE",
- "CKR_OPERATION_NOT_INITIALIZED"
- };
+ "CKR_OPERATION_ACTIVE",
+ "CKR_OPERATION_NOT_INITIALIZED"
+ };
static const char *const pkcs11_return_name_A0[] = {
- "CKR_PIN_INCORRECT",
- "CKR_PIN_INVALID",
- "CKR_PIN_LEN_RANGE",
- "CKR_PIN_EXPIRED",
- "CKR_PIN_LOCKED"
- };
+ "CKR_PIN_INCORRECT",
+ "CKR_PIN_INVALID",
+ "CKR_PIN_LEN_RANGE",
+ "CKR_PIN_EXPIRED",
+ "CKR_PIN_LOCKED"
+ };
static const char *const pkcs11_return_name_B0[] = {
- "CKR_SESSION_CLOSED",
- "CKR_SESSION_COUNT",
- "CKR_0xB2_UNDEFINED",
- "CKR_SESSION_HANDLE_INVALID",
- "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
- "CKR_SESSION_READ_ONLY",
- "CKR_SESSION_EXISTS",
- "CKR_SESSION_READ_ONLY_EXISTS",
- "CKR_SESSION_READ_WRITE_SO_EXISTS"
- };
+ "CKR_SESSION_CLOSED",
+ "CKR_SESSION_COUNT",
+ "CKR_0xB2_UNDEFINED",
+ "CKR_SESSION_HANDLE_INVALID",
+ "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
+ "CKR_SESSION_READ_ONLY",
+ "CKR_SESSION_EXISTS",
+ "CKR_SESSION_READ_ONLY_EXISTS",
+ "CKR_SESSION_READ_WRITE_SO_EXISTS"
+ };
static const char *const pkcs11_return_name_C0[] = {
- "CKR_SIGNATURE_INVALID",
- "CKR_SIGNATURE_LEN_RANGE"
- };
+ "CKR_SIGNATURE_INVALID",
+ "CKR_SIGNATURE_LEN_RANGE"
+ };
static const char *const pkcs11_return_name_D0[] = {
- "CKR_TEMPLATE_INCOMPLETE",
- "CKR_TEMPLATE_INCONSISTENT"
- };
+ "CKR_TEMPLATE_INCOMPLETE",
+ "CKR_TEMPLATE_INCONSISTENT"
+ };
static const char *const pkcs11_return_name_E0[] = {
- "CKR_TOKEN_NOT_PRESENT",
- "CKR_TOKEN_NOT_RECOGNIZED",
- "CKR_TOKEN_WRITE_PROTECTED"
- };
+ "CKR_TOKEN_NOT_PRESENT",
+ "CKR_TOKEN_NOT_RECOGNIZED",
+ "CKR_TOKEN_WRITE_PROTECTED"
+ };
static const char *const pkcs11_return_name_F0[] = {
- "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
- "CKR_UNWRAPPING_KEY_SIZE_RANGE",
- "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"
- };
+ "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
+ "CKR_UNWRAPPING_KEY_SIZE_RANGE",
+ "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"
+ };
static const char *const pkcs11_return_name_100[] = {
- "CKR_USER_ALREADY_LOGGED_IN",
- "CKR_USER_NOT_LOGGED_IN",
- "CKR_USER_PIN_NOT_INITIALIZED",
- "CKR_USER_TYPE_INVALID",
- "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
- "CKR_USER_TOO_MANY_TYPES"
- };
+ "CKR_USER_ALREADY_LOGGED_IN",
+ "CKR_USER_NOT_LOGGED_IN",
+ "CKR_USER_PIN_NOT_INITIALIZED",
+ "CKR_USER_TYPE_INVALID",
+ "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
+ "CKR_USER_TOO_MANY_TYPES"
+ };
static const char *const pkcs11_return_name_110[] = {
- "CKR_WRAPPED_KEY_INVALID",
- "CKR_0x111_UNDEFINED",
- "CKR_WRAPPED_KEY_LEN_RANGE",
- "CKR_WRAPPING_KEY_HANDLE_INVALID",
- "CKR_WRAPPING_KEY_SIZE_RANGE",
- "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"
- };
+ "CKR_WRAPPED_KEY_INVALID",
+ "CKR_0x111_UNDEFINED",
+ "CKR_WRAPPED_KEY_LEN_RANGE",
+ "CKR_WRAPPING_KEY_HANDLE_INVALID",
+ "CKR_WRAPPING_KEY_SIZE_RANGE",
+ "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"
+ };
static const char *const pkcs11_return_name_120[] = {
- "CKR_RANDOM_SEED_NOT_SUPPORTED",
- "CKR_RANDOM_NO_RNG"
- };
+ "CKR_RANDOM_SEED_NOT_SUPPORTED",
+ "CKR_RANDOM_NO_RNG"
+ };
static const char *const pkcs11_return_name_130[] = {
- "CKR_DOMAIN_PARAMS_INVALID"
- };
+ "CKR_DOMAIN_PARAMS_INVALID"
+ };
static const char *const pkcs11_return_name_150[] = {
- "CKR_BUFFER_TOO_SMALL"
- };
+ "CKR_BUFFER_TOO_SMALL"
+ };
static const char *const pkcs11_return_name_160[] = {
- "CKR_SAVED_STATE_INVALID"
- };
+ "CKR_SAVED_STATE_INVALID"
+ };
static const char *const pkcs11_return_name_170[] = {
- "CKR_INFORMATION_SENSITIVE"
- };
+ "CKR_INFORMATION_SENSITIVE"
+ };
static const char *const pkcs11_return_name_180[] = {
- "CKR_STATE_UNSAVEABLE"
- };
+ "CKR_STATE_UNSAVEABLE"
+ };
static const char *const pkcs11_return_name_190[] = {
- "CKR_CRYPTOKI_NOT_INITIALIZED",
- "CKR_CRYPTOKI_ALREADY_INITIALIZED"
- };
+ "CKR_CRYPTOKI_NOT_INITIALIZED",
+ "CKR_CRYPTOKI_ALREADY_INITIALIZED"
+ };
static const char *const pkcs11_return_name_1A0[] = {
- "CKR_MUTEX_BAD",
- "CKR_MUTEX_NOT_LOCKED"
- };
+ "CKR_MUTEX_BAD",
+ "CKR_MUTEX_NOT_LOCKED"
+ };
static const char *const pkcs11_return_name_200[] = {
- "CKR_FUNCTION_REJECTED"
- };
+ "CKR_FUNCTION_REJECTED"
+ };
static const char *const pkcs11_return_name_vendor[] = {
- "CKR_VENDOR_DEFINED"
- };
+ "CKR_VENDOR_DEFINED"
+ };
static enum_names pkcs11_return_names_vendor =
- { CKR_VENDOR_DEFINED, CKR_VENDOR_DEFINED
- , pkcs11_return_name_vendor, NULL };
+ { CKR_VENDOR_DEFINED, CKR_VENDOR_DEFINED
+ , pkcs11_return_name_vendor, NULL };
static enum_names pkcs11_return_names_200 =
- { CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED
- , pkcs11_return_name_200, &pkcs11_return_names_vendor };
+ { CKR_FUNCTION_REJECTED, CKR_FUNCTION_REJECTED
+ , pkcs11_return_name_200, &pkcs11_return_names_vendor };
static enum_names pkcs11_return_names_1A0 =
- { CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED
- , pkcs11_return_name_1A0, &pkcs11_return_names_200 };
+ { CKR_MUTEX_BAD, CKR_MUTEX_NOT_LOCKED
+ , pkcs11_return_name_1A0, &pkcs11_return_names_200 };
static enum_names pkcs11_return_names_190 =
- { CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED
- , pkcs11_return_name_190, &pkcs11_return_names_1A0 };
+ { CKR_CRYPTOKI_NOT_INITIALIZED, CKR_CRYPTOKI_ALREADY_INITIALIZED
+ , pkcs11_return_name_190, &pkcs11_return_names_1A0 };
static enum_names pkcs11_return_names_180 =
- { CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE
- , pkcs11_return_name_180, &pkcs11_return_names_190 };
+ { CKR_STATE_UNSAVEABLE, CKR_STATE_UNSAVEABLE
+ , pkcs11_return_name_180, &pkcs11_return_names_190 };
static enum_names pkcs11_return_names_170 =
- { CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE
- , pkcs11_return_name_170, &pkcs11_return_names_180 };
+ { CKR_INFORMATION_SENSITIVE, CKR_INFORMATION_SENSITIVE
+ , pkcs11_return_name_170, &pkcs11_return_names_180 };
static enum_names pkcs11_return_names_160 =
- { CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID
- , pkcs11_return_name_160, &pkcs11_return_names_170 };
+ { CKR_SAVED_STATE_INVALID, CKR_SAVED_STATE_INVALID
+ , pkcs11_return_name_160, &pkcs11_return_names_170 };
static enum_names pkcs11_return_names_150 =
- { CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL
- , pkcs11_return_name_150, &pkcs11_return_names_160 };
+ { CKR_BUFFER_TOO_SMALL, CKR_BUFFER_TOO_SMALL
+ , pkcs11_return_name_150, &pkcs11_return_names_160 };
static enum_names pkcs11_return_names_130 =
- { CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID
- , pkcs11_return_name_130, &pkcs11_return_names_150 };
+ { CKR_DOMAIN_PARAMS_INVALID, CKR_DOMAIN_PARAMS_INVALID
+ , pkcs11_return_name_130, &pkcs11_return_names_150 };
static enum_names pkcs11_return_names_120 =
- { CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG
- , pkcs11_return_name_120, &pkcs11_return_names_130 };
+ { CKR_RANDOM_SEED_NOT_SUPPORTED, CKR_RANDOM_NO_RNG
+ , pkcs11_return_name_120, &pkcs11_return_names_130 };
static enum_names pkcs11_return_names_110 =
- { CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT
- , pkcs11_return_name_110, &pkcs11_return_names_120 };
+ { CKR_WRAPPED_KEY_INVALID, CKR_WRAPPING_KEY_TYPE_INCONSISTENT
+ , pkcs11_return_name_110, &pkcs11_return_names_120 };
static enum_names pkcs11_return_names_100 =
- { CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES
- , pkcs11_return_name_100, &pkcs11_return_names_110 };
+ { CKR_USER_ALREADY_LOGGED_IN, CKR_USER_TOO_MANY_TYPES
+ , pkcs11_return_name_100, &pkcs11_return_names_110 };
static enum_names pkcs11_return_names_F0 =
- { CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
- , pkcs11_return_name_F0, &pkcs11_return_names_100 };
+ { CKR_UNWRAPPING_KEY_HANDLE_INVALID, CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT
+ , pkcs11_return_name_F0, &pkcs11_return_names_100 };
static enum_names pkcs11_return_names_E0 =
- { CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED
- , pkcs11_return_name_E0, &pkcs11_return_names_F0 };
+ { CKR_TOKEN_NOT_PRESENT, CKR_TOKEN_WRITE_PROTECTED
+ , pkcs11_return_name_E0, &pkcs11_return_names_F0 };
static enum_names pkcs11_return_names_D0 =
- { CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT
- , pkcs11_return_name_D0,&pkcs11_return_names_E0 };
+ { CKR_TEMPLATE_INCOMPLETE, CKR_TEMPLATE_INCONSISTENT
+ , pkcs11_return_name_D0,&pkcs11_return_names_E0 };
static enum_names pkcs11_return_names_C0 =
- { CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE
- , pkcs11_return_name_C0, &pkcs11_return_names_D0 };
+ { CKR_SIGNATURE_INVALID, CKR_SIGNATURE_LEN_RANGE
+ , pkcs11_return_name_C0, &pkcs11_return_names_D0 };
static enum_names pkcs11_return_names_B0 =
- { CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS
- , pkcs11_return_name_B0, &pkcs11_return_names_C0 };
+ { CKR_SESSION_CLOSED, CKR_SESSION_READ_WRITE_SO_EXISTS
+ , pkcs11_return_name_B0, &pkcs11_return_names_C0 };
static enum_names pkcs11_return_names_A0 =
- { CKR_PIN_INCORRECT, CKR_PIN_LOCKED
- , pkcs11_return_name_A0, &pkcs11_return_names_B0 };
+ { CKR_PIN_INCORRECT, CKR_PIN_LOCKED
+ , pkcs11_return_name_A0, &pkcs11_return_names_B0 };
static enum_names pkcs11_return_names_90 =
- { CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED
- , pkcs11_return_name_90, &pkcs11_return_names_A0 };
+ { CKR_OPERATION_ACTIVE, CKR_OPERATION_NOT_INITIALIZED
+ , pkcs11_return_name_90, &pkcs11_return_names_A0 };
static enum_names pkcs11_return_names_80 =
- { CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID
- , pkcs11_return_name_80, &pkcs11_return_names_90 };
+ { CKR_OBJECT_HANDLE_INVALID, CKR_OBJECT_HANDLE_INVALID
+ , pkcs11_return_name_80, &pkcs11_return_names_90 };
static enum_names pkcs11_return_names_70 =
- { CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID
- , pkcs11_return_name_70, &pkcs11_return_names_80 };
+ { CKR_MECHANISM_INVALID, CKR_MECHANISM_PARAM_INVALID
+ , pkcs11_return_name_70, &pkcs11_return_names_80 };
static enum_names pkcs11_return_names_60 =
- { CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE
- , pkcs11_return_name_60, &pkcs11_return_names_70 };
+ { CKR_KEY_HANDLE_INVALID, CKR_KEY_UNEXTRACTABLE
+ , pkcs11_return_name_60, &pkcs11_return_names_70 };
static enum_names pkcs11_return_names_50 =
- { CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED
- , pkcs11_return_name_50, &pkcs11_return_names_60 };
+ { CKR_FUNCTION_CANCELED, CKR_FUNCTION_NOT_SUPPORTED
+ , pkcs11_return_name_50, &pkcs11_return_names_60 };
static enum_names pkcs11_return_names_40 =
- { CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE
- , pkcs11_return_name_40, &pkcs11_return_names_50 };
+ { CKR_ENCRYPTED_DATA_INVALID, CKR_ENCRYPTED_DATA_LEN_RANGE
+ , pkcs11_return_name_40, &pkcs11_return_names_50 };
static enum_names pkcs11_return_names_30 =
- { CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED
- , pkcs11_return_name_30, &pkcs11_return_names_40 };
+ { CKR_DEVICE_ERROR, CKR_DEVICE_REMOVED
+ , pkcs11_return_name_30, &pkcs11_return_names_40 };
static enum_names pkcs11_return_names_20 =
- { CKR_DATA_INVALID, CKR_DATA_LEN_RANGE
- , pkcs11_return_name_20, &pkcs11_return_names_30 };
+ { CKR_DATA_INVALID, CKR_DATA_LEN_RANGE
+ , pkcs11_return_name_20, &pkcs11_return_names_30 };
static enum_names pkcs11_return_names_10 =
- { CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID
- , pkcs11_return_name_10, &pkcs11_return_names_20};
+ { CKR_ATTRIBUTE_READ_ONLY, CKR_ATTRIBUTE_VALUE_INVALID
+ , pkcs11_return_name_10, &pkcs11_return_names_20};
static enum_names pkcs11_return_names =
- { CKR_OK, CKR_CANT_LOCK
- , pkcs11_return_name, &pkcs11_return_names_10};
+ { CKR_OK, CKR_CANT_LOCK
+ , pkcs11_return_name, &pkcs11_return_names_10};
/*
* Unload a PKCS#11 module.
@@ -390,49 +389,49 @@ static enum_names pkcs11_return_names =
static CK_RV
scx_unload_pkcs11_module(scx_pkcs11_module_t *mod)
{
- if (!mod || mod->_magic != SCX_MAGIC)
- return CKR_ARGUMENTS_BAD;
+ if (!mod || mod->_magic != SCX_MAGIC)
+ return CKR_ARGUMENTS_BAD;
- if (dlclose(mod->handle) < 0)
- return CKR_FUNCTION_FAILED;
+ if (dlclose(mod->handle) < 0)
+ return CKR_FUNCTION_FAILED;
- memset(mod, 0, sizeof(*mod));
- pfree(mod);
- return CKR_OK;
+ memset(mod, 0, sizeof(*mod));
+ free(mod);
+ return CKR_OK;
}
static scx_pkcs11_module_t*
scx_load_pkcs11_module(const char *name, CK_FUNCTION_LIST_PTR_PTR funcs)
{
- CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
- scx_pkcs11_module_t *mod;
- void *handle;
- int rv;
+ CK_RV (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
+ scx_pkcs11_module_t *mod;
+ void *handle;
+ int rv;
- if (name == NULL || *name == '\0')
- return NULL;
+ if (name == NULL || *name == '\0')
+ return NULL;
- /* Try to load PKCS#11 library module*/
- handle = dlopen(name, RTLD_NOW);
- if (handle == NULL)
- return NULL;
+ /* Try to load PKCS#11 library module*/
+ handle = dlopen(name, RTLD_NOW);
+ if (handle == NULL)
+ return NULL;
- mod = alloc_thing(scx_pkcs11_module_t, "scx_pkcs11_module");
- mod->_magic = SCX_MAGIC;
- mod->handle = handle;
+ mod = malloc_thing(scx_pkcs11_module_t);
+ mod->_magic = SCX_MAGIC;
+ mod->handle = handle;
/* Get the list of function pointers */
- c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
- dlsym(mod->handle, "C_GetFunctionList");
- if (!c_get_function_list)
- goto failed;
+ c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
+ dlsym(mod->handle, "C_GetFunctionList");
+ if (!c_get_function_list)
+ goto failed;
- rv = c_get_function_list(funcs);
- if (rv == CKR_OK)
- return mod;
+ rv = c_get_function_list(funcs);
+ if (rv == CKR_OK)
+ return mod;
failed: scx_unload_pkcs11_module(mod);
- return NULL;
+ return NULL;
}
/*
@@ -442,78 +441,78 @@ static bool
scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
, smartcard_t *sc, cert_t *cert)
{
- size_t hex_len, label_len;
- u_char *hex_id = NULL;
- chunk_t blob;
- x509cert_t *x509cert;
-
- CK_ATTRIBUTE attr[] = {
- { CKA_ID, NULL_PTR, 0L },
- { CKA_LABEL, NULL_PTR, 0L },
- { CKA_VALUE, NULL_PTR, 0L }
- };
-
- /* initialize the return argument */
- *cert = empty_cert;
-
- /* get the length of the attributes first */
- CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the attribute sizes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- pfreeany(sc->label);
-
- hex_id = alloc_bytes(attr[0].ulValueLen, "hex id");
- hex_len = attr[0].ulValueLen;
- sc->label = alloc_bytes(attr[1].ulValueLen + 1, "sc label");
- label_len = attr[1].ulValueLen;
- blob.ptr = alloc_bytes(attr[2].ulValueLen, "x509cert blob");
- blob.len = attr[2].ulValueLen;
-
- attr[0].pValue = hex_id;
- attr[1].pValue = sc->label;
- attr[2].pValue = blob.ptr;
-
- /* now get the attributes */
- rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfree(hex_id);
- pfreeany(sc->label);
- pfree(blob.ptr);
- return FALSE;
- }
+ size_t hex_len, label_len;
+ u_char *hex_id = NULL;
+ chunk_t blob;
+ x509cert_t *x509cert;
+
+ CK_ATTRIBUTE attr[] = {
+ { CKA_ID, NULL_PTR, 0L },
+ { CKA_LABEL, NULL_PTR, 0L },
+ { CKA_VALUE, NULL_PTR, 0L }
+ };
+
+ /* initialize the return argument */
+ *cert = cert_empty;
+
+ /* get the length of the attributes first */
+ CK_RV rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
+ if (rv != CKR_OK)
+ {
+ plog("couldn't read the attribute sizes: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ free(sc->label);
+
+ hex_id = malloc(attr[0].ulValueLen);
+ hex_len = attr[0].ulValueLen;
+ sc->label = malloc(attr[1].ulValueLen + 1);
+ label_len = attr[1].ulValueLen;
+ blob.ptr = malloc(attr[2].ulValueLen);
+ blob.len = attr[2].ulValueLen;
+
+ attr[0].pValue = hex_id;
+ attr[1].pValue = sc->label;
+ attr[2].pValue = blob.ptr;
+
+ /* now get the attributes */
+ rv = pkcs11_functions->C_GetAttributeValue(session, object, attr, 3);
+ if (rv != CKR_OK)
+ {
+ plog("couldn't read the attributes: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ free(hex_id);
+ free(sc->label);
+ free(blob.ptr);
+ return FALSE;
+ }
- pfreeany(sc->id);
+ free(sc->id);
- /* convert id from hex to ASCII */
- sc->id = alloc_bytes(2*hex_len + 1, " sc id");
- datatot(hex_id, hex_len, 16, sc->id, 2*hex_len + 1);
- pfree(hex_id);
+ /* convert id from hex to ASCII */
+ sc->id = malloc(2*hex_len + 1);
+ datatot(hex_id, hex_len, 16, sc->id, 2*hex_len + 1);
+ free(hex_id);
- /* safeguard in case the label is not null terminated */
- sc->label[label_len] = '\0';
+ /* safeguard in case the label is not null terminated */
+ sc->label[label_len] = '\0';
- /* parse the retrieved cert */
- x509cert = alloc_thing(x509cert_t, "x509cert");
- *x509cert = empty_x509cert;
- x509cert->smartcard = TRUE;
+ /* parse the retrieved cert */
+ x509cert = malloc_thing(x509cert_t);
+ *x509cert = empty_x509cert;
+ x509cert->smartcard = TRUE;
- if (!parse_x509cert(blob, 0, x509cert))
- {
- plog("failed to load cert from smartcard, error in X.509 certificate");
- free_x509cert(x509cert);
- return FALSE;
- }
- cert->type = CERT_X509_SIGNATURE;
- cert->u.x509 = x509cert;
- return TRUE;
+ if (!parse_x509cert(blob, 0, x509cert))
+ {
+ plog("failed to load cert from smartcard, error in X.509 certificate");
+ free_x509cert(x509cert);
+ return FALSE;
+ }
+ cert->type = CERT_X509_SIGNATURE;
+ cert->u.x509 = x509cert;
+ return TRUE;
}
/*
@@ -522,96 +521,96 @@ scx_find_cert_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object
static void
scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
{
- CK_RV rv;
- CK_OBJECT_CLASS class = CKO_CERTIFICATE;
- CK_ATTRIBUTE attr[] = {{ CKA_CLASS, &class, sizeof(class) }};
-
- rv = pkcs11_functions->C_FindObjectsInit(session, attr, 1);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return;
- }
-
- for (;;)
- {
- CK_OBJECT_HANDLE object;
- CK_ULONG obj_count = 0;
- err_t ugh;
- time_t valid_until;
- smartcard_t *sc;
- x509cert_t *cert;
+ CK_RV rv;
+ CK_OBJECT_CLASS class = CKO_CERTIFICATE;
+ CK_ATTRIBUTE attr[] = {{ CKA_CLASS, &class, sizeof(class) }};
- rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
+ rv = pkcs11_functions->C_FindObjectsInit(session, attr, 1);
if (rv != CKR_OK)
{
- plog("error in C_FindObjects: %s"
- , enum_show(&pkcs11_return_names, rv));
- break;
- }
-
- /* no objects left */
- if (obj_count == 0)
- break;
-
- /* create and initialize a new smartcard object */
- sc = alloc_thing(smartcard_t, "smartcard");
- *sc = empty_sc;
- sc->any_slot = FALSE;
- sc->slot = slot;
-
- if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
- {
- scx_free(sc);
- continue;
+ plog("error in C_FindObjectsInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return;
}
- DBG(DBG_CONTROL,
- DBG_log("found cert in %s with id: %s, label: '%s'"
- , scx_print_slot(sc, ""), sc->id, sc->label)
- )
- /* check validity of certificate */
- cert = sc->last_cert.u.x509;
- valid_until = cert->notAfter;
- ugh = check_validity(cert, &valid_until);
- if (ugh != NULL)
- {
- plog(" %s", ugh);
- free_x509cert(cert);
- scx_free(sc);
- continue;
- }
- else
+ for (;;)
{
- DBG(DBG_CONTROL,
- DBG_log(" certificate is valid")
- )
+ CK_OBJECT_HANDLE object;
+ CK_ULONG obj_count = 0;
+ err_t ugh;
+ time_t valid_until;
+ smartcard_t *sc;
+ x509cert_t *cert;
+
+ rv = pkcs11_functions->C_FindObjects(session, &object, 1, &obj_count);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_FindObjects: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ break;
+ }
+
+ /* no objects left */
+ if (obj_count == 0)
+ break;
+
+ /* create and initialize a new smartcard object */
+ sc = malloc_thing(smartcard_t);
+ *sc = empty_sc;
+ sc->any_slot = FALSE;
+ sc->slot = slot;
+
+ if (!scx_find_cert_object(session, object, sc, &sc->last_cert))
+ {
+ scx_free(sc);
+ continue;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("found cert in %s with id: %s, label: '%s'"
+ , scx_print_slot(sc, ""), sc->id, sc->label)
+ )
+
+ /* check validity of certificate */
+ cert = sc->last_cert.u.x509;
+ valid_until = cert->notAfter;
+ ugh = check_validity(cert, &valid_until);
+ if (ugh != NULL)
+ {
+ plog(" %s", ugh);
+ free_x509cert(cert);
+ scx_free(sc);
+ continue;
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log(" certificate is valid")
+ )
+ }
+
+ sc = scx_add(sc);
+
+ /* put end entity and ca certificates into different chains */
+ if (cert->isCA)
+ {
+ sc->last_cert.u.x509 = add_authcert(cert, AUTH_CA);
+ }
+ else
+ {
+ add_x509_public_key(cert, valid_until, DAL_LOCAL);
+ sc->last_cert.u.x509 = add_x509cert(cert);
+ }
+
+ share_cert(sc->last_cert);
+ time(&sc->last_load);
}
- sc = scx_add(sc);
-
- /* put end entity and ca certificates into different chains */
- if (cert->isCA)
- {
- sc->last_cert.u.x509 = add_authcert(cert, AUTH_CA);
- }
- else
+ rv = pkcs11_functions->C_FindObjectsFinal(session);
+ if (rv != CKR_OK)
{
- add_x509_public_key(cert, valid_until, DAL_LOCAL);
- sc->last_cert.u.x509 = add_x509cert(cert);
+ plog("error in C_FindObjectsFinal: %s"
+ , enum_show(&pkcs11_return_names, rv));
}
-
- share_cert(sc->last_cert);
- time(&sc->last_load);
- }
-
- rv = pkcs11_functions->C_FindObjectsFinal(session);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsFinal: %s"
- , enum_show(&pkcs11_return_names, rv));
- }
}
/*
@@ -620,74 +619,74 @@ scx_find_cert_objects(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
static void
scx_find_all_cert_objects(void)
{
- CK_RV rv;
- CK_SLOT_ID_PTR slots = NULL_PTR;
- CK_ULONG slot_count = 0;
- CK_ULONG i;
-
- if (!scx_initialized)
- {
- plog("pkcs11 module not initialized");
- return;
- }
-
- /* read size, always returns CKR_OK ! */
- rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
-
- /* allocate memory for the slots */
- slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
-
- rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
- pfreeany(slots);
- return;
- }
-
- /* look in every slot for certificate objects */
- for (i = 0; i < slot_count; i++)
- {
- CK_SLOT_ID slot = slots[i];
- CK_SLOT_INFO info;
- CK_SESSION_HANDLE session;
-
- rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
+ CK_RV rv;
+ CK_SLOT_ID_PTR slots = NULL_PTR;
+ CK_ULONG slot_count = 0;
+ CK_ULONG i;
- if (rv != CKR_OK)
+ if (!scx_initialized)
{
- plog("error in C_GetSlotInfo: %s"
- , enum_show(&pkcs11_return_names, rv));
- continue;
- }
-
- if (!(info.flags & CKF_TOKEN_PRESENT))
- {
- plog("no token present in slot %lu", slot);
- continue;
+ plog("pkcs11 module not initialized");
+ return;
}
- rv = pkcs11_functions->C_OpenSession(slot
- , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
+ /* read size, always returns CKR_OK ! */
+ rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
+
+ /* allocate memory for the slots */
+ slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
+
+ rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
if (rv != CKR_OK)
{
- plog("failed to open a session on slot %lu: %s"
- , slot, enum_show(&pkcs11_return_names, rv));
- continue;
+ plog("error in C_GetSlotList: %s", enum_show(&pkcs11_return_names, rv));
+ free(slots);
+ return;
}
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
- )
- scx_find_cert_objects(slot, session);
- rv = pkcs11_functions->C_CloseSession(session);
- if (rv != CKR_OK)
+ /* look in every slot for certificate objects */
+ for (i = 0; i < slot_count; i++)
{
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
+ CK_SLOT_ID slot = slots[i];
+ CK_SLOT_INFO info;
+ CK_SESSION_HANDLE session;
+
+ rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
+
+ if (rv != CKR_OK)
+ {
+ plog("error in C_GetSlotInfo: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ continue;
+ }
+
+ if (!(info.flags & CKF_TOKEN_PRESENT))
+ {
+ plog("no token present in slot %lu", slot);
+ continue;
+ }
+
+ rv = pkcs11_functions->C_OpenSession(slot
+ , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
+ if (rv != CKR_OK)
+ {
+ plog("failed to open a session on slot %lu: %s"
+ , slot, enum_show(&pkcs11_return_names, rv));
+ continue;
+ }
+ DBG(DBG_CONTROLMORE,
+ DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
+ )
+ scx_find_cert_objects(slot, session);
+
+ rv = pkcs11_functions->C_CloseSession(session);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_CloseSession: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ }
}
- }
- pfreeany(slots);
+ free(slots);
}
#endif
@@ -701,52 +700,52 @@ void
scx_init(const char* module, const char *init_args)
{
#ifdef SMARTCARD
- CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
- CK_RV rv;
+ CK_C_INITIALIZE_ARGS args = { .pReserved = (char *)init_args, };
+ CK_RV rv;
- if (scx_initialized)
- {
- plog("weird - pkcs11 module seems already to be initialized");
- return;
- }
+ if (scx_initialized)
+ {
+ plog("weird - pkcs11 module seems already to be initialized");
+ return;
+ }
- if (module == NULL)
+ if (module == NULL)
#ifdef PKCS11_DEFAULT_LIB
- module = PKCS11_DEFAULT_LIB;
+ module = PKCS11_DEFAULT_LIB;
#else
- {
- plog("no pkcs11 module defined");
- return;
- }
+ {
+ plog("no pkcs11 module defined");
+ return;
+ }
#endif
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module '%s' loading...", module)
- )
- pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
- if (pkcs11_module == NULL)
- {
- plog("failed to load pkcs11 module '%s'", module);
- return;
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module initializing...")
- )
- rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
- if (rv != CKR_OK)
- {
- plog("failed to initialize pkcs11 module: %s"
- , enum_show(&pkcs11_return_names, rv));
- return;
- }
-
- scx_initialized = TRUE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module loaded and initialized")
- )
-
- scx_find_all_cert_objects();
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 module '%s' loading...", module)
+ )
+ pkcs11_module = scx_load_pkcs11_module(module, &pkcs11_functions);
+ if (pkcs11_module == NULL)
+ {
+ plog("failed to load pkcs11 module '%s'", module);
+ return;
+ }
+
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 module initializing...")
+ )
+ rv = pkcs11_functions->C_Initialize(init_args ? &args : NULL);
+ if (rv != CKR_OK)
+ {
+ plog("failed to initialize pkcs11 module: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return;
+ }
+
+ scx_initialized = TRUE;
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 module loaded and initialized")
+ )
+
+ scx_find_all_cert_objects();
#endif
}
@@ -757,27 +756,27 @@ void
scx_finalize(void)
{
#ifdef SMARTCARD
- while (smartcards != NULL)
- {
- scx_release(smartcards);
- }
-
- if (pkcs11_functions != NULL_PTR)
- {
- pkcs11_functions->C_Finalize(NULL_PTR);
- pkcs11_functions = NULL_PTR;
- }
-
- if (pkcs11_module != NULL)
- {
- scx_unload_pkcs11_module(pkcs11_module);
- pkcs11_module = NULL;
- }
-
- scx_initialized = FALSE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 module finalized and unloaded")
- )
+ while (smartcards != NULL)
+ {
+ scx_release(smartcards);
+ }
+
+ if (pkcs11_functions != NULL_PTR)
+ {
+ pkcs11_functions->C_Finalize(NULL_PTR);
+ pkcs11_functions = NULL_PTR;
+ }
+
+ if (pkcs11_module != NULL)
+ {
+ scx_unload_pkcs11_module(pkcs11_module);
+ pkcs11_module = NULL;
+ }
+
+ scx_initialized = FALSE;
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 module finalized and unloaded")
+ )
#endif
}
@@ -787,7 +786,7 @@ scx_finalize(void)
bool
scx_on_smartcard(const char *filename)
{
- return strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0;
+ return strneq(filename, SCX_TOKEN, strlen(SCX_TOKEN));
}
#ifdef SMARTCARD
@@ -795,55 +794,55 @@ scx_on_smartcard(const char *filename)
* find a specific object on the smartcard
*/
static bool
-scx_pkcs11_find_object( CK_SESSION_HANDLE session,
- CK_OBJECT_HANDLE_PTR object,
- CK_OBJECT_CLASS class,
- const char* id)
+scx_pkcs11_find_object( CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR object,
+ CK_OBJECT_CLASS class,
+ const char* id)
{
- size_t len;
- char buf[BUF_LEN];
- CK_RV rv;
- CK_ULONG obj_count = 0;
- CK_ULONG attr_count = 1;
-
- CK_ATTRIBUTE attr[] = {
- { CKA_CLASS, &class, sizeof(class) },
- { CKA_ID, &buf, 0L }
- };
-
- if (id != NULL)
- {
- ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
- attr[1].ulValueLen = len;
- attr_count = 2;
- }
-
- /* get info for certificate with id */
- rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
+ size_t len;
+ char buf[BUF_LEN];
+ CK_RV rv;
+ CK_ULONG obj_count = 0;
+ CK_ULONG attr_count = 1;
- rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjects: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
+ CK_ATTRIBUTE attr[] = {
+ { CKA_CLASS, &class, sizeof(class) },
+ { CKA_ID, &buf, 0L }
+ };
- rv = pkcs11_functions->C_FindObjectsFinal(session);
- if (rv != CKR_OK)
- {
- plog("error in C_FindObjectsFinal: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
+ if (id != NULL)
+ {
+ ttodata(id, strlen(id), 16, buf, BUF_LEN, &len);
+ attr[1].ulValueLen = len;
+ attr_count = 2;
+ }
+
+ /* get info for certificate with id */
+ rv = pkcs11_functions->C_FindObjectsInit(session, attr, attr_count);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_FindObjectsInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_FindObjects(session, object, 1, &obj_count);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_FindObjects: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
- return (obj_count != 0);
+ rv = pkcs11_functions->C_FindObjectsFinal(session);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_FindObjectsFinal: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ return (obj_count != 0);
}
/*
@@ -852,54 +851,54 @@ scx_pkcs11_find_object( CK_SESSION_HANDLE session,
static bool
scx_find_cert_id_in_slot(smartcard_t *sc, CK_SLOT_ID slot)
{
- CK_SESSION_HANDLE session;
- CK_OBJECT_HANDLE object;
- CK_SLOT_INFO info;
-
- CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
-
- if (rv != CKR_OK)
- {
- plog("error in C_GetSlotInfo: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- if (!(info.flags & CKF_TOKEN_PRESENT))
- {
- plog("no token present in slot %lu", slot);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_OpenSession(slot
- , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
- if (rv != CKR_OK)
- {
- plog("failed to open a session on slot %lu: %s"
- , slot, enum_show(&pkcs11_return_names, rv));
+ CK_SESSION_HANDLE session;
+ CK_OBJECT_HANDLE object;
+ CK_SLOT_INFO info;
+
+ CK_RV rv = pkcs11_functions->C_GetSlotInfo(slot, &info);
+
+ if (rv != CKR_OK)
+ {
+ plog("error in C_GetSlotInfo: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ if (!(info.flags & CKF_TOKEN_PRESENT))
+ {
+ plog("no token present in slot %lu", slot);
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_OpenSession(slot
+ , CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session);
+ if (rv != CKR_OK)
+ {
+ plog("failed to open a session on slot %lu: %s"
+ , slot, enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+ DBG(DBG_CONTROLMORE,
+ DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
+ )
+
+ /* check if there is a certificate on the card in the specified slot */
+ if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
+ {
+ sc->slot = slot;
+ sc->any_slot = FALSE;
+ sc->session = session;
+ sc->session_opened = TRUE;
+ return TRUE;
+ }
+
+ rv = pkcs11_functions->C_CloseSession(session);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_CloseSession: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ }
return FALSE;
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("pkcs11 session #%ld for searching slot %lu", session, slot)
- )
-
- /* check if there is a certificate on the card in the specified slot */
- if (scx_pkcs11_find_object(session, &object, CKO_CERTIFICATE, sc->id))
- {
- sc->slot = slot;
- sc->any_slot = FALSE;
- sc->session = session;
- sc->session_opened = TRUE;
- return TRUE;
- }
-
- rv = pkcs11_functions->C_CloseSession(session);
- if (rv != CKR_OK)
- {
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
- }
- return FALSE;
}
#endif
@@ -910,74 +909,74 @@ bool
scx_establish_context(smartcard_t *sc)
{
#ifdef SMARTCARD
- bool id_found = FALSE;
-
- if (!scx_initialized)
- {
- plog("pkcs11 module not initialized");
- return FALSE;
- }
+ bool id_found = FALSE;
- if (sc->session_opened)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld already open", sc->session)
- )
- return TRUE;
- }
-
- if (!sc->any_slot)
- id_found = scx_find_cert_id_in_slot(sc, sc->slot);
-
- if (!id_found)
- {
- CK_RV rv;
- CK_SLOT_ID slot;
- CK_SLOT_ID_PTR slots = NULL_PTR;
- CK_ULONG slot_count = 0;
- CK_ULONG i;
+ if (!scx_initialized)
+ {
+ plog("pkcs11 module not initialized");
+ return FALSE;
+ }
- /* read size, always returns CKR_OK ! */
- rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
+ if (sc->session_opened)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 session #%ld already open", sc->session)
+ )
+ return TRUE;
+ }
- /* allocate memory for the slots */
- slots = (CK_SLOT_ID *)alloc_bytes(slot_count * sizeof(CK_SLOT_ID), "slots");
+ if (!sc->any_slot)
+ id_found = scx_find_cert_id_in_slot(sc, sc->slot);
- rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
- if (rv != CKR_OK)
+ if (!id_found)
{
- plog("error in C_GetSlotList: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfreeany(slots);
- return FALSE;
- }
+ CK_RV rv;
+ CK_SLOT_ID slot;
+ CK_SLOT_ID_PTR slots = NULL_PTR;
+ CK_ULONG slot_count = 0;
+ CK_ULONG i;
+
+ /* read size, always returns CKR_OK ! */
+ rv = pkcs11_functions->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
+
+ /* allocate memory for the slots */
+ slots = (CK_SLOT_ID *)malloc(slot_count * sizeof(CK_SLOT_ID));
+
+ rv = pkcs11_functions->C_GetSlotList(FALSE, slots, &slot_count);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_GetSlotList: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ free(slots);
+ return FALSE;
+ }
+
+ /* look in every slot for a certificate with a given object ID */
+ for (i = 0; i < slot_count; i++)
+ {
+ slot = slots[i];
+ id_found = scx_find_cert_id_in_slot(sc, slot);
+ if (id_found)
+ break;
+ }
+ free(slots);
+ }
- /* look in every slot for a certificate with a given object ID */
- for (i = 0; i < slot_count; i++)
+ if (id_found)
{
- slot = slots[i];
- id_found = scx_find_cert_id_in_slot(sc, slot);
- if (id_found)
- break;
- }
- pfreeany(slots)
- }
-
- if (id_found)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
- DBG_log("pkcs11 session #%ld opened", sc->session)
- )
- }
- else
- {
- plog(" no certificate with id %s found on smartcard", sc->id);
- }
- return id_found;
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("found token with id %s in slot %lu", sc->id, sc->slot);
+ DBG_log("pkcs11 session #%ld opened", sc->session)
+ )
+ }
+ else
+ {
+ plog(" no certificate with id %s found on smartcard", sc->id);
+ }
+ return id_found;
#else
- plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
- return FALSE;
+ plog("warning: SMARTCARD support is deactivated in pluto/Makefile!");
+ return FALSE;
#endif
}
@@ -988,41 +987,41 @@ bool
scx_login(smartcard_t *sc)
{
#ifdef SMARTCARD
- CK_RV rv;
+ CK_RV rv;
+
+ if (sc->logged_in)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 session #%ld login already done", sc->session)
+ )
+ return TRUE;
+ }
+
+ if (sc->pin.ptr == NULL)
+ {
+ plog("unable to log in without PIN!");
+ return FALSE;
+ }
+
+ if (!sc->session_opened)
+ {
+ plog("session not opened");
+ return FALSE;
+ }
- if (sc->logged_in)
- {
+ rv = pkcs11_functions->C_Login(sc->session, CKU_USER
+ , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
+ if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
+ {
+ plog("unable to login: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld login already done", sc->session)
+ DBG_log("pkcs11 session #%ld login successful", sc->session)
)
+ sc->logged_in = TRUE;
return TRUE;
- }
-
- if (sc->pin.ptr == NULL)
- {
- plog("unable to log in without PIN!");
- return FALSE;
- }
-
- if (!sc->session_opened)
- {
- plog("session not opened");
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Login(sc->session, CKU_USER
- , (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
- if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
- {
- plog("unable to login: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld login successful", sc->session)
- )
- sc->logged_in = TRUE;
- return TRUE;
#else
return FALSE;
#endif
@@ -1035,17 +1034,17 @@ scx_login(smartcard_t *sc)
static void
scx_logout(smartcard_t *sc)
{
- CK_RV rv;
-
- rv = pkcs11_functions->C_Logout(sc->session);
- if (rv != CKR_OK)
- plog("error in C_Logout: %s"
- , enum_show(&pkcs11_return_names, rv));
- else
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld logout", sc->session)
- )
- sc->logged_in = FALSE;
+ CK_RV rv;
+
+ rv = pkcs11_functions->C_Logout(sc->session);
+ if (rv != CKR_OK)
+ plog("error in C_Logout: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ else
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 session #%ld logout", sc->session)
+ )
+ sc->logged_in = FALSE;
}
#endif
@@ -1057,27 +1056,27 @@ void
scx_release_context(smartcard_t *sc)
{
#ifdef SMARTCARD
- CK_RV rv;
-
- if (!scx_initialized)
- return;
+ CK_RV rv;
- if (sc->session_opened)
- {
- if (sc->logged_in)
- scx_logout(sc);
+ if (!scx_initialized)
+ return;
- sc->session_opened = FALSE;
-
- rv = pkcs11_functions->C_CloseSession(sc->session);
- if (rv != CKR_OK)
- plog("error in C_CloseSession: %s"
- , enum_show(&pkcs11_return_names, rv));
- else
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("pkcs11 session #%ld closed", sc->session)
- )
- }
+ if (sc->session_opened)
+ {
+ if (sc->logged_in)
+ scx_logout(sc);
+
+ sc->session_opened = FALSE;
+
+ rv = pkcs11_functions->C_CloseSession(sc->session);
+ if (rv != CKR_OK)
+ plog("error in C_CloseSession: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ else
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("pkcs11 session #%ld closed", sc->session)
+ )
+ }
#endif
}
@@ -1088,64 +1087,64 @@ bool
scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
, bool *cached)
{
-#ifdef SMARTCARD /* compile with smartcard support */
- CK_OBJECT_HANDLE object;
+#ifdef SMARTCARD /* compile with smartcard support */
+ CK_OBJECT_HANDLE object;
- const char *number_slot_id = filename + strlen(SCX_TOKEN);
+ const char *number_slot_id = filename + strlen(SCX_TOKEN);
- smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
+ smartcard_t *sc = scx_add(scx_parse_number_slot_id(number_slot_id));
- /* return the smartcard object */
- *scp = sc;
+ /* return the smartcard object */
+ *scp = sc;
- /* is there a cached smartcard certificate? */
- *cached = sc->last_cert.type != CERT_NONE
- && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
+ /* is there a cached smartcard certificate? */
+ *cached = sc->last_cert.type != CERT_NONE
+ && (time(NULL) - sc->last_load) < SCX_CERT_CACHE_INTERVAL;
- if (*cached)
- {
- *cert = sc->last_cert;
- plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
- , sc->number
- , scx_print_slot(sc, "")
- , sc->id
- , sc->label);
- return TRUE;
- }
+ if (*cached)
+ {
+ *cert = sc->last_cert;
+ plog(" using cached cert from smartcard #%d (%s, id: %s, label: '%s')"
+ , sc->number
+ , scx_print_slot(sc, "")
+ , sc->id
+ , sc->label);
+ return TRUE;
+ }
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
+ if (!scx_establish_context(sc))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- /* find the certificate object */
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
- {
- scx_release_context(sc);
- return FALSE;
- }
+ /* find the certificate object */
+ if (!scx_pkcs11_find_object(sc->session, &object, CKO_CERTIFICATE, sc->id))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- /* retrieve the certificate object */
- if (!scx_find_cert_object(sc->session, object, sc, cert))
- {
- scx_release_context(sc);
- return FALSE;
- }
+ /* retrieve the certificate object */
+ if (!scx_find_cert_object(sc->session, object, sc, cert))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
- plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
- , sc->number
- , scx_print_slot(sc, "")
- , sc->id
- , sc->label);
+ plog(" loaded cert from smartcard #%d (%s, id: %s, label: '%s')"
+ , sc->number
+ , scx_print_slot(sc, "")
+ , sc->id
+ , sc->label);
- return TRUE;
+ return TRUE;
#else
- plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
- return FALSE;
+ plog(" warning: SMARTCARD support is deactivated in pluto/Makefile!");
+ return FALSE;
#endif
}
@@ -1162,58 +1161,58 @@ scx_load_cert(const char *filename, smartcard_t **scp, cert_t *cert
smartcard_t*
scx_parse_number_slot_id(const char *number_slot_id)
{
- int len = strlen(number_slot_id);
- smartcard_t *sc = alloc_thing(smartcard_t, "smartcard");
-
- /* assign default values */
- *sc = empty_sc;
-
- if (len == 0) /* default: use certificate #1 */
- {
- sc->number = 1;
- }
- else if (*number_slot_id == '#') /* #number scheme */
- {
- err_t ugh;
- unsigned long ul;
-
- ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
- if (ugh == NULL)
- sc->number = (int)ul;
- else
- plog("error parsing smartcard number: %s", ugh);
- }
- else /* slot:id scheme */
- {
- int slot_len = len;
- char *p = strchr(number_slot_id, ':');
-
- if (p != NULL)
- {
- int id_len = len - (p + 1 - number_slot_id);
- slot_len -= (1 + id_len);
-
- if (id_len > 0) /* we have an id */
- sc->id = p + 1;
- }
- if (slot_len > 0) /* we have a slot */
- {
- err_t ugh = NULL;
- unsigned long ul;
-
- ugh = atoul(number_slot_id, slot_len, 10, &ul);
- if (ugh == NULL)
- {
- sc->slot = ul;
- sc->any_slot = FALSE;
- }
- else
- plog("error parsing smartcard slot number: %s", ugh);
- }
- }
- /* unshare the id string */
- sc->id = clone_str(sc->id, "key id");
- return sc;
+ int len = strlen(number_slot_id);
+ smartcard_t *sc = malloc_thing(smartcard_t);
+
+ /* assign default values */
+ *sc = empty_sc;
+
+ if (len == 0) /* default: use certificate #1 */
+ {
+ sc->number = 1;
+ }
+ else if (*number_slot_id == '#') /* #number scheme */
+ {
+ err_t ugh;
+ unsigned long ul;
+
+ ugh = atoul(number_slot_id+1, len-1 , 10, &ul);
+ if (ugh == NULL)
+ sc->number = (int)ul;
+ else
+ plog("error parsing smartcard number: %s", ugh);
+ }
+ else /* slot:id scheme */
+ {
+ int slot_len = len;
+ char *p = strchr(number_slot_id, ':');
+
+ if (p != NULL)
+ {
+ int id_len = len - (p + 1 - number_slot_id);
+ slot_len -= (1 + id_len);
+
+ if (id_len > 0) /* we have an id */
+ sc->id = p + 1;
+ }
+ if (slot_len > 0) /* we have a slot */
+ {
+ err_t ugh = NULL;
+ unsigned long ul;
+
+ ugh = atoul(number_slot_id, slot_len, 10, &ul);
+ if (ugh == NULL)
+ {
+ sc->slot = ul;
+ sc->any_slot = FALSE;
+ }
+ else
+ plog("error parsing smartcard slot number: %s", ugh);
+ }
+ }
+ /* unshare the id string */
+ sc->id = clone_str(sc->id);
+ return sc;
}
/*
@@ -1223,49 +1222,49 @@ bool
scx_verify_pin(smartcard_t *sc)
{
#ifdef SMARTCARD
- CK_RV rv;
-
- if (!sc->pinpad)
- sc->valid = FALSE;
+ CK_RV rv;
+
+ if (!sc->pinpad)
+ sc->valid = FALSE;
- if (sc->pin.ptr == NULL)
- {
- plog("unable to verify without PIN");
- return FALSE;
- }
+ if (sc->pin.ptr == NULL)
+ {
+ plog("unable to verify without PIN");
+ return FALSE;
+ }
- /* establish context */
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
+ /* establish context */
+ if (!scx_establish_context(sc))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
- (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
- if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
- {
- sc->valid = TRUE;
- sc->logged_in = TRUE;
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log((rv == CKR_OK)
- ? "PIN code correct"
- : "already logged in, no PIN entry required");
- DBG_log("pkcs11 session #%ld login successful", sc->session)
- )
- }
- else
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("PIN code incorrect")
- )
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
+ rv = pkcs11_functions->C_Login(sc->session, CKU_USER,
+ (CK_UTF8CHAR *) sc->pin.ptr, sc->pin.len);
+ if (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
+ {
+ sc->valid = TRUE;
+ sc->logged_in = TRUE;
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log((rv == CKR_OK)
+ ? "PIN code correct"
+ : "already logged in, no PIN entry required");
+ DBG_log("pkcs11 session #%ld login successful", sc->session)
+ )
+ }
+ else
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("PIN code incorrect")
+ )
+ }
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
#else
- sc->valid = FALSE;
+ sc->valid = FALSE;
#endif
- return sc->valid;
+ return sc->valid;
}
/*
@@ -1276,105 +1275,105 @@ scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t outlen)
{
#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG siglen = (CK_ULONG)outlen;
- CK_BBOOL sign_flag, decrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
- { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
- };
-
- if (!sc->logged_in)
- return FALSE;
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
+ CK_RV rv;
+ CK_OBJECT_HANDLE object;
+ CK_ULONG siglen = (CK_ULONG)outlen;
+ CK_BBOOL sign_flag, decrypt_flag;
+ CK_ATTRIBUTE attr[] = {
+ { CKA_SIGN, &sign_flag, sizeof(sign_flag) },
+ { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
+ };
+
+ if (!sc->logged_in)
+ return FALSE;
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
- if (rv != CKR_OK)
- {
- plog("couldn't read the private key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("RSA key flags: sign = %s, decrypt = %s"
- , (sign_flag)? "true":"false"
- , (decrypt_flag)? "true":"false")
- )
-
- if (sign_flag)
- {
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
- if (rv != CKR_OK)
+ if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
{
- plog("error in C_SignInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
+ plog("unable to find private key with id '%s'", sc->id);
+ return FALSE;
}
- rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
- , out, &siglen);
+ rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
if (rv != CKR_OK)
{
- plog("error in C_Sign: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- }
- else if (decrypt_flag)
- {
- CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
- size_t padlen;
- u_char *p = out ;
-
- /* PKCS#1 v1.5 8.1 encryption-block formatting */
- *p++ = 0x00;
- *p++ = 0x01; /* BT (block type) 01 */
- padlen = outlen - 3 - inlen;
- memset(p, 0xFF, padlen);
- p += padlen;
- *p++ = 0x00;
- memcpy(p, in, inlen);
+ plog("couldn't read the private key attributes: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("RSA key flags: sign = %s, decrypt = %s"
+ , (sign_flag)? "true":"false"
+ , (decrypt_flag)? "true":"false")
+ )
- rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
- if (rv != CKR_OK)
+ if (sign_flag)
{
- plog("error in C_DecryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
- , out, &siglen);
- if (rv != CKR_OK)
- {
- plog("error in C_Decrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
- }
- else
- {
- plog("private key has neither sign nor decrypt flag set");
- return FALSE;
- }
+ CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
+
+ rv = pkcs11_functions->C_SignInit(sc->session, &mech, object);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_SignInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_Sign(sc->session, (CK_BYTE_PTR)in, inlen
+ , out, &siglen);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_Sign: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+ }
+ else if (decrypt_flag)
+ {
+ CK_MECHANISM mech = { CKM_RSA_X_509, NULL_PTR, 0 };
+ size_t padlen;
+ u_char *p = out ;
+
+ /* PKCS#1 v1.5 8.1 encryption-block formatting */
+ *p++ = 0x00;
+ *p++ = 0x01; /* BT (block type) 01 */
+ padlen = outlen - 3 - inlen;
+ memset(p, 0xFF, padlen);
+ p += padlen;
+ *p++ = 0x00;
+ memcpy(p, in, inlen);
+
+ rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_DecryptInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_Decrypt(sc->session, out, outlen
+ , out, &siglen);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_Decrypt: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
+ }
+ else
+ {
+ plog("private key has neither sign nor decrypt flag set");
+ return FALSE;
+ }
- if (siglen > (CK_ULONG)outlen)
- {
- plog("signature length (%lu) larger than allocated buffer (%d)"
- , siglen, (int)outlen);
- return FALSE;
- }
- return TRUE;
+ if (siglen > (CK_ULONG)outlen)
+ {
+ plog("signature length (%lu) larger than allocated buffer (%d)"
+ , siglen, (int)outlen);
+ return FALSE;
+ }
+ return TRUE;
#else
- return FALSE;
+ return FALSE;
#endif
}
@@ -1386,132 +1385,146 @@ scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t *outlen)
{
#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG len = (CK_ULONG)(*outlen);
- CK_BBOOL encrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_MODULUS, NULL_PTR, 0L },
- { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
- { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
- };
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- if (!scx_establish_context(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
- {
- plog("unable to find public key with id '%s'", sc->id);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
- if (rv != CKR_OK)
- {
- plog("couldn't read the public key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
+ CK_RV rv;
+ CK_OBJECT_HANDLE object;
+ CK_ULONG len = (CK_ULONG)(*outlen);
+ CK_BBOOL encrypt_flag;
+ CK_ATTRIBUTE attr[] = {
+ { CKA_MODULUS, NULL_PTR, 0L },
+ { CKA_PUBLIC_EXPONENT, NULL_PTR, 0L },
+ { CKA_ENCRYPT, &encrypt_flag, sizeof(encrypt_flag) }
+ };
+ CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
+
+ if (!scx_establish_context(sc))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- if (!encrypt_flag)
- {
- plog("public key cannot be used for encryption");
- scx_release_context(sc);
- return FALSE;
- }
-
- /* there must be enough space left for the PKCS#1 v1.5 padding */
- if (inlen > attr[0].ulValueLen - 11)
- {
- plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
- , (int)inlen, attr[0].ulValueLen - 11);
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
-
- if (rv != CKR_OK)
- {
- if (rv == CKR_FUNCTION_NOT_SUPPORTED)
- {
- RSA_public_key_t rsa;
- chunk_t plain_text = {(u_char*)in, inlen};
- chunk_t cipher_text;
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA encryption in software")
- )
- attr[0].pValue = alloc_bytes(attr[0].ulValueLen, "modulus");
- attr[1].pValue = alloc_bytes(attr[1].ulValueLen, "exponent");
-
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
- if (rv != CKR_OK)
- {
- plog("couldn't read modulus and public exponent: %s"
- , enum_show(&pkcs11_return_names, rv));
- pfree(attr[0].pValue);
- pfree(attr[1].pValue);
+ if (!scx_pkcs11_find_object(sc->session, &object, CKO_PUBLIC_KEY, sc->id))
+ {
+ plog("unable to find public key with id '%s'", sc->id);
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 3);
+ if (rv != CKR_OK)
+ {
+ plog("couldn't read the public key attributes: %s"
+ , enum_show(&pkcs11_return_names, rv));
scx_release_context(sc);
return FALSE;
- }
- rsa.k = attr[0].ulValueLen;
- n_to_mpz(&rsa.n, attr[0].pValue, attr[0].ulValueLen);
- n_to_mpz(&rsa.e, attr[1].pValue, attr[1].ulValueLen);
- pfree(attr[0].pValue);
- pfree(attr[1].pValue);
-
- cipher_text = RSA_encrypt(&rsa, plain_text);
- free_RSA_public_content(&rsa);
- if (cipher_text.ptr == NULL)
- {
- plog("smartcard input data length is too large");
- if (!pkcs11_keep_state)
- scx_release_context(sc);
- return FALSE;
- }
-
- memcpy(out, cipher_text.ptr, cipher_text.len);
- *outlen = cipher_text.len;
- freeanychunk(cipher_text);
- if (!pkcs11_keep_state)
+ }
+
+ if (!encrypt_flag)
+ {
+ plog("public key cannot be used for encryption");
scx_release_context(sc);
- return TRUE;
+ return FALSE;
}
- else
+
+ /* there must be enough space left for the PKCS#1 v1.5 padding */
+ if (inlen > attr[0].ulValueLen - 11)
{
- plog("error in C_EncryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA encryption on smartcard")
- )
- rv = pkcs11_functions->C_Encrypt(sc->session, (u_char*)in, inlen
- , out, &len);
- if (rv != CKR_OK)
- {
- plog("error in C_Encrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
+ plog("smartcard input data length (%d) exceeds maximum of %lu bytes"
+ , (int)inlen, attr[0].ulValueLen - 11);
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_EncryptInit(sc->session, &mech, object);
+
+ if (rv != CKR_OK)
+ {
+ if (rv == CKR_FUNCTION_NOT_SUPPORTED)
+ {
+ public_key_t *key;
+ chunk_t rsa_modulus, rsa_exponent, rsa_key, cipher_text;
+ chunk_t plain_text = {(u_char*)in, inlen};
+
+ DBG(DBG_CONTROL,
+ DBG_log("doing RSA encryption in software")
+ )
+ attr[0].pValue = malloc(attr[0].ulValueLen);
+ attr[1].pValue = malloc(attr[1].ulValueLen);
+
+ rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 2);
+ if (rv != CKR_OK)
+ {
+ plog("couldn't read modulus and public exponent: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ free(attr[0].pValue);
+ free(attr[1].pValue);
+ scx_release_context(sc);
+ return FALSE;
+ }
+ rsa_modulus = chunk_create((u_char*) attr[0].pValue,
+ (size_t) attr[0].ulValueLen);
+ rsa_exponent = chunk_create((u_char*) attr[1].pValue,
+ (size_t) attr[1].ulValueLen);
+ rsa_key = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_integer("m", rsa_modulus),
+ asn1_integer("m", rsa_exponent));
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, rsa_key, BUILD_END);
+ free(rsa_key.ptr);
+ if (key == NULL)
+ {
+ return FALSE;
+ }
+ key->encrypt(key, plain_text, &cipher_text);
+ key->destroy(key);
+
+ if (cipher_text.ptr == NULL)
+ {
+ plog("smartcard input data length is too large");
+ if (!pkcs11_keep_state)
+ {
+ scx_release_context(sc);
+ }
+ return FALSE;
+ }
+
+ memcpy(out, cipher_text.ptr, cipher_text.len);
+ *outlen = cipher_text.len;
+ free(cipher_text.ptr);
+
+ if (!pkcs11_keep_state)
+ {
+ scx_release_context(sc);
+ }
+ return TRUE;
+ }
+ else
+ {
+ plog("error in C_EncryptInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ scx_release_context(sc);
+ return FALSE;
+ }
+ }
- *outlen = (size_t)len;
- return TRUE;
+ DBG(DBG_CONTROL,
+ DBG_log("doing RSA encryption on smartcard")
+ )
+ rv = pkcs11_functions->C_Encrypt(sc->session, (u_char*)in, inlen
+ , out, &len);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_Encrypt: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ scx_release_context(sc);
+ return FALSE;
+ }
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
+
+ *outlen = (size_t)len;
+ return TRUE;
#else
- return FALSE;
+ return FALSE;
#endif
}
/*
@@ -1522,70 +1535,70 @@ scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
, u_char *out, size_t *outlen)
{
#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ULONG len = (CK_ULONG)(*outlen);
- CK_BBOOL decrypt_flag;
- CK_ATTRIBUTE attr[] = {
- { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
- };
- CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
-
- if (!scx_establish_context(sc) || !scx_login(sc))
- {
- scx_release_context(sc);
- return FALSE;
- }
-
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
+ CK_RV rv;
+ CK_OBJECT_HANDLE object;
+ CK_ULONG len = (CK_ULONG)(*outlen);
+ CK_BBOOL decrypt_flag;
+ CK_ATTRIBUTE attr[] = {
+ { CKA_DECRYPT, &decrypt_flag, sizeof(decrypt_flag) }
+ };
+ CK_MECHANISM mech = { CKM_RSA_PKCS, NULL_PTR, 0 };
+
+ if (!scx_establish_context(sc) || !scx_login(sc))
+ {
+ scx_release_context(sc);
+ return FALSE;
+ }
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
- if (rv != CKR_OK)
- {
- plog("couldn't read the private key attributes: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
+ if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
+ {
+ plog("unable to find private key with id '%s'", sc->id);
+ return FALSE;
+ }
- if (!decrypt_flag)
- {
- plog("private key cannot be used for decryption");
- scx_release_context(sc);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("doing RSA decryption on smartcard")
- )
- rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
- if (rv != CKR_OK)
- {
- plog("error in C_DecryptInit: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
-
- rv = pkcs11_functions->C_Decrypt(sc->session, (u_char*)in, inlen
- , out, &len);
- if (rv != CKR_OK)
- {
- plog("error in C_Decrypt: %s"
- , enum_show(&pkcs11_return_names, rv));
- scx_release_context(sc);
- return FALSE;
- }
- if (!pkcs11_keep_state)
- scx_release_context(sc);
+ rv = pkcs11_functions->C_GetAttributeValue(sc->session, object, attr, 1);
+ if (rv != CKR_OK)
+ {
+ plog("couldn't read the private key attributes: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
- *outlen = (size_t)len;
- return TRUE;
+ if (!decrypt_flag)
+ {
+ plog("private key cannot be used for decryption");
+ scx_release_context(sc);
+ return FALSE;
+ }
+
+ DBG(DBG_CONTROL,
+ DBG_log("doing RSA decryption on smartcard")
+ )
+ rv = pkcs11_functions->C_DecryptInit(sc->session, &mech, object);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_DecryptInit: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ scx_release_context(sc);
+ return FALSE;
+ }
+
+ rv = pkcs11_functions->C_Decrypt(sc->session, (u_char*)in, inlen
+ , out, &len);
+ if (rv != CKR_OK)
+ {
+ plog("error in C_Decrypt: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ scx_release_context(sc);
+ return FALSE;
+ }
+ if (!pkcs11_keep_state)
+ scx_release_context(sc);
+
+ *outlen = (size_t)len;
+ return TRUE;
#else
- return FALSE;
+ return FALSE;
#endif
}
@@ -1597,92 +1610,92 @@ bool
scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
, const char* keyid, int whackfd)
{
- char inbuf[RSA_MAX_OCTETS];
- char outbuf[2*RSA_MAX_OCTETS + 1];
- size_t outlen = sizeof(inbuf);
- size_t inlen;
- smartcard_t *sc,*sc_new;
+ char inbuf[RSA_MAX_OCTETS];
+ char outbuf[2*RSA_MAX_OCTETS + 1];
+ size_t outlen = sizeof(inbuf);
+ size_t inlen;
+ smartcard_t *sc,*sc_new;
- const char *number_slot_id = "";
+ const char *number_slot_id = "";
- err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
+ err_t ugh = ttodata(msg, 0, inbase, inbuf, sizeof(inbuf), &inlen);
- /* no prefix - use default base */
- if (ugh != NULL && inbase == 0)
- ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
+ /* no prefix - use default base */
+ if (ugh != NULL && inbase == 0)
+ ugh = ttodata(msg, 0, DEFAULT_BASE, inbuf, sizeof(inbuf), &inlen);
- if (ugh != NULL)
- {
- plog("format error in smartcard input data: %s", ugh);
- return FALSE;
- }
-
- if (keyid != NULL)
- {
- number_slot_id = (strncmp(keyid, SCX_TOKEN, strlen(SCX_TOKEN)) == 0)
- ? keyid + strlen(SCX_TOKEN) : keyid;
- }
-
- sc_new = scx_parse_number_slot_id(number_slot_id);
- sc = scx_add(sc_new);
- if (sc == sc_new)
- scx_share(sc);
-
- DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
- DBG_dump("smartcard input data:\n", inbuf, inlen)
- )
-
- if (op == SC_OP_DECRYPT)
- {
- if (!sc->valid && whackfd != NULL_FD)
- scx_get_pin(sc, whackfd);
-
- if (!sc->valid)
- {
- loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
- return FALSE;
- }
- }
-
- DBG(DBG_CONTROL | DBG_CRYPT,
- DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
- , (int)sc->slot, sc->id)
- )
-
- switch (op)
- {
- case SC_OP_ENCRYPT:
- if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
- return FALSE;
- break;
- case SC_OP_DECRYPT:
- if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
- return FALSE;
- break;
- default:
- break;
- }
-
- DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
- DBG_dump("smartcard output data:\n", inbuf, outlen)
- )
-
- if (outbase == 0) /* use default base */
- outbase = DEFAULT_BASE;
-
- if (outbase == 256) /* ascii plain text */
- whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
- else
- {
- outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
- if (outlen == 0)
- {
- plog("error in output format conversion");
- return FALSE;
- }
- whack_log(RC_COMMENT, "%s", outbuf);
- }
- return TRUE;
+ if (ugh != NULL)
+ {
+ plog("format error in smartcard input data: %s", ugh);
+ return FALSE;
+ }
+
+ if (keyid != NULL)
+ {
+ number_slot_id = (strneq(keyid, SCX_TOKEN, strlen(SCX_TOKEN)))
+ ? keyid + strlen(SCX_TOKEN) : keyid;
+ }
+
+ sc_new = scx_parse_number_slot_id(number_slot_id);
+ sc = scx_add(sc_new);
+ if (sc == sc_new)
+ scx_share(sc);
+
+ DBG((op == SC_OP_ENCRYPT)? DBG_PRIVATE:DBG_RAW,
+ DBG_dump("smartcard input data:\n", inbuf, inlen)
+ )
+
+ if (op == SC_OP_DECRYPT)
+ {
+ if (!sc->valid && whackfd != NULL_FD)
+ scx_get_pin(sc, whackfd);
+
+ if (!sc->valid)
+ {
+ loglog(RC_NOVALIDPIN, "cannot decrypt without valid PIN");
+ return FALSE;
+ }
+ }
+
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ DBG_log("using RSA key from smartcard (slot: %d, id: %s)"
+ , (int)sc->slot, sc->id)
+ )
+
+ switch (op)
+ {
+ case SC_OP_ENCRYPT:
+ if (!scx_encrypt(sc, inbuf, inlen, inbuf, &outlen))
+ return FALSE;
+ break;
+ case SC_OP_DECRYPT:
+ if (!scx_decrypt(sc, inbuf, inlen, inbuf, &outlen))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+
+ DBG((op == SC_OP_DECRYPT)? DBG_PRIVATE:DBG_RAW,
+ DBG_dump("smartcard output data:\n", inbuf, outlen)
+ )
+
+ if (outbase == 0) /* use default base */
+ outbase = DEFAULT_BASE;
+
+ if (outbase == 256) /* ascii plain text */
+ whack_log(RC_COMMENT, "%.*s", (int)outlen, inbuf);
+ else
+ {
+ outlen = datatot(inbuf, outlen, outbase, outbuf, sizeof(outbuf));
+ if (outlen == 0)
+ {
+ plog("error in output format conversion");
+ return FALSE;
+ }
+ whack_log(RC_COMMENT, "%s", outbuf);
+ }
+ return TRUE;
}
/*
@@ -1692,32 +1705,32 @@ size_t
scx_get_keylength(smartcard_t *sc)
{
#ifdef SMARTCARD
- CK_RV rv;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
+ CK_RV rv;
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attr[] = {{ CKA_MODULUS, NULL_PTR, 0}};
- if (!sc->logged_in)
- return FALSE;
+ if (!sc->logged_in)
+ return FALSE;
- if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
- {
- plog("unable to find private key with id '%s'", sc->id);
- return FALSE;
- }
-
- /* get the length of the private key */
- rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
- , (CK_ATTRIBUTE_PTR)&attr, 1);
- if (rv != CKR_OK)
- {
- plog("failed to get key length: %s"
- , enum_show(&pkcs11_return_names, rv));
- return FALSE;
- }
+ if (!scx_pkcs11_find_object(sc->session, &object, CKO_PRIVATE_KEY, sc->id))
+ {
+ plog("unable to find private key with id '%s'", sc->id);
+ return FALSE;
+ }
+
+ /* get the length of the private key */
+ rv = pkcs11_functions->C_GetAttributeValue(sc->session, object
+ , (CK_ATTRIBUTE_PTR)&attr, 1);
+ if (rv != CKR_OK)
+ {
+ plog("failed to get key length: %s"
+ , enum_show(&pkcs11_return_names, rv));
+ return FALSE;
+ }
- return attr[0].ulValueLen; /*Return key length in bytes */
+ return attr[0].ulValueLen; /*Return key length in bytes */
#else
- return 0;
+ return 0;
#endif
}
@@ -1728,54 +1741,55 @@ bool
scx_get_pin(smartcard_t *sc, int whackfd)
{
#ifdef SMARTCARD
- char pin[BUF_LEN];
- int i, n;
+ char pin[BUF_LEN];
+ int i, n;
- whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
- , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
+ whack_log(RC_ENTERSECRET, "need PIN for #%d (%s, id: %s, label: '%s')"
+ , sc->number, scx_print_slot(sc, ""), sc->id, sc->label);
- for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
- {
- if (i > 0)
- whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
-
- n = read(whackfd, pin, BUF_LEN);
-
- if (n == -1)
+ for (i = 0; i < SCX_MAX_PIN_TRIALS; i++)
{
- whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
- return FALSE;
+ if (i > 0)
+ whack_log(RC_ENTERSECRET, "invalid PIN, please try again");
+
+ n = read(whackfd, pin, BUF_LEN);
+
+ if (n == -1)
+ {
+ whack_log(RC_LOG_SERIOUS, "read(whackfd) failed");
+ return FALSE;
+ }
+
+ if (strlen(pin) == 0)
+ {
+ whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
+ return FALSE;
+ }
+
+ sc->pin.ptr = pin;
+ sc->pin.len = strlen(pin);
+
+ /* verify the pin */
+ if (scx_verify_pin(sc))
+ {
+ sc->pin = chunk_create(pin, strlen(pin));
+ sc->pin = chunk_clone(sc->pin);
+ break;
+ }
+
+ /* wrong pin - we try another round */
+ sc->pin = chunk_empty;
}
- if (strlen(pin) == 0)
- {
- whack_log(RC_LOG_SERIOUS, "no PIN entered, aborted");
- return FALSE;
- }
-
- sc->pin.ptr = pin;
- sc->pin.len = strlen(pin);
-
- /* verify the pin */
- if (scx_verify_pin(sc))
- {
- clonetochunk(sc->pin, pin, strlen(pin), "pin");
- break;
- }
-
- /* wrong pin - we try another round */
- sc->pin = empty_chunk;
- }
-
- if (sc->valid)
- whack_log(RC_SUCCESS, "valid PIN");
- else
- whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
+ if (sc->valid)
+ whack_log(RC_SUCCESS, "valid PIN");
+ else
+ whack_log(RC_LOG_SERIOUS, "invalid PIN, too many trials");
#else
- sc->valid = FALSE;
- whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
+ sc->valid = FALSE;
+ whack_log(RC_LOG_SERIOUS, "SMARTCARD support is deactivated in pluto/Makefile!");
#endif
- return sc->valid;
+ return sc->valid;
}
@@ -1785,13 +1799,13 @@ scx_get_pin(smartcard_t *sc, int whackfd)
void
scx_free_pin(chunk_t *pin)
{
- if (pin->ptr != NULL)
- {
- /* clear pin field in memory */
- memset(pin->ptr, '\0', pin->len);
- pfree(pin->ptr);
- *pin = empty_chunk;
- }
+ if (pin->ptr != NULL)
+ {
+ /* clear pin field in memory */
+ memset(pin->ptr, '\0', pin->len);
+ free(pin->ptr);
+ *pin = chunk_empty;
+ }
}
/*
@@ -1800,14 +1814,14 @@ scx_free_pin(chunk_t *pin)
void
scx_free(smartcard_t *sc)
{
- if (sc != NULL)
- {
- scx_release_context(sc);
- pfreeany(sc->id);
- pfreeany(sc->label);
- scx_free_pin(&sc->pin);
- pfree(sc);
- }
+ if (sc != NULL)
+ {
+ scx_release_context(sc);
+ free(sc->id);
+ free(sc->label);
+ scx_free_pin(&sc->pin);
+ free(sc);
+ }
}
/* release of a smartcard record decreases the count by one
@@ -1816,15 +1830,15 @@ scx_free(smartcard_t *sc)
void
scx_release(smartcard_t *sc)
{
- if (sc != NULL && --sc->count == 0)
- {
- smartcard_t **pp = &smartcards;
- while (*pp != sc)
- pp = &(*pp)->next;
- *pp = sc->next;
- release_cert(sc->last_cert);
- scx_free(sc);
- }
+ if (sc != NULL && --sc->count == 0)
+ {
+ smartcard_t **pp = &smartcards;
+ while (*pp != sc)
+ pp = &(*pp)->next;
+ *pp = sc->next;
+ release_cert(sc->last_cert);
+ scx_free(sc);
+ }
}
/*
@@ -1833,17 +1847,17 @@ scx_release(smartcard_t *sc)
static bool
scx_same(smartcard_t *a, smartcard_t *b)
{
- if (a->number && b->number)
- {
- /* same number */
- return a->number == b->number;
- }
- else
- {
- /* same id and/or same slot */
- return (!a->id || (b->id && streq(a->id, b->id)))
- && (a->any_slot || b->any_slot || a->slot == b->slot);
- }
+ if (a->number && b->number)
+ {
+ /* same number */
+ return a->number == b->number;
+ }
+ else
+ {
+ /* same id and/or same slot */
+ return (!a->id || (b->id && streq(a->id, b->id)))
+ && (a->any_slot || b->any_slot || a->slot == b->slot);
+ }
}
/* for each link pointing to the smartcard record
@@ -1852,8 +1866,8 @@ scx_same(smartcard_t *a, smartcard_t *b)
void
scx_share(smartcard_t *sc)
{
- if (sc != NULL)
- sc->count++;
+ if (sc != NULL)
+ sc->count++;
}
/*
@@ -1862,28 +1876,28 @@ scx_share(smartcard_t *sc)
smartcard_t*
scx_add(smartcard_t *smartcard)
{
- smartcard_t *sc = smartcards;
- smartcard_t **psc = &smartcards;
-
- while (sc != NULL)
- {
- if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
- {
- scx_free(smartcard);
- return sc;
- }
- psc = &sc->next;
- sc = sc->next;
- }
-
- /* insert new smartcard record at the end of the chain */
- *psc = smartcard;
- smartcard->number = ++sc_number;
- smartcard->count = 1;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" smartcard #%d added", sc_number)
- )
- return smartcard;
+ smartcard_t *sc = smartcards;
+ smartcard_t **psc = &smartcards;
+
+ while (sc != NULL)
+ {
+ if (scx_same(smartcard, sc)) /* already in chain, free smartcard record */
+ {
+ scx_free(smartcard);
+ return sc;
+ }
+ psc = &sc->next;
+ sc = sc->next;
+ }
+
+ /* insert new smartcard record at the end of the chain */
+ *psc = smartcard;
+ smartcard->number = ++sc_number;
+ smartcard->count = 1;
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" smartcard #%d added", sc_number)
+ )
+ return smartcard;
}
/*
@@ -1892,15 +1906,15 @@ scx_add(smartcard_t *smartcard)
smartcard_t*
scx_get(x509cert_t *cert)
{
- smartcard_t *sc = smartcards;
-
- while (sc != NULL)
- {
- if (sc->last_cert.u.x509 == cert)
- return sc;
- sc = sc->next;
- }
- return NULL;
+ smartcard_t *sc = smartcards;
+
+ while (sc != NULL)
+ {
+ if (sc->last_cert.u.x509 == cert)
+ return sc;
+ sc = sc->next;
+ }
+ return NULL;
}
/*
@@ -1909,13 +1923,13 @@ scx_get(x509cert_t *cert)
char *
scx_print_slot(smartcard_t *sc, const char *whitespace)
{
- char *buf = temporary_cyclic_buffer();
+ char *buf = temporary_cyclic_buffer();
- if (sc->any_slot)
- snprintf(buf, BUF_LEN, "any slot");
- else
- snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
- return buf;
+ if (sc->any_slot)
+ snprintf(buf, BUF_LEN, "any slot");
+ else
+ snprintf(buf, BUF_LEN, "slot: %s%lu", whitespace, sc->slot);
+ return buf;
}
/*
@@ -1924,39 +1938,39 @@ scx_print_slot(smartcard_t *sc, const char *whitespace)
void
scx_list(bool utc)
{
- smartcard_t *sc = smartcards;
-
- if (sc != NULL)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of Smartcard Objects:");
- whack_log(RC_COMMENT, " ");
- }
-
- while (sc != NULL)
- {
- whack_log(RC_COMMENT, "%s, #%d, count: %d"
- , timetoa(&sc->last_load, utc)
- , sc->number
- , sc->count);
- whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
- , scx_print_slot(sc, " ")
- , sc->session_opened? "opened" : "closed"
- , sc->logged_in? "in" : "out"
- , sc->pinpad? "pin pad"
- : ((sc->pin.ptr == NULL)? "no pin"
- : sc->valid? "valid pin" : "invalid pin"));
- if (sc->id != NULL)
- whack_log(RC_COMMENT, " id: %s", sc->id);
- if (sc->label != NULL)
- whack_log(RC_COMMENT, " label: '%s'", sc->label);
- if (sc->last_cert.type == CERT_X509_SIGNATURE)
- {
- char buf[BUF_LEN];
-
- dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
- whack_log(RC_COMMENT, " subject: '%s'", buf);
- }
- sc = sc->next;
- }
+ smartcard_t *sc = smartcards;
+
+ if (sc != NULL)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of Smartcard Objects:");
+ whack_log(RC_COMMENT, " ");
+ }
+
+ while (sc != NULL)
+ {
+ whack_log(RC_COMMENT, "%T, #%d, count: %d"
+ , &sc->last_load, utc
+ , sc->number
+ , sc->count);
+ whack_log(RC_COMMENT, " %s, session %s, logged %s, has %s"
+ , scx_print_slot(sc, " ")
+ , sc->session_opened? "opened" : "closed"
+ , sc->logged_in? "in" : "out"
+ , sc->pinpad? "pin pad"
+ : ((sc->pin.ptr == NULL)? "no pin"
+ : sc->valid? "valid pin" : "invalid pin"));
+ if (sc->id != NULL)
+ whack_log(RC_COMMENT, " id: %s", sc->id);
+ if (sc->label != NULL)
+ whack_log(RC_COMMENT, " label: '%s'", sc->label);
+ if (sc->last_cert.type == CERT_X509_SIGNATURE)
+ {
+ char buf[BUF_LEN];
+
+ dntoa(buf, BUF_LEN, sc->last_cert.u.x509->subject);
+ whack_log(RC_COMMENT, " subject: '%s'", buf);
+ }
+ sc = sc->next;
+ }
}
diff --git a/src/pluto/smartcard.h b/src/pluto/smartcard.h
index 69510171c..60a0fccfc 100644
--- a/src/pluto/smartcard.h
+++ b/src/pluto/smartcard.h
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: smartcard.h 4709 2008-11-27 10:20:25Z martin $
*/
#ifndef _SMARTCARD_H
@@ -21,19 +19,19 @@
#include "certs.h"
-#define SCX_TOKEN "%smartcard"
-#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
-#define SCX_MAX_PIN_TRIALS 3
+#define SCX_TOKEN "%smartcard"
+#define SCX_CERT_CACHE_INTERVAL 60 /* seconds */
+#define SCX_MAX_PIN_TRIALS 3
/* smartcard operations, update copy in whack.h */
#ifndef SC_OP_T
#define SC_OP_T
typedef enum {
- SC_OP_NONE = 0,
- SC_OP_ENCRYPT = 1,
- SC_OP_DECRYPT = 2,
- SC_OP_SIGN = 3,
+ SC_OP_NONE = 0,
+ SC_OP_ENCRYPT = 1,
+ SC_OP_DECRYPT = 2,
+ SC_OP_SIGN = 3,
} sc_op_t;
#endif /* SC_OP_T */
@@ -42,21 +40,21 @@ typedef enum {
typedef struct smartcard smartcard_t;
struct smartcard {
- smartcard_t *next;
- time_t last_load;
- cert_t last_cert;
- int count;
- int number;
- unsigned long slot;
- char *id;
- char *label;
- chunk_t pin;
- bool pinpad;
- bool valid;
- bool session_opened;
- bool logged_in;
- bool any_slot;
- long session;
+ smartcard_t *next;
+ time_t last_load;
+ cert_t last_cert;
+ int count;
+ int number;
+ unsigned long slot;
+ char *id;
+ char *label;
+ chunk_t pin;
+ bool pinpad;
+ bool valid;
+ bool session_opened;
+ bool logged_in;
+ bool any_slot;
+ long session;
};
extern const smartcard_t empty_sc;
@@ -78,17 +76,17 @@ extern bool scx_establish_context(smartcard_t *sc);
extern bool scx_login(smartcard_t *sc);
extern bool scx_on_smartcard(const char *filename);
extern bool scx_load_cert(const char *filename, smartcard_t **scp
- , cert_t *cert, bool *cached);
+ , cert_t *cert, bool *cached);
extern bool scx_verify_pin(smartcard_t *sc);
extern void scx_share(smartcard_t *sc);
extern bool scx_sign_hash(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t outlen);
+ , u_char *out, size_t outlen);
extern bool scx_encrypt(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t *outlen);
+ , u_char *out, size_t *outlen);
extern bool scx_decrypt(smartcard_t *sc, const u_char *in, size_t inlen
- , u_char *out, size_t *outlen);
+ , u_char *out, size_t *outlen);
extern bool scx_op_via_whack(const char* msg, int inbase, int outbase
- , sc_op_t op, const char *keyid, int whackfd);
+ , sc_op_t op, const char *keyid, int whackfd);
extern bool scx_get_pin(smartcard_t *sc, int whackfd);
extern size_t scx_get_keylength(smartcard_t *sc);
extern smartcard_t* scx_add(smartcard_t *sc);
diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c
index 9d1bf8843..b8f4a3c23 100644
--- a/src/pluto/spdb.c
+++ b/src/pluto/spdb.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: spdb.c 3845 2008-04-18 17:00:30Z andreas $
*/
#include <stdio.h>
@@ -23,7 +21,6 @@
#include <sys/queue.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
#include "constants.h"
#include "defs.h"
@@ -36,16 +33,14 @@
#include "log.h"
#include "spdb.h"
#include "whack.h"
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "crypto.h"
#include "alg_info.h"
#include "kernel_alg.h"
#include "ike_alg.h"
#include "db_ops.h"
#include "nat_traversal.h"
-#define AD(x) x, elemsof(x) /* Array Description */
+#define AD(x) x, countof(x) /* Array Description */
#define AD_NULL NULL, 0
/**************** Oakely (main mode) SA database ****************/
@@ -53,7 +48,7 @@
/* array of proposals to be conjoined (can only be one for Oakley) */
static struct db_prop oakley_pc[] =
- { { PROTO_ISAKMP, AD_NULL } };
+ { { PROTO_ISAKMP, AD_NULL } };
/* array of proposal conjuncts (can only be one) */
@@ -67,131 +62,131 @@ struct db_sa oakley_sadb = { AD(oakley_props) };
/* arrays of attributes for transforms */
static struct db_attr espsha1_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
- };
+ { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
+ };
static struct db_attr ah_HMAC_SHA1_attr[] = {
- { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
- };
+ { AUTH_ALGORITHM, AUTH_ALGORITHM_HMAC_SHA1 },
+ };
/* arrays of transforms, each in in preference order */
static struct db_trans espa_trans[] = {
- { ESP_3DES, AD(espsha1_attr) },
- };
+ { ESP_3DES, AD(espsha1_attr) },
+ };
static struct db_trans esp_trans[] = {
- { ESP_3DES, AD_NULL },
- };
+ { ESP_3DES, AD_NULL },
+ };
#ifdef SUPPORT_ESP_NULL
static struct db_trans espnull_trans[] = {
- { ESP_NULL, AD(espsha1_attr) },
- };
+ { ESP_NULL, AD(espsha1_attr) },
+ };
#endif /* SUPPORT_ESP_NULL */
static struct db_trans ah_trans[] = {
- { AH_SHA, AD(ah_HMAC_SHA1_attr) },
- };
+ { AH_SHA, AD(ah_HMAC_SHA1_attr) },
+ };
static struct db_trans ipcomp_trans[] = {
- { IPCOMP_DEFLATE, AD_NULL },
- };
+ { IPCOMP_DEFLATE, AD_NULL },
+ };
/* arrays of proposals to be conjoined */
static struct db_prop ah_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- };
+ { PROTO_IPSEC_AH, AD(ah_trans) },
+ };
#ifdef SUPPORT_ESP_NULL
static struct db_prop espnull_pc[] = {
- { PROTO_IPSEC_ESP, AD(espnull_trans) },
- };
+ { PROTO_IPSEC_ESP, AD(espnull_trans) },
+ };
#endif /* SUPPORT_ESP_NULL */
static struct db_prop esp_pc[] = {
- { PROTO_IPSEC_ESP, AD(espa_trans) },
- };
+ { PROTO_IPSEC_ESP, AD(espa_trans) },
+ };
static struct db_prop ah_esp_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPSEC_ESP, AD(esp_trans) },
- };
+ { PROTO_IPSEC_AH, AD(ah_trans) },
+ { PROTO_IPSEC_ESP, AD(esp_trans) },
+ };
static struct db_prop compress_pc[] = {
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
+ { PROTO_IPCOMP, AD(ipcomp_trans) },
+ };
static struct db_prop ah_compress_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
+ { PROTO_IPSEC_AH, AD(ah_trans) },
+ { PROTO_IPCOMP, AD(ipcomp_trans) },
+ };
#ifdef SUPPORT_ESP_NULL
static struct db_prop espnull_compress_pc[] = {
- { PROTO_IPSEC_ESP, AD(espnull_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
+ { PROTO_IPSEC_ESP, AD(espnull_trans) },
+ { PROTO_IPCOMP, AD(ipcomp_trans) },
+ };
#endif /* SUPPORT_ESP_NULL */
static struct db_prop esp_compress_pc[] = {
- { PROTO_IPSEC_ESP, AD(espa_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
+ { PROTO_IPSEC_ESP, AD(espa_trans) },
+ { PROTO_IPCOMP, AD(ipcomp_trans) },
+ };
static struct db_prop ah_esp_compress_pc[] = {
- { PROTO_IPSEC_AH, AD(ah_trans) },
- { PROTO_IPSEC_ESP, AD(esp_trans) },
- { PROTO_IPCOMP, AD(ipcomp_trans) },
- };
+ { PROTO_IPSEC_AH, AD(ah_trans) },
+ { PROTO_IPSEC_ESP, AD(esp_trans) },
+ { PROTO_IPCOMP, AD(ipcomp_trans) },
+ };
/* arrays of proposal alternatives (each element is a conjunction) */
static struct db_prop_conj ah_props[] = {
- { AD(ah_pc) },
+ { AD(ah_pc) },
#ifdef SUPPORT_ESP_NULL
- { AD(espnull_pc) }
+ { AD(espnull_pc) }
#endif
- };
+ };
static struct db_prop_conj esp_props[] =
- { { AD(esp_pc) } };
+ { { AD(esp_pc) } };
static struct db_prop_conj ah_esp_props[] =
- { { AD(ah_esp_pc) } };
+ { { AD(ah_esp_pc) } };
static struct db_prop_conj compress_props[] = {
- { AD(compress_pc) },
- };
+ { AD(compress_pc) },
+ };
static struct db_prop_conj ah_compress_props[] = {
- { AD(ah_compress_pc) },
+ { AD(ah_compress_pc) },
#ifdef SUPPORT_ESP_NULL
- { AD(espnull_compress_pc) }
+ { AD(espnull_compress_pc) }
#endif
- };
+ };
static struct db_prop_conj esp_compress_props[] =
- { { AD(esp_compress_pc) } };
+ { { AD(esp_compress_pc) } };
static struct db_prop_conj ah_esp_compress_props[] =
- { { AD(ah_esp_compress_pc) } };
+ { { AD(ah_esp_compress_pc) } };
/* The IPsec sadb is subscripted by a bitset (subset of policy)
* with members from { POLICY_ENCRYPT, POLICY_AUTHENTICATE, POLICY_COMPRESS }
* shifted right by POLICY_IPSEC_SHIFT.
*/
struct db_sa ipsec_sadb[1 << 3] = {
- { AD_NULL }, /* none */
- { AD(esp_props) }, /* POLICY_ENCRYPT */
- { AD(ah_props) }, /* POLICY_AUTHENTICATE */
- { AD(ah_esp_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE */
- { AD(compress_props) }, /* POLICY_COMPRESS */
- { AD(esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_COMPRESS */
- { AD(ah_compress_props) }, /* POLICY_AUTHENTICATE+POLICY_COMPRESS */
- { AD(ah_esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE+POLICY_COMPRESS */
- };
+ { AD_NULL }, /* none */
+ { AD(esp_props) }, /* POLICY_ENCRYPT */
+ { AD(ah_props) }, /* POLICY_AUTHENTICATE */
+ { AD(ah_esp_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE */
+ { AD(compress_props) }, /* POLICY_COMPRESS */
+ { AD(esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_COMPRESS */
+ { AD(ah_compress_props) }, /* POLICY_AUTHENTICATE+POLICY_COMPRESS */
+ { AD(ah_esp_compress_props) }, /* POLICY_ENCRYPT+POLICY_AUTHENTICATE+POLICY_COMPRESS */
+ };
#undef AD
#undef AD_NULL
@@ -204,41 +199,41 @@ out_attr(int type
, enum_names **attr_val_descs USED_BY_DEBUG
, pb_stream *pbs)
{
- struct isakmp_attribute attr;
-
- if (val >> 16 == 0)
- {
- /* short value: use TV form */
- attr.isaat_af_type = type | ISAKMP_ATTR_AF_TV;
- attr.isaat_lv = val;
- if (!out_struct(&attr, attr_desc, pbs, NULL))
- return FALSE;
- }
- else
- {
- /* This is a real fudge! Since we rarely use long attributes
- * and since this is the only place where we can cause an
- * ISAKMP message length to be other than a multiple of 4 octets,
- * we force the length of the value to be a multiple of 4 octets.
- * Furthermore, we only handle values up to 4 octets in length.
- * Voila: a fixed format!
- */
- pb_stream val_pbs;
- u_int32_t nval = htonl(val);
-
- attr.isaat_af_type = type | ISAKMP_ATTR_AF_TLV;
- if (!out_struct(&attr, attr_desc, pbs, &val_pbs)
- || !out_raw(&nval, sizeof(nval), &val_pbs, "long attribute value"))
- return FALSE;
- close_output_pbs(&val_pbs);
- }
- DBG(DBG_EMITTING,
- enum_names *d = attr_val_descs[type];
-
- if (d != NULL)
- DBG_log(" [%lu is %s]"
- , val, enum_show(d, val)));
- return TRUE;
+ struct isakmp_attribute attr;
+
+ if (val >> 16 == 0)
+ {
+ /* short value: use TV form */
+ attr.isaat_af_type = type | ISAKMP_ATTR_AF_TV;
+ attr.isaat_lv = val;
+ if (!out_struct(&attr, attr_desc, pbs, NULL))
+ return FALSE;
+ }
+ else
+ {
+ /* This is a real fudge! Since we rarely use long attributes
+ * and since this is the only place where we can cause an
+ * ISAKMP message length to be other than a multiple of 4 octets,
+ * we force the length of the value to be a multiple of 4 octets.
+ * Furthermore, we only handle values up to 4 octets in length.
+ * Voila: a fixed format!
+ */
+ pb_stream val_pbs;
+ u_int32_t nval = htonl(val);
+
+ attr.isaat_af_type = type | ISAKMP_ATTR_AF_TLV;
+ if (!out_struct(&attr, attr_desc, pbs, &val_pbs)
+ || !out_raw(&nval, sizeof(nval), &val_pbs, "long attribute value"))
+ return FALSE;
+ close_output_pbs(&val_pbs);
+ }
+ DBG(DBG_EMITTING,
+ enum_names *d = attr_val_descs[type];
+
+ if (d != NULL)
+ DBG_log(" [%lu is %s]"
+ , val, enum_show(d, val)));
+ return TRUE;
}
#define return_on(var, val) do { var=val;goto return_out; } while(0);
/* Output an SA, as described by a db_sa.
@@ -251,336 +246,336 @@ out_sa(pb_stream *outs
, bool oakley_mode
, u_int8_t np)
{
- pb_stream sa_pbs;
- int pcn;
- bool ret = FALSE;
- bool ah_spi_generated = FALSE
- , esp_spi_generated = FALSE
- , ipcomp_cpi_generated = FALSE;
+ pb_stream sa_pbs;
+ int pcn;
+ bool ret = FALSE;
+ bool ah_spi_generated = FALSE
+ , esp_spi_generated = FALSE
+ , ipcomp_cpi_generated = FALSE;
#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
- struct db_context *db_ctx = NULL;
+ struct db_context *db_ctx = NULL;
#endif
- /* SA header out */
- {
- struct isakmp_sa sa;
-
- sa.isasa_np = np;
- st->st_doi = sa.isasa_doi = ISAKMP_DOI_IPSEC; /* all we know */
- if (!out_struct(&sa, &isakmp_sa_desc, outs, &sa_pbs))
- return_on(ret, FALSE);
- }
-
- /* within SA: situation out */
- st->st_situation = SIT_IDENTITY_ONLY;
- if (!out_struct(&st->st_situation, &ipsec_sit_desc, &sa_pbs, NULL))
- return_on(ret, FALSE);
-
- /* within SA: Proposal Payloads
- *
- * Multiple Proposals with the same number are simultaneous
- * (conjuncts) and must deal with different protocols (AH or ESP).
- * Proposals with different numbers are alternatives (disjuncts),
- * in preference order.
- * Proposal numbers must be monotonic.
- * See RFC 2408 "ISAKMP" 4.2
- */
-
- for (pcn = 0; pcn != sadb->prop_conj_cnt; pcn++)
- {
- struct db_prop_conj *pc = &sadb->prop_conjs[pcn];
- int pn;
-
- for (pn = 0; pn != pc->prop_cnt; pn++)
+ /* SA header out */
{
- struct db_prop *p = &pc->props[pn];
- pb_stream proposal_pbs;
- struct isakmp_proposal proposal;
- struct_desc *trans_desc = NULL;
- struct_desc *attr_desc = NULL;
- enum_names **attr_val_descs = NULL;
- int tn;
- bool tunnel_mode;
-
- tunnel_mode = (pn == pc->prop_cnt-1)
- && (st->st_policy & POLICY_TUNNEL);
-
- /* Proposal header */
- proposal.isap_np = pcn == sadb->prop_conj_cnt-1 && pn == pc->prop_cnt-1
- ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_P;
- proposal.isap_proposal = pcn;
- proposal.isap_protoid = p->protoid;
- proposal.isap_spisize = oakley_mode ? 0
- : p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE
- : IPSEC_DOI_SPI_SIZE;
-
- /* In quick mode ONLY, create proposal for runtime kernel algos.
- * Replace ESP proposals with runtime created one
- */
- if (!oakley_mode && p->protoid == PROTO_IPSEC_ESP)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- if (st->st_connection->alg_info_esp)
- {
- static char buf[256]="";
-
- alg_info_snprint(buf, sizeof (buf),
- (struct alg_info *)st->st_connection->alg_info_esp);
- DBG_log(buf);
- }
- )
- db_ctx = kernel_alg_db_new(st->st_connection->alg_info_esp, st->st_policy);
- p = db_prop_get(db_ctx);
-
- if (!p || p->trans_cnt == 0)
- {
- loglog(RC_LOG_SERIOUS,
- "empty IPSEC SA proposal to send "
- "(no kernel algorithms for esp selection)");
- return_on(ret, FALSE);
- }
- }
-
- if (oakley_mode && p->protoid == PROTO_ISAKMP)
- {
- DBG(DBG_CONTROL | DBG_CRYPT,
- if (st->st_connection->alg_info_ike)
- {
- static char buf[256]="";
-
- alg_info_snprint(buf, sizeof (buf),
- (struct alg_info *)st->st_connection->alg_info_ike);
- DBG_log(buf);
- }
- )
- db_ctx = ike_alg_db_new(st->st_connection->alg_info_ike, st->st_policy);
- p = db_prop_get(db_ctx);
-
- if (!p || p->trans_cnt == 0)
- {
- loglog(RC_LOG_SERIOUS,
- "empty ISAKMP SA proposal to send "
- "(no algorithms for ike selection?)");
- return_on(ret, FALSE);
- }
- }
-
- proposal.isap_notrans = p->trans_cnt;
- if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs))
- return_on(ret, FALSE);
+ struct isakmp_sa sa;
- /* Per-protocols stuff:
- * Set trans_desc.
- * Set attr_desc.
- * Set attr_val_descs.
- * If not oakley_mode, emit SPI.
- * We allocate SPIs on demand.
- * All ESPs in an SA will share a single SPI.
- * All AHs in an SAwill share a single SPI.
- * AHs' SPI will be distinct from ESPs'.
- * This latter is needed because KLIPS doesn't
- * use the protocol when looking up a (dest, protocol, spi).
- * ??? If multiple ESPs are composed, how should their SPIs
- * be allocated?
- */
- {
- ipsec_spi_t *spi_ptr = NULL;
- int proto = 0;
- bool *spi_generated = NULL;
-
- switch (p->protoid)
- {
- case PROTO_ISAKMP:
- passert(oakley_mode);
- trans_desc = &isakmp_isakmp_transform_desc;
- attr_desc = &isakmp_oakley_attribute_desc;
- attr_val_descs = oakley_attr_val_descs;
- /* no SPI needed */
- break;
- case PROTO_IPSEC_AH:
- passert(!oakley_mode);
- trans_desc = &isakmp_ah_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
- spi_ptr = &st->st_ah.our_spi;
- spi_generated = &ah_spi_generated;
- proto = IPPROTO_AH;
- break;
- case PROTO_IPSEC_ESP:
- passert(!oakley_mode);
- trans_desc = &isakmp_esp_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
- spi_ptr = &st->st_esp.our_spi;
- spi_generated = &esp_spi_generated;
- proto = IPPROTO_ESP;
- break;
- case PROTO_IPCOMP:
- passert(!oakley_mode);
- trans_desc = &isakmp_ipcomp_transform_desc;
- attr_desc = &isakmp_ipsec_attribute_desc;
- attr_val_descs = ipsec_attr_val_descs;
-
- /* a CPI isn't quite the same as an SPI
- * so we use specialized code to emit it.
- */
- if (!ipcomp_cpi_generated)
- {
- st->st_ipcomp.our_spi = get_my_cpi(
- &st->st_connection->spd, tunnel_mode);
- if (st->st_ipcomp.our_spi == 0)
- return_on(ret, FALSE); /* problem generating CPI */
-
- ipcomp_cpi_generated = TRUE;
- }
- /* CPI is stored in network low order end of an
- * ipsec_spi_t. So we start a couple of bytes in.
- */
- if (!out_raw((u_char *)&st->st_ipcomp.our_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE
- , &proposal_pbs, "CPI"))
- return_on(ret, FALSE);
- break;
- default:
- bad_case(p->protoid);
- }
- if (spi_ptr != NULL)
- {
- if (!*spi_generated)
- {
- *spi_ptr = get_ipsec_spi(0
- , proto
- , &st->st_connection->spd
- , tunnel_mode);
- if (*spi_ptr == 0)
- return FALSE;
- *spi_generated = TRUE;
- }
- if (!out_raw((u_char *)spi_ptr, IPSEC_DOI_SPI_SIZE
- , &proposal_pbs, "SPI"))
+ sa.isasa_np = np;
+ st->st_doi = sa.isasa_doi = ISAKMP_DOI_IPSEC; /* all we know */
+ if (!out_struct(&sa, &isakmp_sa_desc, outs, &sa_pbs))
return_on(ret, FALSE);
- }
- }
+ }
- /* within proposal: Transform Payloads */
- for (tn = 0; tn != p->trans_cnt; tn++)
- {
- struct db_trans *t = &p->trans[tn];
- pb_stream trans_pbs;
- struct isakmp_transform trans;
- int an;
+ /* within SA: situation out */
+ st->st_situation = SIT_IDENTITY_ONLY;
+ if (!out_struct(&st->st_situation, &ipsec_sit_desc, &sa_pbs, NULL))
+ return_on(ret, FALSE);
- trans.isat_np = (tn == p->trans_cnt - 1)
- ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_T;
- trans.isat_transnum = tn;
- trans.isat_transid = t->transid;
- if (!out_struct(&trans, trans_desc, &proposal_pbs, &trans_pbs))
- return_on(ret, FALSE);
+ /* within SA: Proposal Payloads
+ *
+ * Multiple Proposals with the same number are simultaneous
+ * (conjuncts) and must deal with different protocols (AH or ESP).
+ * Proposals with different numbers are alternatives (disjuncts),
+ * in preference order.
+ * Proposal numbers must be monotonic.
+ * See RFC 2408 "ISAKMP" 4.2
+ */
- /* Within tranform: Attributes. */
+ for (pcn = 0; pcn != sadb->prop_conj_cnt; pcn++)
+ {
+ struct db_prop_conj *pc = &sadb->prop_conjs[pcn];
+ int pn;
- /* For Phase 2 / Quick Mode, GROUP_DESCRIPTION is
- * automatically generated because it must be the same
- * in every transform. Except IPCOMP.
- */
- if (p->protoid != PROTO_IPCOMP
- && st->st_pfs_group != NULL)
+ for (pn = 0; pn != pc->prop_cnt; pn++)
{
- passert(!oakley_mode);
- passert(st->st_pfs_group != &unset_group);
- out_attr(GROUP_DESCRIPTION, st->st_pfs_group->group
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
+ struct db_prop *p = &pc->props[pn];
+ pb_stream proposal_pbs;
+ struct isakmp_proposal proposal;
+ struct_desc *trans_desc = NULL;
+ struct_desc *attr_desc = NULL;
+ enum_names **attr_val_descs = NULL;
+ int tn;
+ bool tunnel_mode;
+
+ tunnel_mode = (pn == pc->prop_cnt-1)
+ && (st->st_policy & POLICY_TUNNEL);
+
+ /* Proposal header */
+ proposal.isap_np = pcn == sadb->prop_conj_cnt-1 && pn == pc->prop_cnt-1
+ ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_P;
+ proposal.isap_proposal = pcn;
+ proposal.isap_protoid = p->protoid;
+ proposal.isap_spisize = oakley_mode ? 0
+ : p->protoid == PROTO_IPCOMP ? IPCOMP_CPI_SIZE
+ : IPSEC_DOI_SPI_SIZE;
+
+ /* In quick mode ONLY, create proposal for runtime kernel algos.
+ * Replace ESP proposals with runtime created one
+ */
+ if (!oakley_mode && p->protoid == PROTO_IPSEC_ESP)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ if (st->st_connection->alg_info_esp)
+ {
+ static char buf[BUF_LEN]="";
+
+ alg_info_snprint(buf, sizeof (buf),
+ (struct alg_info *)st->st_connection->alg_info_esp);
+ DBG_log("esp proposal: %s", buf);
+ }
+ )
+ db_ctx = kernel_alg_db_new(st->st_connection->alg_info_esp, st->st_policy);
+ p = db_prop_get(db_ctx);
+
+ if (!p || p->trans_cnt == 0)
+ {
+ loglog(RC_LOG_SERIOUS,
+ "empty IPSEC SA proposal to send "
+ "(no kernel algorithms for esp selection)");
+ return_on(ret, FALSE);
+ }
+ }
- /* automatically generate duration
- * and, for Phase 2 / Quick Mode, encapsulation.
- */
- if (oakley_mode)
- {
- out_attr(OAKLEY_LIFE_TYPE, OAKLEY_LIFE_SECONDS
- , attr_desc, attr_val_descs
- , &trans_pbs);
- out_attr(OAKLEY_LIFE_DURATION
- , st->st_connection->sa_ike_life_seconds
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
- else
- {
- /* RFC 2407 (IPSEC DOI) 4.5 specifies that
- * the default is "unspecified (host-dependent)".
- * This makes little sense, so we always specify it.
- *
- * Unlike other IPSEC transforms, IPCOMP defaults
- * to Transport Mode, so we can exploit the default
- * (draft-shacham-ippcp-rfc2393bis-05.txt 4.1).
- */
- if (p->protoid != PROTO_IPCOMP
- || st->st_policy & POLICY_TUNNEL)
- {
-#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- if ((st->nat_traversal & NAT_T_DETECTED)
- && !(st->st_policy & POLICY_TUNNEL))
+ if (oakley_mode && p->protoid == PROTO_ISAKMP)
{
- /* Inform user that we will not respect policy and only
- * propose Tunnel Mode
- */
- loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
- "Transport Mode not allowed due to security concerns -- "
- "using Tunnel mode");
+ DBG(DBG_CONTROL | DBG_CRYPT,
+ if (st->st_connection->alg_info_ike)
+ {
+ static char buf[BUF_LEN]="";
+
+ alg_info_snprint(buf, sizeof (buf),
+ (struct alg_info *)st->st_connection->alg_info_ike);
+ DBG_log("ike proposal: %s", buf);
+ }
+ )
+ db_ctx = ike_alg_db_new(st->st_connection, st->st_policy);
+ p = db_prop_get(db_ctx);
+
+ if (!p || p->trans_cnt == 0)
+ {
+ loglog(RC_LOG_SERIOUS,
+ "empty ISAKMP SA proposal to send "
+ "(no algorithms for ike selection?)");
+ return_on(ret, FALSE);
+ }
}
+
+ proposal.isap_notrans = p->trans_cnt;
+ if (!out_struct(&proposal, &isakmp_proposal_desc, &sa_pbs, &proposal_pbs))
+ return_on(ret, FALSE);
+
+ /* Per-protocols stuff:
+ * Set trans_desc.
+ * Set attr_desc.
+ * Set attr_val_descs.
+ * If not oakley_mode, emit SPI.
+ * We allocate SPIs on demand.
+ * All ESPs in an SA will share a single SPI.
+ * All AHs in an SAwill share a single SPI.
+ * AHs' SPI will be distinct from ESPs'.
+ * This latter is needed because KLIPS doesn't
+ * use the protocol when looking up a (dest, protocol, spi).
+ * ??? If multiple ESPs are composed, how should their SPIs
+ * be allocated?
+ */
+ {
+ ipsec_spi_t *spi_ptr = NULL;
+ int proto = 0;
+ bool *spi_generated = NULL;
+
+ switch (p->protoid)
+ {
+ case PROTO_ISAKMP:
+ passert(oakley_mode);
+ trans_desc = &isakmp_isakmp_transform_desc;
+ attr_desc = &isakmp_oakley_attribute_desc;
+ attr_val_descs = oakley_attr_val_descs;
+ /* no SPI needed */
+ break;
+ case PROTO_IPSEC_AH:
+ passert(!oakley_mode);
+ trans_desc = &isakmp_ah_transform_desc;
+ attr_desc = &isakmp_ipsec_attribute_desc;
+ attr_val_descs = ipsec_attr_val_descs;
+ spi_ptr = &st->st_ah.our_spi;
+ spi_generated = &ah_spi_generated;
+ proto = IPPROTO_AH;
+ break;
+ case PROTO_IPSEC_ESP:
+ passert(!oakley_mode);
+ trans_desc = &isakmp_esp_transform_desc;
+ attr_desc = &isakmp_ipsec_attribute_desc;
+ attr_val_descs = ipsec_attr_val_descs;
+ spi_ptr = &st->st_esp.our_spi;
+ spi_generated = &esp_spi_generated;
+ proto = IPPROTO_ESP;
+ break;
+ case PROTO_IPCOMP:
+ passert(!oakley_mode);
+ trans_desc = &isakmp_ipcomp_transform_desc;
+ attr_desc = &isakmp_ipsec_attribute_desc;
+ attr_val_descs = ipsec_attr_val_descs;
+
+ /* a CPI isn't quite the same as an SPI
+ * so we use specialized code to emit it.
+ */
+ if (!ipcomp_cpi_generated)
+ {
+ st->st_ipcomp.our_spi = get_my_cpi(
+ &st->st_connection->spd, tunnel_mode);
+ if (st->st_ipcomp.our_spi == 0)
+ return_on(ret, FALSE); /* problem generating CPI */
+
+ ipcomp_cpi_generated = TRUE;
+ }
+ /* CPI is stored in network low order end of an
+ * ipsec_spi_t. So we start a couple of bytes in.
+ */
+ if (!out_raw((u_char *)&st->st_ipcomp.our_spi
+ + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
+ , IPCOMP_CPI_SIZE
+ , &proposal_pbs, "CPI"))
+ return_on(ret, FALSE);
+ break;
+ default:
+ bad_case(p->protoid);
+ }
+ if (spi_ptr != NULL)
+ {
+ if (!*spi_generated)
+ {
+ *spi_ptr = get_ipsec_spi(0
+ , proto
+ , &st->st_connection->spd
+ , tunnel_mode);
+ if (*spi_ptr == 0)
+ return FALSE;
+ *spi_generated = TRUE;
+ }
+ if (!out_raw((u_char *)spi_ptr, IPSEC_DOI_SPI_SIZE
+ , &proposal_pbs, "SPI"))
+ return_on(ret, FALSE);
+ }
+ }
+
+ /* within proposal: Transform Payloads */
+ for (tn = 0; tn != p->trans_cnt; tn++)
+ {
+ struct db_trans *t = &p->trans[tn];
+ pb_stream trans_pbs;
+ struct isakmp_transform trans;
+ int an;
+
+ trans.isat_np = (tn == p->trans_cnt - 1)
+ ? ISAKMP_NEXT_NONE : ISAKMP_NEXT_T;
+ trans.isat_transnum = tn;
+ trans.isat_transid = t->transid;
+ if (!out_struct(&trans, trans_desc, &proposal_pbs, &trans_pbs))
+ return_on(ret, FALSE);
+
+ /* Within tranform: Attributes. */
+
+ /* For Phase 2 / Quick Mode, GROUP_DESCRIPTION is
+ * automatically generated because it must be the same
+ * in every transform. Except IPCOMP.
+ */
+ if (p->protoid != PROTO_IPCOMP
+ && st->st_pfs_group != NULL)
+ {
+ passert(!oakley_mode);
+ passert(st->st_pfs_group != &unset_group);
+ out_attr(GROUP_DESCRIPTION, st->st_pfs_group->algo_id
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ }
+
+ /* automatically generate duration
+ * and, for Phase 2 / Quick Mode, encapsulation.
+ */
+ if (oakley_mode)
+ {
+ out_attr(OAKLEY_LIFE_TYPE, OAKLEY_LIFE_SECONDS
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ out_attr(OAKLEY_LIFE_DURATION
+ , st->st_connection->sa_ike_life_seconds
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ }
+ else
+ {
+ /* RFC 2407 (IPSEC DOI) 4.5 specifies that
+ * the default is "unspecified (host-dependent)".
+ * This makes little sense, so we always specify it.
+ *
+ * Unlike other IPSEC transforms, IPCOMP defaults
+ * to Transport Mode, so we can exploit the default
+ * (draft-shacham-ippcp-rfc2393bis-05.txt 4.1).
+ */
+ if (p->protoid != PROTO_IPCOMP
+ || st->st_policy & POLICY_TUNNEL)
+ {
+#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
+ if ((st->nat_traversal & NAT_T_DETECTED)
+ && !(st->st_policy & POLICY_TUNNEL))
+ {
+ /* Inform user that we will not respect policy and only
+ * propose Tunnel Mode
+ */
+ loglog(RC_LOG_SERIOUS, "NAT-Traversal: "
+ "Transport Mode not allowed due to security concerns -- "
+ "using Tunnel mode");
+ }
#endif
- out_attr(ENCAPSULATION_MODE
+ out_attr(ENCAPSULATION_MODE
#ifdef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- , NAT_T_ENCAPSULATION_MODE(st, st->st_policy)
+ , NAT_T_ENCAPSULATION_MODE(st, st->st_policy)
#else
- /* If NAT-T is detected, use UDP_TUNNEL as long as Transport
- * Mode has security concerns.
- *
- * User has been informed of that
- */
- , NAT_T_ENCAPSULATION_MODE(st, POLICY_TUNNEL)
+ /* If NAT-T is detected, use UDP_TUNNEL as long as Transport
+ * Mode has security concerns.
+ *
+ * User has been informed of that
+ */
+ , NAT_T_ENCAPSULATION_MODE(st, POLICY_TUNNEL)
#endif
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
- out_attr(SA_LIFE_TYPE, SA_LIFE_TYPE_SECONDS
- , attr_desc, attr_val_descs
- , &trans_pbs);
- out_attr(SA_LIFE_DURATION
- , st->st_connection->sa_ipsec_life_seconds
- , attr_desc, attr_val_descs
- , &trans_pbs);
- }
-
- /* spit out attributes from table */
- for (an = 0; an != t->attr_cnt; an++)
- {
- struct db_attr *a = &t->attrs[an];
-
- out_attr(a->type, a->val
- , attr_desc, attr_val_descs
- , &trans_pbs);
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ }
+ out_attr(SA_LIFE_TYPE, SA_LIFE_TYPE_SECONDS
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ out_attr(SA_LIFE_DURATION
+ , st->st_connection->sa_ipsec_life_seconds
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ }
+
+ /* spit out attributes from table */
+ for (an = 0; an != t->attr_cnt; an++)
+ {
+ struct db_attr *a = &t->attrs[an];
+
+ out_attr(a->type, a->val
+ , attr_desc, attr_val_descs
+ , &trans_pbs);
+ }
+
+ close_output_pbs(&trans_pbs);
+ }
+ close_output_pbs(&proposal_pbs);
}
-
- close_output_pbs(&trans_pbs);
- }
- close_output_pbs(&proposal_pbs);
+ /* end of a conjunction of proposals */
}
- /* end of a conjunction of proposals */
- }
- close_output_pbs(&sa_pbs);
- ret = TRUE;
+ close_output_pbs(&sa_pbs);
+ ret = TRUE;
return_out:
#if !defined NO_KERNEL_ALG || !defined NO_IKE_ALG
- if (db_ctx)
- db_destroy(db_ctx);
+ if (db_ctx)
+ db_destroy(db_ctx);
#endif
- return ret;
+ return ret;
}
/* Handle long form of duration attribute.
@@ -590,27 +585,27 @@ return_out:
static u_int32_t
decode_long_duration(pb_stream *pbs)
{
- u_int32_t val = 0;
-
- /* ignore leading zeros */
- while (pbs_left(pbs) != 0 && *pbs->cur == '\0')
- pbs->cur++;
-
- if (pbs_left(pbs) > sizeof(val))
- {
- /* "clamp" too large value to max representable value */
- val -= 1; /* portable way to get to maximum value */
- DBG(DBG_PARSING, DBG_log(" too large duration clamped to: %lu"
- , (unsigned long)val));
- }
- else
- {
- /* decode number */
- while (pbs_left(pbs) != 0)
- val = (val << BITS_PER_BYTE) | *pbs->cur++;
- DBG(DBG_PARSING, DBG_log(" long duration: %lu", (unsigned long)val));
- }
- return val;
+ u_int32_t val = 0;
+
+ /* ignore leading zeros */
+ while (pbs_left(pbs) != 0 && *pbs->cur == '\0')
+ pbs->cur++;
+
+ if (pbs_left(pbs) > sizeof(val))
+ {
+ /* "clamp" too large value to max representable value */
+ val -= 1; /* portable way to get to maximum value */
+ DBG(DBG_PARSING, DBG_log(" too large duration clamped to: %lu"
+ , (unsigned long)val));
+ }
+ else
+ {
+ /* decode number */
+ while (pbs_left(pbs) != 0)
+ val = (val << BITS_PER_BYTE) | *pbs->cur++;
+ DBG(DBG_PARSING, DBG_log(" long duration: %lu", (unsigned long)val));
+ }
+ return val;
}
/* Preparse the body of an ISAKMP SA Payload and
@@ -621,99 +616,99 @@ decode_long_duration(pb_stream *pbs)
*/
notification_t
preparse_isakmp_sa_body(const struct isakmp_sa *sa
- , pb_stream *sa_pbs
- , u_int32_t *ipsecdoisit
- , pb_stream *proposal_pbs
- , struct isakmp_proposal *proposal)
+ , pb_stream *sa_pbs
+ , u_int32_t *ipsecdoisit
+ , pb_stream *proposal_pbs
+ , struct isakmp_proposal *proposal)
{
- /* DOI */
- if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
- {
- loglog(RC_LOG_SERIOUS, "Unknown/unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
- /* XXX Could send notification back */
- return DOI_NOT_SUPPORTED;
- }
-
- /* Situation */
- if (!in_struct(ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
- return SITUATION_NOT_SUPPORTED;
-
- if (*ipsecdoisit != SIT_IDENTITY_ONLY)
- {
- loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
- , bitnamesof(sit_bit_names, *ipsecdoisit));
- /* XXX Could send notification back */
- return SITUATION_NOT_SUPPORTED;
- }
-
- /* The rules for ISAKMP SAs are scattered.
- * RFC 2409 "IKE" section 5 says that there
- * can only be one SA, and it can have only one proposal in it.
- * There may well be multiple transforms.
- */
- if (!in_struct(proposal, &isakmp_proposal_desc, sa_pbs, proposal_pbs))
- return PAYLOAD_MALFORMED;
-
- if (proposal->isap_np != ISAKMP_NEXT_NONE)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload must be alone in Oakley SA; found %s following Proposal"
- , enum_show(&payload_names, proposal->isap_np));
- return PAYLOAD_MALFORMED;
- }
-
- if (proposal->isap_protoid != PROTO_ISAKMP)
- {
- loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) found in Oakley Proposal"
- , enum_show(&protocol_names, proposal->isap_protoid));
- return INVALID_PROTOCOL_ID;
- }
-
- /* Just what should we accept for the SPI field?
- * The RFC is sort of contradictory. We will ignore the SPI
- * as long as it is of the proper size.
- *
- * From RFC2408 2.4 Identifying Security Associations:
- * During phase 1 negotiations, the initiator and responder cookies
- * determine the ISAKMP SA. Therefore, the SPI field in the Proposal
- * payload is redundant and MAY be set to 0 or it MAY contain the
- * transmitting entity's cookie.
- *
- * From RFC2408 3.5 Proposal Payload:
- * o SPI Size (1 octet) - Length in octets of the SPI as defined by
- * the Protocol-Id. In the case of ISAKMP, the Initiator and
- * Responder cookie pair from the ISAKMP Header is the ISAKMP SPI,
- * therefore, the SPI Size is irrelevant and MAY be from zero (0) to
- * sixteen (16). If the SPI Size is non-zero, the content of the
- * SPI field MUST be ignored. If the SPI Size is not a multiple of
- * 4 octets it will have some impact on the SPI field and the
- * alignment of all payloads in the message. The Domain of
- * Interpretation (DOI) will dictate the SPI Size for other
- * protocols.
- */
- if (proposal->isap_spisize == 0)
- {
- /* empty (0) SPI -- fine */
- }
- else if (proposal->isap_spisize <= MAX_ISAKMP_SPI_SIZE)
- {
- u_char junk_spi[MAX_ISAKMP_SPI_SIZE];
-
- if (!in_raw(junk_spi, proposal->isap_spisize, proposal_pbs, "Oakley SPI"))
- return PAYLOAD_MALFORMED;
- }
- else
- {
- loglog(RC_LOG_SERIOUS, "invalid SPI size (%u) in Oakley Proposal"
- , (unsigned)proposal->isap_spisize);
- return INVALID_SPI;
- }
- return NOTHING_WRONG;
+ /* DOI */
+ if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
+ {
+ loglog(RC_LOG_SERIOUS, "Unknown/unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
+ /* XXX Could send notification back */
+ return DOI_NOT_SUPPORTED;
+ }
+
+ /* Situation */
+ if (!in_struct(ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
+ return SITUATION_NOT_SUPPORTED;
+
+ if (*ipsecdoisit != SIT_IDENTITY_ONLY)
+ {
+ loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
+ , bitnamesof(sit_bit_names, *ipsecdoisit));
+ /* XXX Could send notification back */
+ return SITUATION_NOT_SUPPORTED;
+ }
+
+ /* The rules for ISAKMP SAs are scattered.
+ * RFC 2409 "IKE" section 5 says that there
+ * can only be one SA, and it can have only one proposal in it.
+ * There may well be multiple transforms.
+ */
+ if (!in_struct(proposal, &isakmp_proposal_desc, sa_pbs, proposal_pbs))
+ return PAYLOAD_MALFORMED;
+
+ if (proposal->isap_np != ISAKMP_NEXT_NONE)
+ {
+ loglog(RC_LOG_SERIOUS, "Proposal Payload must be alone in Oakley SA; found %s following Proposal"
+ , enum_show(&payload_names, proposal->isap_np));
+ return PAYLOAD_MALFORMED;
+ }
+
+ if (proposal->isap_protoid != PROTO_ISAKMP)
+ {
+ loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) found in Oakley Proposal"
+ , enum_show(&protocol_names, proposal->isap_protoid));
+ return INVALID_PROTOCOL_ID;
+ }
+
+ /* Just what should we accept for the SPI field?
+ * The RFC is sort of contradictory. We will ignore the SPI
+ * as long as it is of the proper size.
+ *
+ * From RFC2408 2.4 Identifying Security Associations:
+ * During phase 1 negotiations, the initiator and responder cookies
+ * determine the ISAKMP SA. Therefore, the SPI field in the Proposal
+ * payload is redundant and MAY be set to 0 or it MAY contain the
+ * transmitting entity's cookie.
+ *
+ * From RFC2408 3.5 Proposal Payload:
+ * o SPI Size (1 octet) - Length in octets of the SPI as defined by
+ * the Protocol-Id. In the case of ISAKMP, the Initiator and
+ * Responder cookie pair from the ISAKMP Header is the ISAKMP SPI,
+ * therefore, the SPI Size is irrelevant and MAY be from zero (0) to
+ * sixteen (16). If the SPI Size is non-zero, the content of the
+ * SPI field MUST be ignored. If the SPI Size is not a multiple of
+ * 4 octets it will have some impact on the SPI field and the
+ * alignment of all payloads in the message. The Domain of
+ * Interpretation (DOI) will dictate the SPI Size for other
+ * protocols.
+ */
+ if (proposal->isap_spisize == 0)
+ {
+ /* empty (0) SPI -- fine */
+ }
+ else if (proposal->isap_spisize <= MAX_ISAKMP_SPI_SIZE)
+ {
+ u_char junk_spi[MAX_ISAKMP_SPI_SIZE];
+
+ if (!in_raw(junk_spi, proposal->isap_spisize, proposal_pbs, "Oakley SPI"))
+ return PAYLOAD_MALFORMED;
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS, "invalid SPI size (%u) in Oakley Proposal"
+ , (unsigned)proposal->isap_spisize);
+ return INVALID_SPI;
+ }
+ return NOTHING_WRONG;
}
static struct {
- u_int8_t *start;
- u_int8_t *cur;
- u_int8_t *roof;
+ u_int8_t *start;
+ u_int8_t *cur;
+ u_int8_t *roof;
} backup;
/*
@@ -722,9 +717,9 @@ static struct {
void
backup_pbs(pb_stream *pbs)
{
- backup.start = pbs->start;
- backup.cur = pbs->cur;
- backup.roof = pbs->roof;
+ backup.start = pbs->start;
+ backup.cur = pbs->cur;
+ backup.roof = pbs->roof;
}
/*
@@ -733,9 +728,9 @@ backup_pbs(pb_stream *pbs)
void
restore_pbs(pb_stream *pbs)
{
- pbs->start = backup.start;
- pbs->cur = backup.cur;
- pbs->roof = backup.roof;
+ pbs->start = backup.start;
+ pbs->cur = backup.cur;
+ pbs->roof = backup.roof;
}
/*
@@ -743,90 +738,93 @@ restore_pbs(pb_stream *pbs)
*/
notification_t
parse_isakmp_policy(pb_stream *proposal_pbs
- , u_int notrans
- , lset_t *policy)
+ , u_int notrans
+ , lset_t *policy)
{
- int last_transnum = -1;
+ int last_transnum = -1;
- *policy = LEMPTY;
+ *policy = LEMPTY;
- while (notrans--)
- {
- pb_stream trans_pbs;
- u_char *attr_start;
- size_t attr_len;
- struct isakmp_transform trans;
+ while (notrans--)
+ {
+ pb_stream trans_pbs;
+ u_char *attr_start;
+ size_t attr_len;
+ struct isakmp_transform trans;
- if (!in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs))
- return BAD_PROPOSAL_SYNTAX;
+ if (!in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs))
+ return BAD_PROPOSAL_SYNTAX;
- if (trans.isat_transnum <= last_transnum)
- {
- /* picky, picky, picky */
- loglog(RC_LOG_SERIOUS, "Transform Numbers are not monotonically increasing"
- " in Oakley Proposal");
- return BAD_PROPOSAL_SYNTAX;
- }
- last_transnum = trans.isat_transnum;
+ if (trans.isat_transnum <= last_transnum)
+ {
+ /* picky, picky, picky */
+ loglog(RC_LOG_SERIOUS, "Transform Numbers are not monotonically increasing"
+ " in Oakley Proposal");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ last_transnum = trans.isat_transnum;
- if (trans.isat_transid != KEY_IKE)
- {
- loglog(RC_LOG_SERIOUS, "expected KEY_IKE but found %s in Oakley Transform"
- , enum_show(&isakmp_transformid_names, trans.isat_transid));
- return INVALID_TRANSFORM_ID;
- }
+ if (trans.isat_transid != KEY_IKE)
+ {
+ loglog(RC_LOG_SERIOUS, "expected KEY_IKE but found %s in Oakley Transform"
+ , enum_show(&isakmp_transformid_names, trans.isat_transid));
+ return INVALID_TRANSFORM_ID;
+ }
- attr_start = trans_pbs.cur;
- attr_len = pbs_left(&trans_pbs);
+ attr_start = trans_pbs.cur;
+ attr_len = pbs_left(&trans_pbs);
- /* preprocess authentication attributes only */
- while (pbs_left(&trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
+ /* preprocess authentication attributes only */
+ while (pbs_left(&trans_pbs) != 0)
+ {
+ struct isakmp_attribute a;
+ pb_stream attr_pbs;
- if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
- return BAD_PROPOSAL_SYNTAX;
+ if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
+ return BAD_PROPOSAL_SYNTAX;
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
+ passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
- switch (a.isaat_af_type)
- {
- case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
- switch (a.isaat_lv)
- {
- case OAKLEY_PRESHARED_KEY:
- *policy |= POLICY_PSK;
- break;
- case OAKLEY_RSA_SIG:
- *policy |= POLICY_RSASIG;
- break;
- case XAUTHInitPreShared:
- *policy |= POLICY_XAUTH_SERVER;
- /* fall through */
- case XAUTHRespPreShared:
- *policy |= POLICY_XAUTH_PSK;
- break;
- case XAUTHInitRSA:
- *policy |= POLICY_XAUTH_SERVER;
- /* fall through */
- case XAUTHRespRSA:
- *policy |= POLICY_XAUTH_RSASIG;
- break;
- default:
- break;
+ switch (a.isaat_af_type)
+ {
+ case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
+ switch (a.isaat_lv)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ *policy |= POLICY_PSK;
+ break;
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ *policy |= POLICY_PUBKEY;
+ break;
+ case XAUTHInitPreShared:
+ *policy |= POLICY_XAUTH_SERVER;
+ /* fall through */
+ case XAUTHRespPreShared:
+ *policy |= POLICY_XAUTH_PSK;
+ break;
+ case XAUTHInitRSA:
+ *policy |= POLICY_XAUTH_SERVER;
+ /* fall through */
+ case XAUTHRespRSA:
+ *policy |= POLICY_XAUTH_RSASIG;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
}
- break;
- default:
- break;
- }
}
- }
- DBG(DBG_CONTROL|DBG_PARSING,
- DBG_log("preparse_isakmp_policy: peer requests %s authentication"
- , prettypolicy(*policy))
- )
- return NOTHING_WRONG;
+ DBG(DBG_CONTROL|DBG_PARSING,
+ DBG_log("preparse_isakmp_policy: peer requests %s authentication"
+ , prettypolicy(*policy))
+ )
+ return NOTHING_WRONG;
}
/*
@@ -835,22 +833,22 @@ parse_isakmp_policy(pb_stream *proposal_pbs
static err_t
find_preshared_key(struct state* st)
{
- err_t ugh = NULL;
- struct connection *c = st->st_connection;
+ err_t ugh = NULL;
+ struct connection *c = st->st_connection;
- if (get_preshared_secret(c) == NULL)
- {
- char my_id[BUF_LEN], his_id[BUF_LEN];
+ if (get_preshared_secret(c) == NULL)
+ {
+ char my_id[BUF_LEN], his_id[BUF_LEN];
- idtoa(&c->spd.this.id, my_id, sizeof(my_id));
- if (his_id_was_instantiated(c))
- strcpy(his_id, "%any");
- else
- idtoa(&c->spd.that.id, his_id, sizeof(his_id));
- ugh = builddiag("Can't authenticate: no preshared key found for `%s' and `%s'"
- , my_id, his_id);
- }
- return ugh;
+ idtoa(&c->spd.this.id, my_id, sizeof(my_id));
+ if (his_id_was_instantiated(c))
+ strcpy(his_id, "%any");
+ else
+ idtoa(&c->spd.that.id, his_id, sizeof(his_id));
+ ugh = builddiag("Can't authenticate: no preshared key found for `%s' and `%s'"
+ , my_id, his_id);
+ }
+ return ugh;
}
/* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
@@ -864,429 +862,432 @@ find_preshared_key(struct state* st)
*/
notification_t
parse_isakmp_sa_body(u_int32_t ipsecdoisit
- , pb_stream *proposal_pbs
- , struct isakmp_proposal *proposal
- , pb_stream *r_sa_pbs
- , struct state *st
- , bool initiator)
+ , pb_stream *proposal_pbs
+ , struct isakmp_proposal *proposal
+ , pb_stream *r_sa_pbs
+ , struct state *st
+ , bool initiator)
{
- struct connection *c = st->st_connection;
- unsigned no_trans_left;
-
- /* for each transform payload... */
- no_trans_left = proposal->isap_notrans;
-
- for (;;)
- {
- pb_stream trans_pbs;
- u_char *attr_start;
- size_t attr_len;
- struct isakmp_transform trans;
- lset_t seen_attrs = 0;
- lset_t seen_durations = 0;
- u_int16_t life_type = 0;
- struct oakley_trans_attrs ta;
- err_t ugh = NULL; /* set to diagnostic when problem detected */
+ struct connection *c = st->st_connection;
+ unsigned no_trans_left;
- /* initialize only optional field in ta */
- ta.life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT; /* When this SA expires (seconds) */
+ /* for each transform payload... */
+ no_trans_left = proposal->isap_notrans;
- if (no_trans_left == 0)
+ for (;;)
{
- loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs);
- attr_start = trans_pbs.cur;
- attr_len = pbs_left(&trans_pbs);
-
- /* process all the attributes that make up the transform */
+ pb_stream trans_pbs;
+ u_char *attr_start;
+ size_t attr_len;
+ struct isakmp_transform trans;
+ lset_t seen_attrs = 0;
+ lset_t seen_durations = 0;
+ u_int16_t life_type = 0;
+ struct oakley_trans_attrs ta;
+ err_t ugh = NULL; /* set to diagnostic when problem detected */
- while (pbs_left(&trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
- u_int32_t val; /* room for larger values */
+ /* initialize only optional field in ta */
+ ta.life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT; /* When this SA expires (seconds) */
- if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
- return BAD_PROPOSAL_SYNTAX;
+ if (no_trans_left == 0)
+ {
+ loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
+ return BAD_PROPOSAL_SYNTAX;
+ }
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
+ in_struct(&trans, &isakmp_isakmp_transform_desc, proposal_pbs, &trans_pbs);
+ attr_start = trans_pbs.cur;
+ attr_len = pbs_left(&trans_pbs);
- if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
- {
- loglog(RC_LOG_SERIOUS, "repeated %s attribute in Oakley Transform %u"
- , enum_show(&oakley_attr_names, a.isaat_af_type)
- , trans.isat_transnum);
- return BAD_PROPOSAL_SYNTAX;
- }
+ /* process all the attributes that make up the transform */
- seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
+ while (pbs_left(&trans_pbs) != 0)
+ {
+ struct isakmp_attribute a;
+ pb_stream attr_pbs;
+ u_int32_t val; /* room for larger values */
- val = a.isaat_lv;
+ if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs, &attr_pbs))
+ return BAD_PROPOSAL_SYNTAX;
- DBG(DBG_PARSING,
- {
- enum_names *vdesc = oakley_attr_val_descs
- [a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
+ passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
- if (vdesc != NULL)
- {
- const char *nm = enum_name(vdesc, val);
+ if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
+ {
+ loglog(RC_LOG_SERIOUS, "repeated %s attribute in Oakley Transform %u"
+ , enum_show(&oakley_attr_names, a.isaat_af_type)
+ , trans.isat_transnum);
+ return BAD_PROPOSAL_SYNTAX;
+ }
- if (nm != NULL)
- DBG_log(" [%u is %s]", (unsigned)val, nm);
- }
- });
+ seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
- switch (a.isaat_af_type)
- {
- case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV:
- if (ike_alg_enc_present(val))
- {
- ta.encrypt = val;
- ta.encrypter = ike_alg_get_encrypter(val);
- ta.enckeylen = ta.encrypter->keydeflen;
- }
- else
- {
- ugh = builddiag("%s is not supported"
- , enum_show(&oakley_enc_names, val));
- }
- break;
+ val = a.isaat_lv;
- case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV:
- if (ike_alg_hash_present(val))
- {
- ta.hash = val;
- ta.hasher = ike_alg_get_hasher(val);
- }
- else
- {
- ugh = builddiag("%s is not supported"
- , enum_show(&oakley_hash_names, val));
- }
- break;
+ DBG(DBG_PARSING,
+ {
+ enum_names *vdesc = oakley_attr_val_descs
+ [a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
- case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
- {
- /* check that authentication method is acceptable */
- lset_t iap = st->st_policy & POLICY_ID_AUTH_MASK;
+ if (vdesc != NULL)
+ {
+ const char *nm = enum_name(vdesc, val);
- /* is the initiator the XAUTH client? */
- bool xauth_init = ( initiator && (st->st_policy & POLICY_XAUTH_SERVER) == LEMPTY)
- || (!initiator && (st->st_policy & POLICY_XAUTH_SERVER) != LEMPTY);
+ if (nm != NULL)
+ DBG_log(" [%u is %s]", (unsigned)val, nm);
+ }
+ });
- switch (val)
- {
- case OAKLEY_PRESHARED_KEY:
- if ((iap & POLICY_PSK) == LEMPTY)
- {
- ugh = "policy does not allow OAKLEY_PRESHARED_KEY authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = OAKLEY_PRESHARED_KEY;
- }
- break;
- case XAUTHInitPreShared:
- if ((iap & POLICY_XAUTH_PSK) == LEMPTY || !xauth_init)
- {
- ugh = "policy does not allow XAUTHInitPreShared authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = XAUTHInitPreShared;
- }
- break;
- case XAUTHRespPreShared:
- if ((iap & POLICY_XAUTH_PSK) == LEMPTY || xauth_init)
- {
- ugh = "policy does not allow XAUTHRespPreShared authentication";
- }
- else
- {
- ugh = find_preshared_key(st);
- ta.auth = XAUTHRespPreShared;
- }
- break;
- case OAKLEY_RSA_SIG:
- /* Accept if policy specifies RSASIG or is default */
- if ((iap & POLICY_RSASIG) == LEMPTY)
- {
- ugh = "policy does not allow OAKLEY_RSA_SIG authentication";
- }
- else
- {
- ta.auth = OAKLEY_RSA_SIG;
- }
- break;
- case XAUTHInitRSA:
- if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || !xauth_init)
+ switch (a.isaat_af_type)
{
- ugh = "policy does not allow XAUTHInitRSA authentication";
- }
- else
- {
- ta.auth = XAUTHInitRSA;
- }
- break;
- case XAUTHRespRSA:
- if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || xauth_init)
- {
- ugh = "policy does not allow XAUTHRespRSA authentication";
+ case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV:
+ if (ike_alg_get_crypter(val))
+ {
+ ta.encrypt = val;
+ ta.encrypter = ike_alg_get_crypter(val);
+ ta.enckeylen = ta.encrypter->keydeflen;
+ }
+ else
+ {
+ ugh = builddiag("%s is not supported"
+ , enum_show(&oakley_enc_names, val));
+ }
+ break;
+
+ case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV:
+ if (ike_alg_get_hasher(val))
+ {
+ ta.hash = val;
+ ta.hasher = ike_alg_get_hasher(val);
+ }
+ else
+ {
+ ugh = builddiag("%s is not supported"
+ , enum_show(&oakley_hash_names, val));
+ }
+ break;
+
+ case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
+ {
+ /* check that authentication method is acceptable */
+ lset_t iap = st->st_policy & POLICY_ID_AUTH_MASK;
+
+ /* is the initiator the XAUTH client? */
+ bool xauth_init = ( initiator && (st->st_policy & POLICY_XAUTH_SERVER) == LEMPTY)
+ || (!initiator && (st->st_policy & POLICY_XAUTH_SERVER) != LEMPTY);
+
+ switch (val)
+ {
+ case OAKLEY_PRESHARED_KEY:
+ if ((iap & POLICY_PSK) == LEMPTY)
+ {
+ ugh = "policy does not allow pre-shared key authentication";
+ }
+ else
+ {
+ ugh = find_preshared_key(st);
+ ta.auth = OAKLEY_PRESHARED_KEY;
+ }
+ break;
+ case XAUTHInitPreShared:
+ if ((iap & POLICY_XAUTH_PSK) == LEMPTY || !xauth_init)
+ {
+ ugh = "policy does not allow XAUTHInitPreShared authentication";
+ }
+ else
+ {
+ ugh = find_preshared_key(st);
+ ta.auth = XAUTHInitPreShared;
+ }
+ break;
+ case XAUTHRespPreShared:
+ if ((iap & POLICY_XAUTH_PSK) == LEMPTY || xauth_init)
+ {
+ ugh = "policy does not allow XAUTHRespPreShared authentication";
+ }
+ else
+ {
+ ugh = find_preshared_key(st);
+ ta.auth = XAUTHRespPreShared;
+ }
+ break;
+ case OAKLEY_RSA_SIG:
+ case OAKLEY_ECDSA_256:
+ case OAKLEY_ECDSA_384:
+ case OAKLEY_ECDSA_521:
+ if ((iap & POLICY_PUBKEY) == LEMPTY)
+ {
+ ugh = "policy does not allow public key authentication";
+ }
+ else
+ {
+ ta.auth = val;
+ }
+ break;
+ case XAUTHInitRSA:
+ if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || !xauth_init)
+ {
+ ugh = "policy does not allow XAUTHInitRSA authentication";
+ }
+ else
+ {
+ ta.auth = XAUTHInitRSA;
+ }
+ break;
+ case XAUTHRespRSA:
+ if ((iap & POLICY_XAUTH_RSASIG) == LEMPTY || xauth_init)
+ {
+ ugh = "policy does not allow XAUTHRespRSA authentication";
+ }
+ else
+ {
+ ta.auth = XAUTHRespRSA;
+ }
+ break;
+ default:
+ ugh = builddiag("Pluto does not support %s authentication"
+ , enum_show(&oakley_auth_names, val));
+ break;
+ }
+ }
+ break;
+
+ case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
+ ta.group = ike_alg_get_dh_group(val);
+ if (ta.group == NULL)
+ {
+ ugh = builddiag("%s is not supported"
+ , enum_show(&oakley_group_names, val));
+ }
+ break;
+
+ case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
+ switch (val)
+ {
+ case OAKLEY_LIFE_SECONDS:
+ case OAKLEY_LIFE_KILOBYTES:
+ if (LHAS(seen_durations, val))
+ {
+ loglog(RC_LOG_SERIOUS
+ , "attribute OAKLEY_LIFE_TYPE value %s repeated"
+ , enum_show(&oakley_lifetime_names, val));
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ seen_durations |= LELEM(val);
+ life_type = val;
+ break;
+ default:
+ ugh = builddiag("unknown value %s"
+ , enum_show(&oakley_lifetime_names, val));
+ break;
+ }
+ break;
+
+ case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
+ val = decode_long_duration(&attr_pbs);
+ /* fall through */
+ case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
+ if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE))
+ {
+ ugh = "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute";
+ break;
+ }
+ seen_attrs &= ~(LELEM(OAKLEY_LIFE_DURATION) | LELEM(OAKLEY_LIFE_TYPE));
+
+ switch (life_type)
+ {
+ case OAKLEY_LIFE_SECONDS:
+ if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)
+ {
+#ifdef CISCO_QUIRKS
+ plog("peer requested %lu seconds"
+ " which exceeds our limit %d seconds"
+ , (long) val
+ , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+ plog("lifetime reduced to %d seconds "
+ "(todo: IPSEC_RESPONDER_LIFETIME notification)"
+ , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+ val = OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM;
+#else
+ ugh = builddiag("peer requested %lu seconds"
+ " which exceeds our limit %d seconds"
+ , (long) val
+ , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
+#endif
+ }
+ ta.life_seconds = val;
+ break;
+ case OAKLEY_LIFE_KILOBYTES:
+ ta.life_kilobytes = val;
+ break;
+ default:
+ bad_case(life_type);
+ }
+ break;
+
+ case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:
+ if ((seen_attrs & LELEM(OAKLEY_ENCRYPTION_ALGORITHM)) == 0)
+ {
+ ugh = "OAKLEY_KEY_LENGTH attribute not preceded by "
+ "OAKLEY_ENCRYPTION_ALGORITHM attribute";
+ break;
+ }
+ if (ta.encrypter == NULL)
+ {
+ ugh = "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM";
+ break;
+ }
+ /*
+ * check if this keylen is compatible with specified algorithm
+ */
+ if (val
+ && (val < ta.encrypter->keyminlen || val > ta.encrypter->keymaxlen))
+ {
+ ugh = "peer proposed key length not valid for "
+ "encryption algorithm specified";
+ }
+ ta.enckeylen = val;
+ break;
+#if 0 /* not yet supported */
+ case OAKLEY_GROUP_TYPE | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_PRF | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_FIELD_SIZE | ISAKMP_ATTR_AF_TV:
+
+ case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TLV:
+ case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TLV:
+ case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TLV:
+ case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TLV:
+ case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TLV:
+ case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TV:
+ case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:
+#endif
+ default:
+ /* fix compiler warning */
+ memset(&ta, 0, sizeof(ta));
+ ugh = "unsupported OAKLEY attribute";
+ break;
}
- else
+
+ if (ugh != NULL)
{
- ta.auth = XAUTHRespRSA;
+ loglog(RC_LOG_SERIOUS, "%s. Attribute %s"
+ , ugh, enum_show(&oakley_attr_names, a.isaat_af_type));
+ break;
}
- break;
- default:
- ugh = builddiag("Pluto does not support %s authentication"
- , enum_show(&oakley_auth_names, val));
- break;
- }
}
- break;
- case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
- ta.group = lookup_group(val);
- if (ta.group == NULL)
+ /*
+ * ML: at last check for allowed transforms in alg_info_ike
+ * (ALG_INFO_F_STRICT flag)
+ */
+ if (ugh == NULL)
{
- ugh = "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported";
+ if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,
+ ta.group ? ta.group->algo_id : -1, c->alg_info_ike))
+ {
+ ugh = "OAKLEY proposal refused";
+ }
}
- break;
- case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
- switch (val)
+ if (ugh == NULL)
{
- case OAKLEY_LIFE_SECONDS:
- case OAKLEY_LIFE_KILOBYTES:
- if (LHAS(seen_durations, val))
- {
- loglog(RC_LOG_SERIOUS
- , "attribute OAKLEY_LIFE_TYPE value %s repeated"
- , enum_show(&oakley_lifetime_names, val));
- return BAD_PROPOSAL_SYNTAX;
- }
- seen_durations |= LELEM(val);
- life_type = val;
- break;
- default:
- ugh = builddiag("unknown value %s"
- , enum_show(&oakley_lifetime_names, val));
- break;
- }
- break;
+ /* a little more checking is in order */
+ {
+ lset_t missing
+ = ~seen_attrs
+ & (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)
+ | LELEM(OAKLEY_HASH_ALGORITHM)
+ | LELEM(OAKLEY_AUTHENTICATION_METHOD)
+ | LELEM(OAKLEY_GROUP_DESCRIPTION));
+
+ if (missing)
+ {
+ loglog(RC_LOG_SERIOUS, "missing mandatory attribute(s) %s in Oakley Transform %u"
+ , bitnamesof(oakley_attr_bit_names, missing)
+ , trans.isat_transnum);
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ }
+ /* We must have liked this transform.
+ * Lets finish early and leave.
+ */
- case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- val = decode_long_duration(&attr_pbs);
- /* fall through */
- case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
- if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE))
- {
- ugh = "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute";
- break;
- }
- seen_attrs &= ~(LELEM(OAKLEY_LIFE_DURATION) | LELEM(OAKLEY_LIFE_TYPE));
+ DBG(DBG_PARSING | DBG_CRYPT
+ , DBG_log("Oakley Transform %u accepted", trans.isat_transnum));
- switch (life_type)
- {
- case OAKLEY_LIFE_SECONDS:
- if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)
- {
-#ifdef CISCO_QUIRKS
- plog("peer requested %lu seconds"
- " which exceeds our limit %d seconds"
- , (long) val
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
- plog("lifetime reduced to %d seconds "
- "(todo: IPSEC_RESPONDER_LIFETIME notification)"
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
- val = OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM;
-#else
- ugh = builddiag("peer requested %lu seconds"
- " which exceeds our limit %d seconds"
- , (long) val
- , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);
-#endif
- }
- ta.life_seconds = val;
- break;
- case OAKLEY_LIFE_KILOBYTES:
- ta.life_kilobytes = val;
- break;
- default:
- bad_case(life_type);
- }
- break;
-
- case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:
- if ((seen_attrs & LELEM(OAKLEY_ENCRYPTION_ALGORITHM)) == 0)
- {
- ugh = "OAKLEY_KEY_LENGTH attribute not preceded by "
- "OAKLEY_ENCRYPTION_ALGORITHM attribute";
- break;
- }
- if (ta.encrypter == NULL)
- {
- ugh = "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM";
- break;
- }
- /*
- * check if this keylen is compatible with specified algorithm
- */
- if (val
- && (val < ta.encrypter->keyminlen || val > ta.encrypter->keymaxlen))
- {
- ugh = "peer proposed key length not valid for "
- "encryption algorithm specified";
- }
- ta.enckeylen = val;
- break;
-#if 0 /* not yet supported */
- case OAKLEY_GROUP_TYPE | ISAKMP_ATTR_AF_TV:
- case OAKLEY_PRF | ISAKMP_ATTR_AF_TV:
- case OAKLEY_FIELD_SIZE | ISAKMP_ATTR_AF_TV:
-
- case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TLV:
- case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TV:
- case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:
-#endif
- default:
- /* fix compiler warning */
- memset(&ta, 0, sizeof(ta));
- ugh = "unsupported OAKLEY attribute";
- break;
- }
-
- if (ugh != NULL)
- {
- loglog(RC_LOG_SERIOUS, "%s. Attribute %s"
- , ugh, enum_show(&oakley_attr_names, a.isaat_af_type));
- break;
- }
- }
+ if (r_sa_pbs != NULL)
+ {
+ struct isakmp_proposal r_proposal = *proposal;
+ pb_stream r_proposal_pbs;
+ struct isakmp_transform r_trans = trans;
+ pb_stream r_trans_pbs;
- /*
- * ML: at last check for allowed transforms in alg_info_ike
- * (ALG_INFO_F_STRICT flag)
- */
- if (ugh == NULL)
- {
- if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,
- ta.group ? ta.group->group : -1, c->alg_info_ike))
- {
- ugh = "OAKLEY proposal refused";
- }
- }
+ /* Situation */
+ if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
+ impossible();
- if (ugh == NULL)
- {
- /* a little more checking is in order */
- {
- lset_t missing
- = ~seen_attrs
- & (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)
- | LELEM(OAKLEY_HASH_ALGORITHM)
- | LELEM(OAKLEY_AUTHENTICATION_METHOD)
- | LELEM(OAKLEY_GROUP_DESCRIPTION));
-
- if (missing)
- {
- loglog(RC_LOG_SERIOUS, "missing mandatory attribute(s) %s in Oakley Transform %u"
- , bitnamesof(oakley_attr_bit_names, missing)
- , trans.isat_transnum);
- return BAD_PROPOSAL_SYNTAX;
- }
- }
- /* We must have liked this transform.
- * Lets finish early and leave.
- */
-
- DBG(DBG_PARSING | DBG_CRYPT
- , DBG_log("Oakley Transform %u accepted", trans.isat_transnum));
-
- if (r_sa_pbs != NULL)
- {
- struct isakmp_proposal r_proposal = *proposal;
- pb_stream r_proposal_pbs;
- struct isakmp_transform r_trans = trans;
- pb_stream r_trans_pbs;
-
- /* Situation */
- if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
- impossible();
-
- /* Proposal */
+ /* Proposal */
#ifdef EMIT_ISAKMP_SPI
- r_proposal.isap_spisize = COOKIE_SIZE;
+ r_proposal.isap_spisize = COOKIE_SIZE;
#else
- r_proposal.isap_spisize = 0;
+ r_proposal.isap_spisize = 0;
#endif
- r_proposal.isap_notrans = 1;
- if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
- impossible();
+ r_proposal.isap_notrans = 1;
+ if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
+ impossible();
- /* SPI */
+ /* SPI */
#ifdef EMIT_ISAKMP_SPI
- if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI"))
- impossible();
- r_proposal.isap_spisize = COOKIE_SIZE;
+ if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI"))
+ impossible();
+ r_proposal.isap_spisize = COOKIE_SIZE;
#else
- /* none (0) */
+ /* none (0) */
#endif
- /* Transform */
- r_trans.isat_np = ISAKMP_NEXT_NONE;
- if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs))
- impossible();
-
- if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes"))
- impossible();
- close_output_pbs(&r_trans_pbs);
- close_output_pbs(&r_proposal_pbs);
- close_output_pbs(r_sa_pbs);
- }
-
- /* copy over the results */
- st->st_oakley = ta;
- return NOTHING_WRONG;
- }
+ /* Transform */
+ r_trans.isat_np = ISAKMP_NEXT_NONE;
+ if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs))
+ impossible();
- /* on to next transform */
- no_trans_left--;
+ if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes"))
+ impossible();
+ close_output_pbs(&r_trans_pbs);
+ close_output_pbs(&r_proposal_pbs);
+ close_output_pbs(r_sa_pbs);
+ }
- if (trans.isat_np == ISAKMP_NEXT_NONE)
- {
- if (no_trans_left != 0)
- {
- loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
- return BAD_PROPOSAL_SYNTAX;
- }
- break;
- }
- if (trans.isat_np != ISAKMP_NEXT_T)
- {
- loglog(RC_LOG_SERIOUS, "unexpected %s payload in Oakley Proposal"
- , enum_show(&payload_names, proposal->isap_np));
- return BAD_PROPOSAL_SYNTAX;
+ /* copy over the results */
+ st->st_oakley = ta;
+ return NOTHING_WRONG;
+ }
+
+ /* on to next transform */
+ no_trans_left--;
+
+ if (trans.isat_np == ISAKMP_NEXT_NONE)
+ {
+ if (no_trans_left != 0)
+ {
+ loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ break;
+ }
+ if (trans.isat_np != ISAKMP_NEXT_T)
+ {
+ loglog(RC_LOG_SERIOUS, "unexpected %s payload in Oakley Proposal"
+ , enum_show(&payload_names, proposal->isap_np));
+ return BAD_PROPOSAL_SYNTAX;
+ }
}
- }
- loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform");
- return NO_PROPOSAL_CHOSEN;
+ loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform");
+ return NO_PROPOSAL_CHOSEN;
}
/* Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode).
@@ -1315,14 +1316,14 @@ parse_isakmp_sa_body(u_int32_t ipsecdoisit
*/
static const struct ipsec_trans_attrs null_ipsec_trans_attrs = {
- 0, /* transid (NULL, for now) */
- 0, /* spi */
- SA_LIFE_DURATION_DEFAULT, /* life_seconds */
- SA_LIFE_DURATION_K_DEFAULT, /* life_kilobytes */
- ENCAPSULATION_MODE_UNSPECIFIED, /* encapsulation */
- AUTH_ALGORITHM_NONE, /* auth */
- 0, /* key_len */
- 0, /* key_rounds */
+ 0, /* transid (NULL, for now) */
+ 0, /* spi */
+ SA_LIFE_DURATION_DEFAULT, /* life_seconds */
+ SA_LIFE_DURATION_K_DEFAULT, /* life_kilobytes */
+ ENCAPSULATION_MODE_UNSPECIFIED, /* encapsulation */
+ AUTH_ALGORITHM_NONE, /* auth */
+ 0, /* key_len */
+ 0, /* key_rounds */
};
static bool
@@ -1331,988 +1332,988 @@ parse_ipsec_transform(struct isakmp_transform *trans
, pb_stream *prop_pbs
, pb_stream *trans_pbs
, struct_desc *trans_desc
-, int previous_transnum /* or -1 if none */
+, int previous_transnum /* or -1 if none */
, bool selection
, bool is_last
, bool is_ipcomp
-, struct state *st) /* current state object */
+, struct state *st) /* current state object */
{
- lset_t seen_attrs = 0;
- lset_t seen_durations = 0;
- u_int16_t life_type = 0;
- const struct oakley_group_desc *pfs_group = NULL;
-
- if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
- return FALSE;
-
- if (trans->isat_transnum <= previous_transnum)
- {
- loglog(RC_LOG_SERIOUS, "Transform Numbers in Proposal are not monotonically increasing");
- return FALSE;
- }
-
- switch (trans->isat_np)
- {
- case ISAKMP_NEXT_T:
- if (is_last)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload has more Transforms than specified");
- return FALSE;
- }
- break;
- case ISAKMP_NEXT_NONE:
- if (!is_last)
- {
- loglog(RC_LOG_SERIOUS, "Proposal Payload has fewer Transforms than specified");
- return FALSE;
- }
- break;
- default:
- loglog(RC_LOG_SERIOUS, "expecting Transform Payload, but found %s in Proposal"
- , enum_show(&payload_names, trans->isat_np));
- return FALSE;
- }
-
- *attrs = null_ipsec_trans_attrs;
- attrs->transid = trans->isat_transid;
-
- while (pbs_left(trans_pbs) != 0)
- {
- struct isakmp_attribute a;
- pb_stream attr_pbs;
- enum_names *vdesc;
- u_int32_t val; /* room for larger value */
- bool ipcomp_inappropriate = is_ipcomp; /* will get reset if OK */
-
- if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs, &attr_pbs))
- return FALSE;
-
- passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
-
- if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
- {
- loglog(RC_LOG_SERIOUS, "repeated %s attribute in IPsec Transform %u"
- , enum_show(&ipsec_attr_names, a.isaat_af_type)
- , trans->isat_transnum);
- return FALSE;
- }
-
- seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
+ lset_t seen_attrs = 0;
+ lset_t seen_durations = 0;
+ u_int16_t life_type = 0;
+ const struct dh_desc *pfs_group = NULL;
- val = a.isaat_lv;
+ if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
+ return FALSE;
- vdesc = ipsec_attr_val_descs[a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
- if (vdesc != NULL)
+ if (trans->isat_transnum <= previous_transnum)
{
- if (enum_name(vdesc, val) == NULL)
- {
- loglog(RC_LOG_SERIOUS, "invalid value %u for attribute %s in IPsec Transform"
- , (unsigned)val, enum_show(&ipsec_attr_names, a.isaat_af_type));
+ loglog(RC_LOG_SERIOUS, "Transform Numbers in Proposal are not monotonically increasing");
return FALSE;
- }
- DBG(DBG_PARSING
- , if ((a.isaat_af_type & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
- DBG_log(" [%u is %s]"
- , (unsigned)val, enum_show(vdesc, val)));
}
- switch (a.isaat_af_type)
+ switch (trans->isat_np)
{
- case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
- if (LHAS(seen_durations, val))
- {
- loglog(RC_LOG_SERIOUS, "attribute SA_LIFE_TYPE value %s repeated in message"
- , enum_show(&sa_lifetime_names, val));
- return FALSE;
- }
- seen_durations |= LELEM(val);
- life_type = val;
- break;
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- val = decode_long_duration(&attr_pbs);
- /* fall through */
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
- if (!LHAS(seen_attrs, SA_LIFE_DURATION))
- {
- loglog(RC_LOG_SERIOUS, "SA_LIFE_DURATION IPsec attribute not preceded by SA_LIFE_TYPE attribute");
- return FALSE;
- }
- seen_attrs &= ~(LELEM(SA_LIFE_DURATION) | LELEM(SA_LIFE_TYPE));
-
- switch (life_type)
- {
- case SA_LIFE_TYPE_SECONDS:
- /* silently limit duration to our maximum */
- attrs->life_seconds = val <= SA_LIFE_DURATION_MAXIMUM
- ? val : SA_LIFE_DURATION_MAXIMUM;
+ case ISAKMP_NEXT_T:
+ if (is_last)
+ {
+ loglog(RC_LOG_SERIOUS, "Proposal Payload has more Transforms than specified");
+ return FALSE;
+ }
break;
- case SA_LIFE_TYPE_KBYTES:
- attrs->life_kilobytes = val;
+ case ISAKMP_NEXT_NONE:
+ if (!is_last)
+ {
+ loglog(RC_LOG_SERIOUS, "Proposal Payload has fewer Transforms than specified");
+ return FALSE;
+ }
break;
- default:
- bad_case(life_type);
- }
- break;
- case GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
- if (is_ipcomp)
+ default:
+ loglog(RC_LOG_SERIOUS, "expecting Transform Payload, but found %s in Proposal"
+ , enum_show(&payload_names, trans->isat_np));
+ return FALSE;
+ }
+
+ *attrs = null_ipsec_trans_attrs;
+ attrs->transid = trans->isat_transid;
+
+ while (pbs_left(trans_pbs) != 0)
+ {
+ struct isakmp_attribute a;
+ pb_stream attr_pbs;
+ enum_names *vdesc;
+ u_int32_t val; /* room for larger value */
+ bool ipcomp_inappropriate = is_ipcomp; /* will get reset if OK */
+
+ if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs, &attr_pbs))
+ return FALSE;
+
+ passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);
+
+ if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))
{
- /* Accept reluctantly. Should not happen, according to
- * draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
- */
- ipcomp_inappropriate = FALSE;
- loglog(RC_COMMENT
- , "IPCA (IPcomp SA) contains GROUP_DESCRIPTION."
- " Ignoring inapproprate attribute.");
+ loglog(RC_LOG_SERIOUS, "repeated %s attribute in IPsec Transform %u"
+ , enum_show(&ipsec_attr_names, a.isaat_af_type)
+ , trans->isat_transnum);
+ return FALSE;
}
- pfs_group = lookup_group(val);
- if (pfs_group == NULL)
+
+ seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);
+
+ val = a.isaat_lv;
+
+ vdesc = ipsec_attr_val_descs[a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];
+ if (vdesc != NULL)
{
- loglog(RC_LOG_SERIOUS, "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported for PFS");
- return FALSE;
+ if (enum_name(vdesc, val) == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "invalid value %u for attribute %s in IPsec Transform"
+ , (unsigned)val, enum_show(&ipsec_attr_names, a.isaat_af_type));
+ return FALSE;
+ }
+ DBG(DBG_PARSING
+ , if ((a.isaat_af_type & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)
+ DBG_log(" [%u is %s]"
+ , (unsigned)val, enum_show(vdesc, val)));
}
- break;
- case ENCAPSULATION_MODE | ISAKMP_ATTR_AF_TV:
- ipcomp_inappropriate = FALSE;
- switch (val)
+
+ switch (a.isaat_af_type)
{
- case ENCAPSULATION_MODE_TUNNEL:
- case ENCAPSULATION_MODE_TRANSPORT:
- if (st->nat_traversal & NAT_T_DETECTED)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is not detected"
- , enum_name(&enc_mode_names, val));
- /*
- * Accept it anyway because SSH-Sentinel does not
- * use UDP_TUNNEL or UDP_TRANSPORT for the diagnostic.
- *
- * remove when SSH-Sentinel is fixed
- */
+ case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV:
+ ipcomp_inappropriate = FALSE;
+ if (LHAS(seen_durations, val))
+ {
+ loglog(RC_LOG_SERIOUS, "attribute SA_LIFE_TYPE value %s repeated in message"
+ , enum_show(&sa_lifetime_names, val));
+ return FALSE;
+ }
+ seen_durations |= LELEM(val);
+ life_type = val;
+ break;
+ case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
+ val = decode_long_duration(&attr_pbs);
+ /* fall through */
+ case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TV:
+ ipcomp_inappropriate = FALSE;
+ if (!LHAS(seen_attrs, SA_LIFE_DURATION))
+ {
+ loglog(RC_LOG_SERIOUS, "SA_LIFE_DURATION IPsec attribute not preceded by SA_LIFE_TYPE attribute");
+ return FALSE;
+ }
+ seen_attrs &= ~(LELEM(SA_LIFE_DURATION) | LELEM(SA_LIFE_TYPE));
+
+ switch (life_type)
+ {
+ case SA_LIFE_TYPE_SECONDS:
+ /* silently limit duration to our maximum */
+ attrs->life_seconds = val <= SA_LIFE_DURATION_MAXIMUM
+ ? val : SA_LIFE_DURATION_MAXIMUM;
+ break;
+ case SA_LIFE_TYPE_KBYTES:
+ attrs->life_kilobytes = val;
+ break;
+ default:
+ bad_case(life_type);
+ }
+ break;
+ case GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:
+ if (is_ipcomp)
+ {
+ /* Accept reluctantly. Should not happen, according to
+ * draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
+ */
+ ipcomp_inappropriate = FALSE;
+ loglog(RC_COMMENT
+ , "IPCA (IPcomp SA) contains GROUP_DESCRIPTION."
+ " Ignoring inapproprate attribute.");
+ }
+ pfs_group = ike_alg_get_dh_group(val);
+ if (pfs_group == NULL)
+ {
+ loglog(RC_LOG_SERIOUS, "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported for PFS");
+ return FALSE;
+ }
+ break;
+ case ENCAPSULATION_MODE | ISAKMP_ATTR_AF_TV:
+ ipcomp_inappropriate = FALSE;
+ switch (val)
+ {
+ case ENCAPSULATION_MODE_TUNNEL:
+ case ENCAPSULATION_MODE_TRANSPORT:
+ if (st->nat_traversal & NAT_T_DETECTED)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "%s must only be used if NAT-Traversal is not detected"
+ , enum_name(&enc_mode_names, val));
+ /*
+ * Accept it anyway because SSH-Sentinel does not
+ * use UDP_TUNNEL or UDP_TRANSPORT for the diagnostic.
+ *
+ * remove when SSH-Sentinel is fixed
+ */
#ifdef I_DONT_CARE_OF_SSH_SENTINEL
- return FALSE;
+ return FALSE;
#endif
- }
- attrs->encapsulation = val;
- break;
- case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS:
+ }
+ attrs->encapsulation = val;
+ break;
+ case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS:
#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- loglog(RC_LOG_SERIOUS
- , "NAT-Traversal: Transport mode disabled due to security concerns");
- return FALSE;
+ loglog(RC_LOG_SERIOUS
+ , "NAT-Traversal: Transport mode disabled due to security concerns");
+ return FALSE;
#endif
- case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS:
- if (st->nat_traversal & NAT_T_WITH_RFC_VALUES)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used with old IETF drafts"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- else if (st->nat_traversal & NAT_T_DETECTED)
- {
- attrs->encapsulation = val
- - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS
- + ENCAPSULATION_MODE_TUNNEL;
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is detected"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- break;
- case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC:
+ case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS:
+ if (st->nat_traversal & NAT_T_WITH_RFC_VALUES)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "%s must only be used with old IETF drafts"
+ , enum_name(&enc_mode_names, val));
+ return FALSE;
+ }
+ else if (st->nat_traversal & NAT_T_DETECTED)
+ {
+ attrs->encapsulation = val
+ - ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS
+ + ENCAPSULATION_MODE_TUNNEL;
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS
+ , "%s must only be used if NAT-Traversal is detected"
+ , enum_name(&enc_mode_names, val));
+ return FALSE;
+ }
+ break;
+ case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC:
#ifndef I_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
- loglog(RC_LOG_SERIOUS
- , "NAT-Traversal: Transport mode disabled due "
- "to security concerns");
- return FALSE;
+ loglog(RC_LOG_SERIOUS
+ , "NAT-Traversal: Transport mode disabled due "
+ "to security concerns");
+ return FALSE;
#endif
- case ENCAPSULATION_MODE_UDP_TUNNEL_RFC:
- if ((st->nat_traversal & NAT_T_DETECTED)
- && (st->nat_traversal & NAT_T_WITH_RFC_VALUES))
- {
- attrs->encapsulation = val
- - ENCAPSULATION_MODE_UDP_TUNNEL_RFC
- + ENCAPSULATION_MODE_TUNNEL;
- }
- else if (st->nat_traversal & NAT_T_DETECTED)
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used with NAT-T RFC"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- else
- {
- loglog(RC_LOG_SERIOUS
- , "%s must only be used if NAT-Traversal is detected"
- , enum_name(&enc_mode_names, val));
- return FALSE;
- }
- break;
- default:
- loglog(RC_LOG_SERIOUS
- , "unknown ENCAPSULATION_MODE %d in IPSec SA", val);
- return FALSE;
- }
- break;
- case AUTH_ALGORITHM | ISAKMP_ATTR_AF_TV:
- attrs->auth = val;
- break;
- case KEY_LENGTH | ISAKMP_ATTR_AF_TV:
- attrs->key_len = val;
- break;
- case KEY_ROUNDS | ISAKMP_ATTR_AF_TV:
- attrs->key_rounds = val;
- break;
+ case ENCAPSULATION_MODE_UDP_TUNNEL_RFC:
+ if ((st->nat_traversal & NAT_T_DETECTED)
+ && (st->nat_traversal & NAT_T_WITH_RFC_VALUES))
+ {
+ attrs->encapsulation = val
+ - ENCAPSULATION_MODE_UDP_TUNNEL_RFC
+ + ENCAPSULATION_MODE_TUNNEL;
+ }
+ else if (st->nat_traversal & NAT_T_DETECTED)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "%s must only be used with NAT-T RFC"
+ , enum_name(&enc_mode_names, val));
+ return FALSE;
+ }
+ else
+ {
+ loglog(RC_LOG_SERIOUS
+ , "%s must only be used if NAT-Traversal is detected"
+ , enum_name(&enc_mode_names, val));
+ return FALSE;
+ }
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS
+ , "unknown ENCAPSULATION_MODE %d in IPSec SA", val);
+ return FALSE;
+ }
+ break;
+ case AUTH_ALGORITHM | ISAKMP_ATTR_AF_TV:
+ attrs->auth = val;
+ break;
+ case KEY_LENGTH | ISAKMP_ATTR_AF_TV:
+ attrs->key_len = val;
+ break;
+ case KEY_ROUNDS | ISAKMP_ATTR_AF_TV:
+ attrs->key_rounds = val;
+ break;
#if 0 /* not yet implemented */
- case COMPRESS_DICT_SIZE | ISAKMP_ATTR_AF_TV:
- break;
- case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TV:
- break;
-
- case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
- break;
- case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TLV:
- break;
+ case COMPRESS_DICT_SIZE | ISAKMP_ATTR_AF_TV:
+ break;
+ case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TV:
+ break;
+
+ case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:
+ break;
+ case COMPRESS_PRIVATE_ALG | ISAKMP_ATTR_AF_TLV:
+ break;
#endif
- default:
- loglog(RC_LOG_SERIOUS, "unsupported IPsec attribute %s"
- , enum_show(&ipsec_attr_names, a.isaat_af_type));
- return FALSE;
- }
- if (ipcomp_inappropriate)
- {
- loglog(RC_LOG_SERIOUS, "IPsec attribute %s inappropriate for IPCOMP"
- , enum_show(&ipsec_attr_names, a.isaat_af_type));
- return FALSE;
+ default:
+ loglog(RC_LOG_SERIOUS, "unsupported IPsec attribute %s"
+ , enum_show(&ipsec_attr_names, a.isaat_af_type));
+ return FALSE;
+ }
+ if (ipcomp_inappropriate)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec attribute %s inappropriate for IPCOMP"
+ , enum_show(&ipsec_attr_names, a.isaat_af_type));
+ return FALSE;
+ }
}
- }
-
- /* Although an IPCOMP SA (IPCA) ought not to have a pfs_group,
- * if it does, demand that it be consistent.
- * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
- */
- if (!is_ipcomp || pfs_group != NULL)
- {
- if (st->st_pfs_group == &unset_group)
- st->st_pfs_group = pfs_group;
-
- if (st->st_pfs_group != pfs_group)
+
+ /* Although an IPCOMP SA (IPCA) ought not to have a pfs_group,
+ * if it does, demand that it be consistent.
+ * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
+ */
+ if (!is_ipcomp || pfs_group != NULL)
{
- loglog(RC_LOG_SERIOUS, "GROUP_DESCRIPTION inconsistent with that of %s in IPsec SA"
- , selection? "the Proposal" : "a previous Transform");
- return FALSE;
- }
- }
+ if (st->st_pfs_group == &unset_group)
+ st->st_pfs_group = pfs_group;
- if (LHAS(seen_attrs, SA_LIFE_DURATION))
- {
- loglog(RC_LOG_SERIOUS, "SA_LIFE_TYPE IPsec attribute not followed by SA_LIFE_DURATION attribute in message");
- return FALSE;
- }
+ if (st->st_pfs_group != pfs_group)
+ {
+ loglog(RC_LOG_SERIOUS, "GROUP_DESCRIPTION inconsistent with that of %s in IPsec SA"
+ , selection? "the Proposal" : "a previous Transform");
+ return FALSE;
+ }
+ }
- if (!LHAS(seen_attrs, ENCAPSULATION_MODE))
- {
- if (is_ipcomp)
+ if (LHAS(seen_attrs, SA_LIFE_DURATION))
{
- /* draft-shacham-ippcp-rfc2393bis-05.txt 4.1:
- * "If the Encapsulation Mode is unspecified,
- * the default value of Transport Mode is assumed."
- * This contradicts/overrides the DOI (quuoted below).
- */
- attrs->encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ loglog(RC_LOG_SERIOUS, "SA_LIFE_TYPE IPsec attribute not followed by SA_LIFE_DURATION attribute in message");
+ return FALSE;
}
- else
+
+ if (!LHAS(seen_attrs, ENCAPSULATION_MODE))
{
- /* ??? Technically, RFC 2407 (IPSEC DOI) 4.5 specifies that
- * the default is "unspecified (host-dependent)".
- * This makes little sense, so we demand that it be specified.
- */
- loglog(RC_LOG_SERIOUS, "IPsec Transform must specify ENCAPSULATION_MODE");
- return FALSE;
+ if (is_ipcomp)
+ {
+ /* draft-shacham-ippcp-rfc2393bis-05.txt 4.1:
+ * "If the Encapsulation Mode is unspecified,
+ * the default value of Transport Mode is assumed."
+ * This contradicts/overrides the DOI (quuoted below).
+ */
+ attrs->encapsulation = ENCAPSULATION_MODE_TRANSPORT;
+ }
+ else
+ {
+ /* ??? Technically, RFC 2407 (IPSEC DOI) 4.5 specifies that
+ * the default is "unspecified (host-dependent)".
+ * This makes little sense, so we demand that it be specified.
+ */
+ loglog(RC_LOG_SERIOUS, "IPsec Transform must specify ENCAPSULATION_MODE");
+ return FALSE;
+ }
}
- }
- /* ??? should check for key_len and/or key_rounds if required */
+ /* ??? should check for key_len and/or key_rounds if required */
- return TRUE;
+ return TRUE;
}
static void
echo_proposal(
- struct isakmp_proposal r_proposal, /* proposal to emit */
- struct isakmp_transform r_trans, /* winning transformation within it */
- u_int8_t np, /* Next Payload for proposal */
- pb_stream *r_sa_pbs, /* SA PBS into which to emit */
- struct ipsec_proto_info *pi, /* info about this protocol instance */
- struct_desc *trans_desc, /* descriptor for this transformation */
- pb_stream *trans_pbs, /* PBS for incoming transform */
- struct spd_route *sr, /* host details for the association */
- bool tunnel_mode) /* true for inner most tunnel SA */
+ struct isakmp_proposal r_proposal, /* proposal to emit */
+ struct isakmp_transform r_trans, /* winning transformation within it */
+ u_int8_t np, /* Next Payload for proposal */
+ pb_stream *r_sa_pbs, /* SA PBS into which to emit */
+ struct ipsec_proto_info *pi, /* info about this protocol instance */
+ struct_desc *trans_desc, /* descriptor for this transformation */
+ pb_stream *trans_pbs, /* PBS for incoming transform */
+ struct spd_route *sr, /* host details for the association */
+ bool tunnel_mode) /* true for inner most tunnel SA */
{
- pb_stream r_proposal_pbs;
- pb_stream r_trans_pbs;
-
- /* Proposal */
- r_proposal.isap_np = np;
- r_proposal.isap_notrans = 1;
- if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
- impossible();
-
- /* allocate and emit our CPI/SPI */
- if (r_proposal.isap_protoid == PROTO_IPCOMP)
- {
- /* CPI is stored in network low order end of an
- * ipsec_spi_t. So we start a couple of bytes in.
- * Note: we may fail to generate a satisfactory CPI,
- * but we'll ignore that.
- */
- pi->our_spi = get_my_cpi(sr, tunnel_mode);
- out_raw((u_char *) &pi->our_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE
- , &r_proposal_pbs, "CPI");
- }
- else
- {
- pi->our_spi = get_ipsec_spi(pi->attrs.spi
- , r_proposal.isap_protoid == PROTO_IPSEC_AH ?
- IPPROTO_AH : IPPROTO_ESP
- , sr
- , tunnel_mode);
- /* XXX should check for errors */
- out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE
- , &r_proposal_pbs, "SPI");
- }
-
- /* Transform */
- r_trans.isat_np = ISAKMP_NEXT_NONE;
- if (!out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs))
- impossible();
-
- /* Transform Attributes: pure echo */
- trans_pbs->cur = trans_pbs->start + sizeof(struct isakmp_transform);
- if (!out_raw(trans_pbs->cur, pbs_left(trans_pbs)
- , &r_trans_pbs, "attributes"))
- impossible();
-
- close_output_pbs(&r_trans_pbs);
- close_output_pbs(&r_proposal_pbs);
-}
+ pb_stream r_proposal_pbs;
+ pb_stream r_trans_pbs;
-notification_t
-parse_ipsec_sa_body(
- pb_stream *sa_pbs, /* body of input SA Payload */
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit body of winning SA */
- bool selection, /* if this SA is a selection, only one transform may appear */
- struct state *st) /* current state object */
-{
- const struct connection *c = st->st_connection;
- u_int32_t ipsecdoisit;
- pb_stream next_proposal_pbs;
-
- struct isakmp_proposal next_proposal;
- ipsec_spi_t next_spi;
-
- bool next_full = TRUE;
-
- /* DOI */
- if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
- {
- loglog(RC_LOG_SERIOUS, "Unknown or unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
- /* XXX Could send notification back */
- return DOI_NOT_SUPPORTED;
- }
-
- /* Situation */
- if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
- return SITUATION_NOT_SUPPORTED;
-
- if (ipsecdoisit != SIT_IDENTITY_ONLY)
- {
- loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
- , bitnamesof(sit_bit_names, ipsecdoisit));
- /* XXX Could send notification back */
- return SITUATION_NOT_SUPPORTED;
- }
-
- /* The rules for IPsec SAs are scattered.
- * RFC 2408 "ISAKMP" section 4.2 gives some info.
- * There may be multiple proposals. Those with identical proposal
- * numbers must be considered as conjuncts. Those with different
- * numbers are disjuncts.
- * Each proposal may have several transforms, each considered
- * an alternative.
- * Each transform may have several attributes, all applying.
- *
- * To handle the way proposals are combined, we need to do a
- * look-ahead.
- */
-
- if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
- return BAD_PROPOSAL_SYNTAX;
-
- /* for each conjunction of proposals... */
- while (next_full)
- {
- int propno = next_proposal.isap_proposal;
- pb_stream ah_prop_pbs, esp_prop_pbs, ipcomp_prop_pbs;
- struct isakmp_proposal ah_proposal = {0, 0, 0, 0, 0, 0, 0};
- struct isakmp_proposal esp_proposal = {0, 0, 0, 0, 0, 0, 0};
- struct isakmp_proposal ipcomp_proposal = {0, 0, 0, 0, 0, 0, 0};
- ipsec_spi_t ah_spi = 0;
- ipsec_spi_t esp_spi = 0;
- ipsec_spi_t ipcomp_cpi = 0;
- bool ah_seen = FALSE;
- bool esp_seen = FALSE;
- bool ipcomp_seen = FALSE;
- bool tunnel_mode = FALSE;
- int inner_proto = 0;
- u_int16_t well_known_cpi = 0;
-
- pb_stream ah_trans_pbs, esp_trans_pbs, ipcomp_trans_pbs;
- struct isakmp_transform ah_trans, esp_trans, ipcomp_trans;
- struct ipsec_trans_attrs ah_attrs, esp_attrs, ipcomp_attrs;
-
- /* for each proposal in the conjunction */
- do {
-
- if (next_proposal.isap_protoid == PROTO_IPCOMP)
- {
- /* IPCOMP CPI */
- if (next_proposal.isap_spisize == IPSEC_DOI_SPI_SIZE)
- {
- /* This code is to accommodate those peculiar
- * implementations that send a CPI in the bottom of an
- * SPI-sized field.
- * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1
- */
- u_int8_t filler[IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE];
-
- if (!in_raw(filler, sizeof(filler)
- , &next_proposal_pbs, "CPI filler")
- || !all_zero(filler, sizeof(filler)))
- return INVALID_SPI;
- }
- else if (next_proposal.isap_spisize != IPCOMP_CPI_SIZE)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper CPI size (%u)"
- , next_proposal.isap_spisize);
- return INVALID_SPI;
- }
+ /* Proposal */
+ r_proposal.isap_np = np;
+ r_proposal.isap_notrans = 1;
+ if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))
+ impossible();
- /* We store CPI in the low order of a network order
+ /* allocate and emit our CPI/SPI */
+ if (r_proposal.isap_protoid == PROTO_IPCOMP)
+ {
+ /* CPI is stored in network low order end of an
* ipsec_spi_t. So we start a couple of bytes in.
+ * Note: we may fail to generate a satisfactory CPI,
+ * but we'll ignore that.
*/
- zero(&next_spi);
- if (!in_raw((u_char *)&next_spi
- + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
- , IPCOMP_CPI_SIZE, &next_proposal_pbs, "CPI"))
- return INVALID_SPI;
-
- /* If sanity ruled, CPIs would have to be such that
- * the SAID (the triple (CPI, IPCOM, destination IP))
- * would be unique, just like for SPIs. But there is a
- * perversion where CPIs can be well-known and consequently
- * the triple is not unique. We hide this fact from
- * ourselves by fudging the top 16 bits to make
- * the property true internally!
- */
- switch (ntohl(next_spi))
- {
- case IPCOMP_DEFLATE:
- well_known_cpi = ntohl(next_spi);
- next_spi = uniquify_his_cpi(next_spi, st);
- if (next_spi == 0)
- {
- loglog(RC_LOG_SERIOUS
- , "IPsec Proposal contains well-known CPI that I cannot uniquify");
- return INVALID_SPI;
- }
- break;
- default:
- if (ntohl(next_spi) < IPCOMP_FIRST_NEGOTIATED
- || ntohl(next_spi) > IPCOMP_LAST_NEGOTIATED)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains CPI from non-negotiated range (0x%lx)"
- , (unsigned long) ntohl(next_spi));
- return INVALID_SPI;
- }
- break;
- }
- }
- else
- {
- /* AH or ESP SPI */
- if (next_proposal.isap_spisize != IPSEC_DOI_SPI_SIZE)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper SPI size (%u)"
- , next_proposal.isap_spisize);
- return INVALID_SPI;
- }
-
- if (!in_raw((u_char *)&next_spi, sizeof(next_spi), &next_proposal_pbs, "SPI"))
- return INVALID_SPI;
+ pi->our_spi = get_my_cpi(sr, tunnel_mode);
+ out_raw((u_char *) &pi->our_spi
+ + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
+ , IPCOMP_CPI_SIZE
+ , &r_proposal_pbs, "CPI");
+ }
+ else
+ {
+ pi->our_spi = get_ipsec_spi(pi->attrs.spi
+ , r_proposal.isap_protoid == PROTO_IPSEC_AH ?
+ IPPROTO_AH : IPPROTO_ESP
+ , sr
+ , tunnel_mode);
+ /* XXX should check for errors */
+ out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE
+ , &r_proposal_pbs, "SPI");
+ }
- /* SPI value 0 is invalid and values 1-255 are reserved to IANA.
- * RFC 2402 (ESP) 2.4, RFC 2406 (AH) 2.1
- * IPCOMP???
- */
- if (ntohl(next_spi) < IPSEC_DOI_SPI_MIN)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains invalid SPI (0x%lx)"
- , (unsigned long) ntohl(next_spi));
- return INVALID_SPI;
- }
- }
+ /* Transform */
+ r_trans.isat_np = ISAKMP_NEXT_NONE;
+ if (!out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs))
+ impossible();
- if (next_proposal.isap_notrans == 0)
- {
- loglog(RC_LOG_SERIOUS, "IPsec Proposal contains no Transforms");
- return BAD_PROPOSAL_SYNTAX;
- }
+ /* Transform Attributes: pure echo */
+ trans_pbs->cur = trans_pbs->start + sizeof(struct isakmp_transform);
+ if (!out_raw(trans_pbs->cur, pbs_left(trans_pbs)
+ , &r_trans_pbs, "attributes"))
+ impossible();
- switch (next_proposal.isap_protoid)
- {
- case PROTO_IPSEC_AH:
- if (ah_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous AH Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- ah_seen = TRUE;
- ah_prop_pbs = next_proposal_pbs;
- ah_proposal = next_proposal;
- ah_spi = next_spi;
- break;
+ close_output_pbs(&r_trans_pbs);
+ close_output_pbs(&r_proposal_pbs);
+}
- case PROTO_IPSEC_ESP:
- if (esp_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous ESP Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- esp_seen = TRUE;
- esp_prop_pbs = next_proposal_pbs;
- esp_proposal = next_proposal;
- esp_spi = next_spi;
- break;
+notification_t
+parse_ipsec_sa_body(
+ pb_stream *sa_pbs, /* body of input SA Payload */
+ const struct isakmp_sa *sa, /* header of input SA Payload */
+ pb_stream *r_sa_pbs, /* if non-NULL, where to emit body of winning SA */
+ bool selection, /* if this SA is a selection, only one transform may appear */
+ struct state *st) /* current state object */
+{
+ const struct connection *c = st->st_connection;
+ u_int32_t ipsecdoisit;
+ pb_stream next_proposal_pbs;
- case PROTO_IPCOMP:
- if (ipcomp_seen)
- {
- loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous IPCOMP Proposals");
- return BAD_PROPOSAL_SYNTAX;
- }
- ipcomp_seen = TRUE;
- ipcomp_prop_pbs = next_proposal_pbs;
- ipcomp_proposal = next_proposal;
- ipcomp_cpi = next_spi;
- break;
-
- default:
- loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) in IPsec Proposal"
- , enum_show(&protocol_names, next_proposal.isap_protoid));
- return INVALID_PROTOCOL_ID;
- }
-
- /* refill next_proposal */
- if (next_proposal.isap_np == ISAKMP_NEXT_NONE)
- {
- next_full = FALSE;
- break;
- }
- else if (next_proposal.isap_np != ISAKMP_NEXT_P)
- {
- loglog(RC_LOG_SERIOUS, "unexpected in Proposal: %s"
- , enum_show(&payload_names, next_proposal.isap_np));
- return BAD_PROPOSAL_SYNTAX;
- }
+ struct isakmp_proposal next_proposal;
+ ipsec_spi_t next_spi;
- if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
- return BAD_PROPOSAL_SYNTAX;
- } while (next_proposal.isap_proposal == propno);
-
- /* Now that we have all conjuncts, we should try
- * the Cartesian product of eachs tranforms!
- * At the moment, we take short-cuts on account of
- * our rudimentary hard-wired policy.
- * For now, we find an acceptable AH (if any)
- * and then an acceptable ESP. The only interaction
- * is that the ESP acceptance can know whether there
- * was an acceptable AH and hence not require an AUTH.
- */
+ bool next_full = TRUE;
- if (ah_seen)
+ /* DOI */
+ if (sa->isasa_doi != ISAKMP_DOI_IPSEC)
{
- int previous_transnum = -1;
- int tn;
-
- for (tn = 0; tn != ah_proposal.isap_notrans; tn++)
- {
- int ok_transid = 0;
- bool ok_auth = FALSE;
-
- if (!parse_ipsec_transform(&ah_trans
- , &ah_attrs
- , &ah_prop_pbs
- , &ah_trans_pbs
- , &isakmp_ah_transform_desc
- , previous_transnum
- , selection
- , tn == ah_proposal.isap_notrans - 1
- , FALSE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = ah_trans.isat_transnum;
-
- /* we must understand ah_attrs.transid
- * COMBINED with ah_attrs.auth.
- * See RFC 2407 "IPsec DOI" section 4.4.3
- * The following combinations are legal,
- * but we don't implement all of them:
- * It seems as if each auth algorithm
- * only applies to one ah transid.
- * AH_MD5, AUTH_ALGORITHM_HMAC_MD5
- * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)
- * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1
- * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)
- */
- switch (ah_attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- loglog(RC_LOG_SERIOUS, "AUTH_ALGORITHM attribute missing in AH Transform");
- return BAD_PROPOSAL_SYNTAX;
+ loglog(RC_LOG_SERIOUS, "Unknown or unsupported DOI %s", enum_show(&doi_names, sa->isasa_doi));
+ /* XXX Could send notification back */
+ return DOI_NOT_SUPPORTED;
+ }
- case AUTH_ALGORITHM_HMAC_MD5:
- ok_auth = TRUE;
- /* fall through */
- case AUTH_ALGORITHM_KPDK:
- ok_transid = AH_MD5;
- break;
+ /* Situation */
+ if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
+ return SITUATION_NOT_SUPPORTED;
- case AUTH_ALGORITHM_HMAC_SHA1:
- ok_auth = TRUE;
- ok_transid = AH_SHA;
- break;
-
- case AUTH_ALGORITHM_DES_MAC:
- ok_transid = AH_DES;
- break;
- }
- if (ah_attrs.transid != ok_transid)
- {
- loglog(RC_LOG_SERIOUS, "%s attribute inappropriate in %s Transform"
- , enum_name(&auth_alg_names, ah_attrs.auth)
- , enum_show(&ah_transformid_names, ah_attrs.transid));
- return BAD_PROPOSAL_SYNTAX;
- }
- if (!ok_auth)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("%s attribute unsupported"
- " in %s Transform from %s"
- , enum_name(&auth_alg_names, ah_attrs.auth)
- , enum_show(&ah_transformid_names, ah_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- break; /* we seem to be happy */
- }
- if (tn == ah_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
- ah_attrs.spi = ah_spi;
- inner_proto = IPPROTO_AH;
- if (ah_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
+ if (ipsecdoisit != SIT_IDENTITY_ONLY)
+ {
+ loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)"
+ , bitnamesof(sit_bit_names, ipsecdoisit));
+ /* XXX Could send notification back */
+ return SITUATION_NOT_SUPPORTED;
}
- if (esp_seen)
+ /* The rules for IPsec SAs are scattered.
+ * RFC 2408 "ISAKMP" section 4.2 gives some info.
+ * There may be multiple proposals. Those with identical proposal
+ * numbers must be considered as conjuncts. Those with different
+ * numbers are disjuncts.
+ * Each proposal may have several transforms, each considered
+ * an alternative.
+ * Each transform may have several attributes, all applying.
+ *
+ * To handle the way proposals are combined, we need to do a
+ * look-ahead.
+ */
+
+ if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
+ return BAD_PROPOSAL_SYNTAX;
+
+ /* for each conjunction of proposals... */
+ while (next_full)
{
- int previous_transnum = -1;
- int tn;
-
- for (tn = 0; tn != esp_proposal.isap_notrans; tn++)
- {
- if (!parse_ipsec_transform(&esp_trans
- , &esp_attrs
- , &esp_prop_pbs
- , &esp_trans_pbs
- , &isakmp_esp_transform_desc
- , previous_transnum
- , selection
- , tn == esp_proposal.isap_notrans - 1
- , FALSE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = esp_trans.isat_transnum;
-
- /* set default key length for AES encryption */
- if (!esp_attrs.key_len && esp_attrs.transid == ESP_AES)
- {
- esp_attrs.key_len = 128; /* bits */
- }
+ int propno = next_proposal.isap_proposal;
+ pb_stream ah_prop_pbs, esp_prop_pbs, ipcomp_prop_pbs;
+ struct isakmp_proposal ah_proposal = {0, 0, 0, 0, 0, 0, 0};
+ struct isakmp_proposal esp_proposal = {0, 0, 0, 0, 0, 0, 0};
+ struct isakmp_proposal ipcomp_proposal = {0, 0, 0, 0, 0, 0, 0};
+ ipsec_spi_t ah_spi = 0;
+ ipsec_spi_t esp_spi = 0;
+ ipsec_spi_t ipcomp_cpi = 0;
+ bool ah_seen = FALSE;
+ bool esp_seen = FALSE;
+ bool ipcomp_seen = FALSE;
+ bool tunnel_mode = FALSE;
+ int inner_proto = 0;
+ u_int16_t well_known_cpi = 0;
+
+ pb_stream ah_trans_pbs, esp_trans_pbs, ipcomp_trans_pbs;
+ struct isakmp_transform ah_trans, esp_trans, ipcomp_trans;
+ struct ipsec_trans_attrs ah_attrs, esp_attrs, ipcomp_attrs;
+
+ /* for each proposal in the conjunction */
+ do {
+
+ if (next_proposal.isap_protoid == PROTO_IPCOMP)
+ {
+ /* IPCOMP CPI */
+ if (next_proposal.isap_spisize == IPSEC_DOI_SPI_SIZE)
+ {
+ /* This code is to accommodate those peculiar
+ * implementations that send a CPI in the bottom of an
+ * SPI-sized field.
+ * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1
+ */
+ u_int8_t filler[IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE];
+
+ if (!in_raw(filler, sizeof(filler)
+ , &next_proposal_pbs, "CPI filler")
+ || !all_zero(filler, sizeof(filler)))
+ return INVALID_SPI;
+ }
+ else if (next_proposal.isap_spisize != IPCOMP_CPI_SIZE)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper CPI size (%u)"
+ , next_proposal.isap_spisize);
+ return INVALID_SPI;
+ }
+
+ /* We store CPI in the low order of a network order
+ * ipsec_spi_t. So we start a couple of bytes in.
+ */
+ zero(&next_spi);
+ if (!in_raw((u_char *)&next_spi
+ + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE
+ , IPCOMP_CPI_SIZE, &next_proposal_pbs, "CPI"))
+ return INVALID_SPI;
+
+ /* If sanity ruled, CPIs would have to be such that
+ * the SAID (the triple (CPI, IPCOM, destination IP))
+ * would be unique, just like for SPIs. But there is a
+ * perversion where CPIs can be well-known and consequently
+ * the triple is not unique. We hide this fact from
+ * ourselves by fudging the top 16 bits to make
+ * the property true internally!
+ */
+ switch (ntohl(next_spi))
+ {
+ case IPCOMP_DEFLATE:
+ well_known_cpi = ntohl(next_spi);
+ next_spi = uniquify_his_cpi(next_spi, st);
+ if (next_spi == 0)
+ {
+ loglog(RC_LOG_SERIOUS
+ , "IPsec Proposal contains well-known CPI that I cannot uniquify");
+ return INVALID_SPI;
+ }
+ break;
+ default:
+ if (ntohl(next_spi) < IPCOMP_FIRST_NEGOTIATED
+ || ntohl(next_spi) > IPCOMP_LAST_NEGOTIATED)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec Proposal contains CPI from non-negotiated range (0x%lx)"
+ , (unsigned long) ntohl(next_spi));
+ return INVALID_SPI;
+ }
+ break;
+ }
+ }
+ else
+ {
+ /* AH or ESP SPI */
+ if (next_proposal.isap_spisize != IPSEC_DOI_SPI_SIZE)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec Proposal with improper SPI size (%u)"
+ , next_proposal.isap_spisize);
+ return INVALID_SPI;
+ }
+
+ if (!in_raw((u_char *)&next_spi, sizeof(next_spi), &next_proposal_pbs, "SPI"))
+ return INVALID_SPI;
+
+ /* SPI value 0 is invalid and values 1-255 are reserved to IANA.
+ * RFC 2402 (ESP) 2.4, RFC 2406 (AH) 2.1
+ * IPCOMP???
+ */
+ if (ntohl(next_spi) < IPSEC_DOI_SPI_MIN)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec Proposal contains invalid SPI (0x%lx)"
+ , (unsigned long) ntohl(next_spi));
+ return INVALID_SPI;
+ }
+ }
- if (!kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len
- ,c->alg_info_esp))
- {
- switch (esp_attrs.transid)
- {
- case ESP_3DES:
- break;
-#ifdef SUPPORT_ESP_NULL /* should be about as secure as AH-only */
- case ESP_NULL:
- if (esp_attrs.auth == AUTH_ALGORITHM_NONE)
+ if (next_proposal.isap_notrans == 0)
{
- loglog(RC_LOG_SERIOUS, "ESP_NULL requires auth algorithm");
- return BAD_PROPOSAL_SYNTAX;
+ loglog(RC_LOG_SERIOUS, "IPsec Proposal contains no Transforms");
+ return BAD_PROPOSAL_SYNTAX;
}
- if (st->st_policy & POLICY_ENCRYPT)
+
+ switch (next_proposal.isap_protoid)
{
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP_NULL Transform Proposal from %s"
- " does not satisfy POLICY_ENCRYPT"
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
+ case PROTO_IPSEC_AH:
+ if (ah_seen)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous AH Proposals");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ ah_seen = TRUE;
+ ah_prop_pbs = next_proposal_pbs;
+ ah_proposal = next_proposal;
+ ah_spi = next_spi;
+ break;
+
+ case PROTO_IPSEC_ESP:
+ if (esp_seen)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous ESP Proposals");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ esp_seen = TRUE;
+ esp_prop_pbs = next_proposal_pbs;
+ esp_proposal = next_proposal;
+ esp_spi = next_spi;
+ break;
+
+ case PROTO_IPCOMP:
+ if (ipcomp_seen)
+ {
+ loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous IPCOMP Proposals");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ ipcomp_seen = TRUE;
+ ipcomp_prop_pbs = next_proposal_pbs;
+ ipcomp_proposal = next_proposal;
+ ipcomp_cpi = next_spi;
+ break;
+
+ default:
+ loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) in IPsec Proposal"
+ , enum_show(&protocol_names, next_proposal.isap_protoid));
+ return INVALID_PROTOCOL_ID;
}
- break;
-#endif
- default:
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported ESP Transform %s from %s"
- , enum_show(&esp_transformid_names, esp_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- }
- if (!kernel_alg_esp_auth_ok(esp_attrs.auth, c->alg_info_esp))
- {
- switch (esp_attrs.auth)
- {
- case AUTH_ALGORITHM_NONE:
- if (!ah_seen)
+ /* refill next_proposal */
+ if (next_proposal.isap_np == ISAKMP_NEXT_NONE)
{
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP from %s must either have AUTH or be combined with AH"
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
+ next_full = FALSE;
+ break;
+ }
+ else if (next_proposal.isap_np != ISAKMP_NEXT_P)
+ {
+ loglog(RC_LOG_SERIOUS, "unexpected in Proposal: %s"
+ , enum_show(&payload_names, next_proposal.isap_np));
+ return BAD_PROPOSAL_SYNTAX;
}
- break;
- case AUTH_ALGORITHM_HMAC_MD5:
- case AUTH_ALGORITHM_HMAC_SHA1:
- break;
- default:
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported ESP auth alg %s from %s"
- , enum_show(&auth_alg_names, esp_attrs.auth)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
- }
- }
- /* A last check for allowed transforms in alg_info_esp
- * (ALG_INFO_F_STRICT flag)
+ if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))
+ return BAD_PROPOSAL_SYNTAX;
+ } while (next_proposal.isap_proposal == propno);
+
+ /* Now that we have all conjuncts, we should try
+ * the Cartesian product of eachs tranforms!
+ * At the moment, we take short-cuts on account of
+ * our rudimentary hard-wired policy.
+ * For now, we find an acceptable AH (if any)
+ * and then an acceptable ESP. The only interaction
+ * is that the ESP acceptance can know whether there
+ * was an acceptable AH and hence not require an AUTH.
*/
- if (!kernel_alg_esp_ok_final(esp_attrs.transid, esp_attrs.key_len
- ,esp_attrs.auth, c->alg_info_esp))
- {
- continue;
- }
- if (ah_seen && ah_attrs.encapsulation != esp_attrs.encapsulation)
+ if (ah_seen)
{
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("AH and ESP transforms disagree about encapsulation; TUNNEL presumed"));
+ int previous_transnum = -1;
+ int tn;
+
+ for (tn = 0; tn != ah_proposal.isap_notrans; tn++)
+ {
+ int ok_transid = 0;
+ bool ok_auth = FALSE;
+
+ if (!parse_ipsec_transform(&ah_trans
+ , &ah_attrs
+ , &ah_prop_pbs
+ , &ah_trans_pbs
+ , &isakmp_ah_transform_desc
+ , previous_transnum
+ , selection
+ , tn == ah_proposal.isap_notrans - 1
+ , FALSE
+ , st))
+ return BAD_PROPOSAL_SYNTAX;
+
+ previous_transnum = ah_trans.isat_transnum;
+
+ /* we must understand ah_attrs.transid
+ * COMBINED with ah_attrs.auth.
+ * See RFC 2407 "IPsec DOI" section 4.4.3
+ * The following combinations are legal,
+ * but we don't implement all of them:
+ * It seems as if each auth algorithm
+ * only applies to one ah transid.
+ * AH_MD5, AUTH_ALGORITHM_HMAC_MD5
+ * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)
+ * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1
+ * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)
+ */
+ switch (ah_attrs.auth)
+ {
+ case AUTH_ALGORITHM_NONE:
+ loglog(RC_LOG_SERIOUS, "AUTH_ALGORITHM attribute missing in AH Transform");
+ return BAD_PROPOSAL_SYNTAX;
+
+ case AUTH_ALGORITHM_HMAC_MD5:
+ ok_auth = TRUE;
+ /* fall through */
+ case AUTH_ALGORITHM_KPDK:
+ ok_transid = AH_MD5;
+ break;
+
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ ok_auth = TRUE;
+ ok_transid = AH_SHA;
+ break;
+
+ case AUTH_ALGORITHM_DES_MAC:
+ ok_transid = AH_DES;
+ break;
+ }
+ if (ah_attrs.transid != ok_transid)
+ {
+ loglog(RC_LOG_SERIOUS, "%s attribute inappropriate in %s Transform"
+ , enum_name(&auth_alg_names, ah_attrs.auth)
+ , enum_show(&ah_transformid_names, ah_attrs.transid));
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ if (!ok_auth)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("%s attribute unsupported"
+ " in %s Transform from %s"
+ , enum_name(&auth_alg_names, ah_attrs.auth)
+ , enum_show(&ah_transformid_names, ah_attrs.transid)
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+ break; /* we seem to be happy */
+ }
+ if (tn == ah_proposal.isap_notrans)
+ continue; /* we didn't find a nice one */
+ ah_attrs.spi = ah_spi;
+ inner_proto = IPPROTO_AH;
+ if (ah_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ tunnel_mode = TRUE;
}
- break; /* we seem to be happy */
- }
- if (tn == esp_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
-
- esp_attrs.spi = esp_spi;
- inner_proto = IPPROTO_ESP;
- if (esp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
- }
- else if (st->st_policy & POLICY_ENCRYPT)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("policy for \"%s\" requires encryption but ESP not in Proposal from %s"
- , c->name, ip_str(&c->spd.that.host_addr)));
- continue; /* we needed encryption, but didn't find ESP */
- }
- else if ((st->st_policy & POLICY_AUTHENTICATE) && !ah_seen)
- {
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("policy for \"%s\" requires authentication"
- " but none in Proposal from %s"
- , c->name, ip_str(&c->spd.that.host_addr)));
- continue; /* we need authentication, but we found neither ESP nor AH */
- }
+ if (esp_seen)
+ {
+ int previous_transnum = -1;
+ int tn;
- if (ipcomp_seen)
- {
- int previous_transnum = -1;
- int tn;
-
-#ifdef NEVER /* we think IPcomp is working now */
- /**** FUDGE TO PREVENT UNREQUESTED IPCOMP:
- **** NEEDED BECAUSE OUR IPCOMP IS EXPERIMENTAL (UNSTABLE).
- ****/
- if (!(st->st_policy & POLICY_COMPRESS))
- {
- plog("compression proposed by %s, but policy for \"%s\" forbids it"
- , ip_str(&c->spd.that.host_addr), c->name);
- continue; /* unwanted compression proposal */
- }
+ for (tn = 0; tn != esp_proposal.isap_notrans; tn++)
+ {
+ if (!parse_ipsec_transform(&esp_trans
+ , &esp_attrs
+ , &esp_prop_pbs
+ , &esp_trans_pbs
+ , &isakmp_esp_transform_desc
+ , previous_transnum
+ , selection
+ , tn == esp_proposal.isap_notrans - 1
+ , FALSE
+ , st))
+ return BAD_PROPOSAL_SYNTAX;
+
+ previous_transnum = esp_trans.isat_transnum;
+
+ /* set default key length for AES encryption */
+ if (!esp_attrs.key_len && esp_attrs.transid == ESP_AES)
+ {
+ esp_attrs.key_len = 128; /* bits */
+ }
+
+ if (!kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len
+ ,c->alg_info_esp))
+ {
+ switch (esp_attrs.transid)
+ {
+ case ESP_3DES:
+ break;
+#ifdef SUPPORT_ESP_NULL /* should be about as secure as AH-only */
+ case ESP_NULL:
+ if (esp_attrs.auth == AUTH_ALGORITHM_NONE)
+ {
+ loglog(RC_LOG_SERIOUS, "ESP_NULL requires auth algorithm");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+ if (st->st_policy & POLICY_ENCRYPT)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("ESP_NULL Transform Proposal from %s"
+ " does not satisfy POLICY_ENCRYPT"
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+ break;
#endif
- if (!can_do_IPcomp)
- {
- plog("compression proposed by %s, but KLIPS is not configured with IPCOMP"
- , ip_str(&c->spd.that.host_addr));
- continue;
- }
-
- if (well_known_cpi != 0 && !ah_seen && !esp_seen)
- {
- plog("illegal proposal: bare IPCOMP used with well-known CPI");
- return BAD_PROPOSAL_SYNTAX;
- }
-
- for (tn = 0; tn != ipcomp_proposal.isap_notrans; tn++)
- {
- if (!parse_ipsec_transform(&ipcomp_trans
- , &ipcomp_attrs
- , &ipcomp_prop_pbs
- , &ipcomp_trans_pbs
- , &isakmp_ipcomp_transform_desc
- , previous_transnum
- , selection
- , tn == ipcomp_proposal.isap_notrans - 1
- , TRUE
- , st))
- return BAD_PROPOSAL_SYNTAX;
-
- previous_transnum = ipcomp_trans.isat_transnum;
-
- if (well_known_cpi != 0 && ipcomp_attrs.transid != well_known_cpi)
- {
- plog("illegal proposal: IPCOMP well-known CPI disagrees with transform");
- return BAD_PROPOSAL_SYNTAX;
+ default:
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("unsupported ESP Transform %s from %s"
+ , enum_show(&esp_transformid_names, esp_attrs.transid)
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+ }
+
+ if (!kernel_alg_esp_auth_ok(esp_attrs.auth, c->alg_info_esp))
+ {
+ switch (esp_attrs.auth)
+ {
+ case AUTH_ALGORITHM_NONE:
+ if (!ah_seen)
+ {
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("ESP from %s must either have AUTH or be combined with AH"
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+ break;
+ case AUTH_ALGORITHM_HMAC_MD5:
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ break;
+ default:
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("unsupported ESP auth alg %s from %s"
+ , enum_show(&auth_alg_names, esp_attrs.auth)
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+ }
+
+ /* A last check for allowed transforms in alg_info_esp
+ * (ALG_INFO_F_STRICT flag)
+ */
+ if (!kernel_alg_esp_ok_final(esp_attrs.transid, esp_attrs.key_len
+ ,esp_attrs.auth, c->alg_info_esp))
+ {
+ continue;
+ }
+
+ if (ah_seen && ah_attrs.encapsulation != esp_attrs.encapsulation)
+ {
+ /* ??? This should be an error, but is it? */
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("AH and ESP transforms disagree about encapsulation; TUNNEL presumed"));
+ }
+
+ break; /* we seem to be happy */
+ }
+ if (tn == esp_proposal.isap_notrans)
+ continue; /* we didn't find a nice one */
+
+ esp_attrs.spi = esp_spi;
+ inner_proto = IPPROTO_ESP;
+ if (esp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ tunnel_mode = TRUE;
}
-
- switch (ipcomp_attrs.transid)
+ else if (st->st_policy & POLICY_ENCRYPT)
{
- case IPCOMP_DEFLATE: /* all we can handle! */
- break;
-
- default:
DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("unsupported IPCOMP Transform %s from %s"
- , enum_show(&ipcomp_transformid_names, ipcomp_attrs.transid)
- , ip_str(&c->spd.that.host_addr)));
- continue; /* try another */
+ , DBG_log("policy for \"%s\" requires encryption but ESP not in Proposal from %s"
+ , c->name, ip_str(&c->spd.that.host_addr)));
+ continue; /* we needed encryption, but didn't find ESP */
}
-
- if (ah_seen && ah_attrs.encapsulation != ipcomp_attrs.encapsulation)
- {
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("AH and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
- } else if (esp_seen && esp_attrs.encapsulation != ipcomp_attrs.encapsulation)
+ else if ((st->st_policy & POLICY_AUTHENTICATE) && !ah_seen)
{
- /* ??? This should be an error, but is it? */
- DBG(DBG_CONTROL | DBG_CRYPT
- , DBG_log("ESP and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("policy for \"%s\" requires authentication"
+ " but none in Proposal from %s"
+ , c->name, ip_str(&c->spd.that.host_addr)));
+ continue; /* we need authentication, but we found neither ESP nor AH */
}
- break; /* we seem to be happy */
- }
- if (tn == ipcomp_proposal.isap_notrans)
- continue; /* we didn't find a nice one */
- ipcomp_attrs.spi = ipcomp_cpi;
- inner_proto = IPPROTO_COMP;
- if (ipcomp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
- tunnel_mode = TRUE;
- }
+ if (ipcomp_seen)
+ {
+ int previous_transnum = -1;
+ int tn;
+
+#ifdef NEVER /* we think IPcomp is working now */
+ /**** FUDGE TO PREVENT UNREQUESTED IPCOMP:
+ **** NEEDED BECAUSE OUR IPCOMP IS EXPERIMENTAL (UNSTABLE).
+ ****/
+ if (!(st->st_policy & POLICY_COMPRESS))
+ {
+ plog("compression proposed by %s, but policy for \"%s\" forbids it"
+ , ip_str(&c->spd.that.host_addr), c->name);
+ continue; /* unwanted compression proposal */
+ }
+#endif
+ if (!can_do_IPcomp)
+ {
+ plog("compression proposed by %s, but KLIPS is not configured with IPCOMP"
+ , ip_str(&c->spd.that.host_addr));
+ continue;
+ }
- /* Eureka: we liked what we saw -- accept it. */
+ if (well_known_cpi != 0 && !ah_seen && !esp_seen)
+ {
+ plog("illegal proposal: bare IPCOMP used with well-known CPI");
+ return BAD_PROPOSAL_SYNTAX;
+ }
- if (r_sa_pbs != NULL)
- {
- /* emit what we've accepted */
+ for (tn = 0; tn != ipcomp_proposal.isap_notrans; tn++)
+ {
+ if (!parse_ipsec_transform(&ipcomp_trans
+ , &ipcomp_attrs
+ , &ipcomp_prop_pbs
+ , &ipcomp_trans_pbs
+ , &isakmp_ipcomp_transform_desc
+ , previous_transnum
+ , selection
+ , tn == ipcomp_proposal.isap_notrans - 1
+ , TRUE
+ , st))
+ return BAD_PROPOSAL_SYNTAX;
+
+ previous_transnum = ipcomp_trans.isat_transnum;
+
+ if (well_known_cpi != 0 && ipcomp_attrs.transid != well_known_cpi)
+ {
+ plog("illegal proposal: IPCOMP well-known CPI disagrees with transform");
+ return BAD_PROPOSAL_SYNTAX;
+ }
+
+ switch (ipcomp_attrs.transid)
+ {
+ case IPCOMP_DEFLATE: /* all we can handle! */
+ break;
+
+ default:
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("unsupported IPCOMP Transform %s from %s"
+ , enum_show(&ipcomp_transformid_names, ipcomp_attrs.transid)
+ , ip_str(&c->spd.that.host_addr)));
+ continue; /* try another */
+ }
+
+ if (ah_seen && ah_attrs.encapsulation != ipcomp_attrs.encapsulation)
+ {
+ /* ??? This should be an error, but is it? */
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("AH and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
+ } else if (esp_seen && esp_attrs.encapsulation != ipcomp_attrs.encapsulation)
+ {
+ /* ??? This should be an error, but is it? */
+ DBG(DBG_CONTROL | DBG_CRYPT
+ , DBG_log("ESP and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));
+ }
+
+ break; /* we seem to be happy */
+ }
+ if (tn == ipcomp_proposal.isap_notrans)
+ continue; /* we didn't find a nice one */
+ ipcomp_attrs.spi = ipcomp_cpi;
+ inner_proto = IPPROTO_COMP;
+ if (ipcomp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)
+ tunnel_mode = TRUE;
+ }
- /* Situation */
- if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
- impossible();
+ /* Eureka: we liked what we saw -- accept it. */
- /* AH proposal */
- if (ah_seen)
- echo_proposal(ah_proposal
- , ah_trans
- , esp_seen || ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_ah
- , &isakmp_ah_transform_desc
- , &ah_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_AH);
-
- /* ESP proposal */
- if (esp_seen)
- echo_proposal(esp_proposal
- , esp_trans
- , ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_esp
- , &isakmp_esp_transform_desc
- , &esp_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_ESP);
-
- /* IPCOMP proposal */
- if (ipcomp_seen)
- echo_proposal(ipcomp_proposal
- , ipcomp_trans
- , ISAKMP_NEXT_NONE
- , r_sa_pbs
- , &st->st_ipcomp
- , &isakmp_ipcomp_transform_desc
- , &ipcomp_trans_pbs
- , &st->st_connection->spd
- , tunnel_mode && inner_proto == IPPROTO_COMP);
-
- close_output_pbs(r_sa_pbs);
- }
+ if (r_sa_pbs != NULL)
+ {
+ /* emit what we've accepted */
+
+ /* Situation */
+ if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))
+ impossible();
+
+ /* AH proposal */
+ if (ah_seen)
+ echo_proposal(ah_proposal
+ , ah_trans
+ , esp_seen || ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
+ , r_sa_pbs
+ , &st->st_ah
+ , &isakmp_ah_transform_desc
+ , &ah_trans_pbs
+ , &st->st_connection->spd
+ , tunnel_mode && inner_proto == IPPROTO_AH);
+
+ /* ESP proposal */
+ if (esp_seen)
+ echo_proposal(esp_proposal
+ , esp_trans
+ , ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE
+ , r_sa_pbs
+ , &st->st_esp
+ , &isakmp_esp_transform_desc
+ , &esp_trans_pbs
+ , &st->st_connection->spd
+ , tunnel_mode && inner_proto == IPPROTO_ESP);
+
+ /* IPCOMP proposal */
+ if (ipcomp_seen)
+ echo_proposal(ipcomp_proposal
+ , ipcomp_trans
+ , ISAKMP_NEXT_NONE
+ , r_sa_pbs
+ , &st->st_ipcomp
+ , &isakmp_ipcomp_transform_desc
+ , &ipcomp_trans_pbs
+ , &st->st_connection->spd
+ , tunnel_mode && inner_proto == IPPROTO_COMP);
+
+ close_output_pbs(r_sa_pbs);
+ }
- /* save decoded version of winning SA in state */
+ /* save decoded version of winning SA in state */
- st->st_ah.present = ah_seen;
- if (ah_seen)
- st->st_ah.attrs = ah_attrs;
+ st->st_ah.present = ah_seen;
+ if (ah_seen)
+ st->st_ah.attrs = ah_attrs;
- st->st_esp.present = esp_seen;
- if (esp_seen)
- st->st_esp.attrs = esp_attrs;
+ st->st_esp.present = esp_seen;
+ if (esp_seen)
+ st->st_esp.attrs = esp_attrs;
- st->st_ipcomp.present = ipcomp_seen;
- if (ipcomp_seen)
- st->st_ipcomp.attrs = ipcomp_attrs;
+ st->st_ipcomp.present = ipcomp_seen;
+ if (ipcomp_seen)
+ st->st_ipcomp.attrs = ipcomp_attrs;
- return NOTHING_WRONG;
- }
+ return NOTHING_WRONG;
+ }
- loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");
- return NO_PROPOSAL_CHOSEN;
+ loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");
+ return NO_PROPOSAL_CHOSEN;
}
diff --git a/src/pluto/spdb.h b/src/pluto/spdb.h
index b098e247a..221cc00bb 100644
--- a/src/pluto/spdb.h
+++ b/src/pluto/spdb.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: spdb.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _SPDB_H
@@ -25,39 +23,39 @@
* Note: only "basic" values are represented so far.
*/
struct db_attr {
- u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
- u_int16_t val;
+ u_int16_t type; /* ISAKMP_ATTR_AF_TV is implied; 0 for end */
+ u_int16_t val;
};
/* transform */
struct db_trans {
- u_int8_t transid; /* Transform-Id */
- struct db_attr *attrs; /* array */
- int attr_cnt; /* number of elements */
+ u_int8_t transid; /* Transform-Id */
+ struct db_attr *attrs; /* array */
+ int attr_cnt; /* number of elements */
};
/* proposal */
struct db_prop {
- u_int8_t protoid; /* Protocol-Id */
- struct db_trans *trans; /* array (disjunction) */
- int trans_cnt; /* number of elements */
- /* SPI size and value isn't part of DB */
+ u_int8_t protoid; /* Protocol-Id */
+ struct db_trans *trans; /* array (disjunction) */
+ int trans_cnt; /* number of elements */
+ /* SPI size and value isn't part of DB */
};
/* conjunction of proposals */
struct db_prop_conj {
- struct db_prop *props; /* array */
- int prop_cnt; /* number of elements */
+ struct db_prop *props; /* array */
+ int prop_cnt; /* number of elements */
};
/* security association */
struct db_sa {
- struct db_prop_conj *prop_conjs; /* array */
- int prop_conj_cnt; /* number of elements */
- /* Hardwired for now;
- * DOI: ISAKMP_DOI_IPSEC
- * Situation: SIT_IDENTITY_ONLY
- */
+ struct db_prop_conj *prop_conjs; /* array */
+ int prop_conj_cnt; /* number of elements */
+ /* Hardwired for now;
+ * DOI: ISAKMP_DOI_IPSEC
+ * Situation: SIT_IDENTITY_ONLY
+ */
};
/* The oakley sadb */
@@ -72,38 +70,38 @@ extern struct db_sa ipsec_sadb[1 << 3];
struct state;
extern bool out_sa(
- pb_stream *outs,
- struct db_sa *sadb,
- struct state *st,
- bool oakley_mode,
- u_int8_t np);
+ pb_stream *outs,
+ struct db_sa *sadb,
+ struct state *st,
+ bool oakley_mode,
+ u_int8_t np);
extern notification_t preparse_isakmp_sa_body(
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *sa_pbs, /* body of input SA Payload */
- u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
- pb_stream *proposal_pbs, /* body of proposal Payload */
- struct isakmp_proposal *proposal);
+ const struct isakmp_sa *sa, /* header of input SA Payload */
+ pb_stream *sa_pbs, /* body of input SA Payload */
+ u_int32_t *ipsecdoisit, /* IPsec DOI SIT bitset */
+ pb_stream *proposal_pbs, /* body of proposal Payload */
+ struct isakmp_proposal *proposal);
extern notification_t parse_isakmp_policy(
- pb_stream *proposal_pbs, /* body of proposal Payload */
- u_int notrans, /* number of transforms */
- lset_t *policy); /* RSA, PSK or XAUTH policy */
+ pb_stream *proposal_pbs, /* body of proposal Payload */
+ u_int notrans, /* number of transforms */
+ lset_t *policy); /* RSA, PSK or XAUTH policy */
extern notification_t parse_isakmp_sa_body(
- u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
- pb_stream *proposal_pbs, /* body of proposal Payload */
- struct isakmp_proposal *proposal,
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- struct state *st, /* current state object */
- bool initiator); /* is caller initiator? */
+ u_int32_t ipsecdoisit, /* IPsec DOI SIT bitset */
+ pb_stream *proposal_pbs, /* body of proposal Payload */
+ struct isakmp_proposal *proposal,
+ pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
+ struct state *st, /* current state object */
+ bool initiator); /* is caller initiator? */
extern notification_t parse_ipsec_sa_body(
- pb_stream *sa_pbs, /* body of input SA Payload */
- const struct isakmp_sa *sa, /* header of input SA Payload */
- pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- bool selection, /* if this SA is a selection, only one tranform can appear */
- struct state *st); /* current state object */
+ pb_stream *sa_pbs, /* body of input SA Payload */
+ const struct isakmp_sa *sa, /* header of input SA Payload */
+ pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
+ bool selection, /* if this SA is a selection, only one tranform can appear */
+ struct state *st); /* current state object */
extern void backup_pbs(pb_stream *pbs);
extern void restore_pbs(pb_stream *pbs);
diff --git a/src/pluto/state.c b/src/pluto/state.c
index 5372e86f5..6ce0d50e5 100644
--- a/src/pluto/state.c
+++ b/src/pluto/state.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: state.c 4924 2009-03-10 21:13:18Z andreas $
*/
#include <stdio.h>
@@ -28,29 +26,28 @@
#include <freeswan.h>
+#include <library.h>
+#include <crypto/rngs/rng.h>
+
#include "constants.h"
#include "defs.h"
#include "connections.h"
#include "state.h"
#include "kernel.h"
#include "log.h"
-#include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */
-#include "keys.h" /* for free_public_key */
-#include "rnd.h"
+#include "packet.h" /* so we can calculate sizeof(struct isakmp_hdr) */
+#include "keys.h" /* for free_public_key */
#include "timer.h"
#include "whack.h"
-#include "demux.h" /* needs packet.h */
-#include "ipsec_doi.h" /* needs demux.h and state.h */
-
-#include "sha1.h"
-#include "md5.h"
-#include "crypto.h" /* requires sha1.h and md5.h */
+#include "demux.h" /* needs packet.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "crypto.h"
/*
* Global variables: had to go somewhere, might as well be this file.
*/
-u_int16_t pluto_port = IKE_UDP_PORT; /* Pluto's port */
+u_int16_t pluto_port = IKE_UDP_PORT; /* Pluto's port */
/*
* This file has the functions that handle the
@@ -79,51 +76,53 @@ u_int16_t pluto_port = IKE_UDP_PORT; /* Pluto's port */
struct msgid_list
{
- msgid_t msgid; /* network order */
- struct msgid_list *next;
+ msgid_t msgid; /* network order */
+ struct msgid_list *next;
};
-bool
-reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
+bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid)
{
- struct msgid_list *p;
+ struct msgid_list *p;
- passert(msgid != MAINMODE_MSGID);
- passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
+ passert(msgid != MAINMODE_MSGID);
+ passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
- for (p = isakmp_sa->st_used_msgids; p != NULL; p = p->next)
- if (p->msgid == msgid)
- return FALSE;
+ for (p = isakmp_sa->st_used_msgids; p != NULL; p = p->next)
+ if (p->msgid == msgid)
+ return FALSE;
- p = alloc_thing(struct msgid_list, "msgid");
- p->msgid = msgid;
- p->next = isakmp_sa->st_used_msgids;
- isakmp_sa->st_used_msgids = p;
- return TRUE;
+ p = malloc_thing(struct msgid_list);
+ p->msgid = msgid;
+ p->next = isakmp_sa->st_used_msgids;
+ isakmp_sa->st_used_msgids = p;
+ return TRUE;
}
-msgid_t
-generate_msgid(struct state *isakmp_sa)
+msgid_t generate_msgid(struct state *isakmp_sa)
{
- int timeout = 100; /* only try so hard for unique msgid */
- msgid_t msgid;
+ int timeout = 100; /* only try so hard for unique msgid */
+ msgid_t msgid;
+ rng_t *rng;
- passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
+ passert(IS_ISAKMP_ENCRYPTED(isakmp_sa->st_state));
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- for (;;)
- {
- get_rnd_bytes((void *) &msgid, sizeof(msgid));
- if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
- break;
-
- if (--timeout == 0)
+ for (;;)
{
- plog("gave up looking for unique msgid; using 0x%08lx"
- , (unsigned long) msgid);
- break;
+ rng->get_bytes(rng, sizeof(msgid), (void *) &msgid);
+ if (msgid != 0 && reserve_msgid(isakmp_sa, msgid))
+ {
+ break;
+ }
+ if (--timeout == 0)
+ {
+ plog("gave up looking for unique msgid; using 0x%08lx"
+ , (unsigned long) msgid);
+ break;
+ }
}
- }
- return msgid;
+ rng->destroy(rng);
+ return msgid;
}
@@ -133,63 +132,61 @@ generate_msgid(struct state *isakmp_sa)
static struct state *statetable[STATE_TABLE_SIZE];
-static struct state **
-state_hash(const u_char *icookie, const u_char *rcookie, const ip_address *peer)
+static struct state **state_hash(const u_char *icookie, const u_char *rcookie,
+ const ip_address *peer)
{
- u_int i = 0, j;
- const unsigned char *byte_ptr;
- size_t length = addrbytesptr(peer, &byte_ptr);
+ u_int i = 0, j;
+ const unsigned char *byte_ptr;
+ size_t length = addrbytesptr(peer, &byte_ptr);
- DBG(DBG_RAW | DBG_CONTROL,
- DBG_dump("ICOOKIE:", icookie, COOKIE_SIZE);
- DBG_dump("RCOOKIE:", rcookie, COOKIE_SIZE);
- DBG_dump("peer:", byte_ptr, length));
+ DBG(DBG_RAW | DBG_CONTROL,
+ DBG_dump("ICOOKIE:", icookie, COOKIE_SIZE);
+ DBG_dump("RCOOKIE:", rcookie, COOKIE_SIZE);
+ DBG_dump("peer:", byte_ptr, length));
- /* XXX the following hash is pretty pathetic */
+ /* XXX the following hash is pretty pathetic */
- for (j = 0; j < COOKIE_SIZE; j++)
- i = i * 407 + icookie[j] + rcookie[j];
+ for (j = 0; j < COOKIE_SIZE; j++)
+ i = i * 407 + icookie[j] + rcookie[j];
- for (j = 0; j < length; j++)
- i = i * 613 + byte_ptr[j];
+ for (j = 0; j < length; j++)
+ i = i * 613 + byte_ptr[j];
- i = i % STATE_TABLE_SIZE;
+ i = i % STATE_TABLE_SIZE;
- DBG(DBG_CONTROL, DBG_log("state hash entry %d", i));
+ DBG(DBG_CONTROL, DBG_log("state hash entry %d", i));
- return &statetable[i];
+ return &statetable[i];
}
/* Get a state object.
* Caller must schedule an event for this object so that it doesn't leak.
* Caller must insert_state().
*/
-struct state *
-new_state(void)
+struct state *new_state(void)
{
- static const struct state blank_state; /* initialized all to zero & NULL */
- static so_serial_t next_so = SOS_FIRST;
- struct state *st;
-
- st = clone_thing(blank_state, "struct state in new_state()");
- st->st_serialno = next_so++;
- passert(next_so > SOS_FIRST); /* overflow can't happen! */
- st->st_whack_sock = NULL_FD;
- DBG(DBG_CONTROL, DBG_log("creating state object #%lu at %p",
- st->st_serialno, (void *) st));
- return st;
+ static const struct state blank_state; /* initialized all to zero & NULL */
+ static so_serial_t next_so = SOS_FIRST;
+ struct state *st;
+
+ st = clone_thing(blank_state);
+ st->st_serialno = next_so++;
+ passert(next_so > SOS_FIRST); /* overflow can't happen! */
+ st->st_whack_sock = NULL_FD;
+ DBG(DBG_CONTROL, DBG_log("creating state object #%lu at %p",
+ st->st_serialno, (void *) st));
+ return st;
}
/*
* Initialize the state table (and mask*).
*/
-void
-init_states(void)
+void init_states(void)
{
- int i;
+ int i;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- statetable[i] = (struct state *) NULL;
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
+ statetable[i] = (struct state *) NULL;
}
/* Find the state object with this serial number.
@@ -199,627 +196,619 @@ init_states(void)
* If this turns out to be a significant CPU hog, it could be
* improved to use a hash table rather than sequential seartch.
*/
-struct state *
-state_with_serialno(so_serial_t sn)
+struct state *state_with_serialno(so_serial_t sn)
{
- if (sn >= SOS_FIRST)
- {
- struct state *st;
- int i;
+ if (sn >= SOS_FIRST)
+ {
+ struct state *st;
+ int i;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_serialno == sn)
- return st;
- }
- return NULL;
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ if (st->st_serialno == sn)
+ return st;
+ }
+ return NULL;
}
/* Insert a state object in the hash table. The object is inserted
* at the begining of list.
* Needs cookies, connection, and msgid.
*/
-void
-insert_state(struct state *st)
+void insert_state(struct state *st)
{
- struct state **p = state_hash(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr);
-
- passert(st->st_hashchain_prev == NULL && st->st_hashchain_next == NULL);
-
- if (*p != NULL)
- {
- passert((*p)->st_hashchain_prev == NULL);
- (*p)->st_hashchain_prev = st;
- }
- st->st_hashchain_next = *p;
- *p = st;
-
- /* Ensure that somebody is in charge of killing this state:
- * if no event is scheduled for it, schedule one to discard the state.
- * If nothing goes wrong, this event will be replaced by
- * a more appropriate one.
- */
- if (st->st_event == NULL)
- event_schedule(EVENT_SO_DISCARD, 0, st);
+ struct state **p = state_hash(st->st_icookie, st->st_rcookie
+ , &st->st_connection->spd.that.host_addr);
+
+ passert(st->st_hashchain_prev == NULL && st->st_hashchain_next == NULL);
+
+ if (*p != NULL)
+ {
+ passert((*p)->st_hashchain_prev == NULL);
+ (*p)->st_hashchain_prev = st;
+ }
+ st->st_hashchain_next = *p;
+ *p = st;
+
+ /* Ensure that somebody is in charge of killing this state:
+ * if no event is scheduled for it, schedule one to discard the state.
+ * If nothing goes wrong, this event will be replaced by
+ * a more appropriate one.
+ */
+ if (st->st_event == NULL)
+ event_schedule(EVENT_SO_DISCARD, 0, st);
}
/* unlink a state object from the hash table, but don't free it
*/
-void
-unhash_state(struct state *st)
+void unhash_state(struct state *st)
{
- /* unlink from forward chain */
- struct state **p = st->st_hashchain_prev == NULL
- ? state_hash(st->st_icookie, st->st_rcookie
- , &st->st_connection->spd.that.host_addr)
- : &st->st_hashchain_prev->st_hashchain_next;
-
- /* unlink from forward chain */
- passert(*p == st);
- *p = st->st_hashchain_next;
-
- /* unlink from backward chain */
- if (st->st_hashchain_next != NULL)
- {
- passert(st->st_hashchain_next->st_hashchain_prev == st);
- st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
- }
-
- st->st_hashchain_next = st->st_hashchain_prev = NULL;
+ /* unlink from forward chain */
+ struct state **p = st->st_hashchain_prev == NULL
+ ? state_hash(st->st_icookie, st->st_rcookie
+ , &st->st_connection->spd.that.host_addr)
+ : &st->st_hashchain_prev->st_hashchain_next;
+
+ /* unlink from forward chain */
+ passert(*p == st);
+ *p = st->st_hashchain_next;
+
+ /* unlink from backward chain */
+ if (st->st_hashchain_next != NULL)
+ {
+ passert(st->st_hashchain_next->st_hashchain_prev == st);
+ st->st_hashchain_next->st_hashchain_prev = st->st_hashchain_prev;
+ }
+
+ st->st_hashchain_next = st->st_hashchain_prev = NULL;
}
/* Free the Whack socket file descriptor.
* This has the side effect of telling Whack that we're done.
*/
-void
-release_whack(struct state *st)
+void release_whack(struct state *st)
{
- close_any(st->st_whack_sock);
+ close_any(st->st_whack_sock);
}
-/* delete a state object */
-void
-delete_state(struct state *st)
+/**
+ * Delete a state object
+ */
+void delete_state(struct state *st)
{
- struct connection *const c = st->st_connection;
- struct state *old_cur_state = cur_state == st? NULL : cur_state;
-
- set_cur_state(st);
+ struct connection *const c = st->st_connection;
+ struct state *old_cur_state = cur_state == st? NULL : cur_state;
- /* If DPD is enabled on this state object, clear any pending events */
- if(st->st_dpd_event != NULL)
- delete_dpd_event(st);
+ set_cur_state(st);
- /* if there is a suspended state transition, disconnect us */
- if (st->st_suspended_md != NULL)
- {
- passert(st->st_suspended_md->st == st);
- st->st_suspended_md->st = NULL;
- }
+ /* If DPD is enabled on this state object, clear any pending events */
+ if(st->st_dpd_event != NULL)
+ delete_dpd_event(st);
- /* tell the other side of any IPSEC SAs that are going down */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- || IS_ISAKMP_SA_ESTABLISHED(st->st_state))
- send_delete(st);
+ /* if there is a suspended state transition, disconnect us */
+ if (st->st_suspended_md != NULL)
+ {
+ passert(st->st_suspended_md->st == st);
+ st->st_suspended_md->st = NULL;
+ }
- delete_event(st); /* delete any pending timer event */
+ /* tell the other side of any IPSEC SAs that are going down */
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
+ || IS_ISAKMP_SA_ESTABLISHED(st->st_state))
+ send_delete(st);
- /* Ditch anything pending on ISAKMP SA being established.
- * Note: this must be done before the unhash_state to prevent
- * flush_pending_by_state inadvertently and prematurely
- * deleting our connection.
- */
- flush_pending_by_state(st);
+ delete_event(st); /* delete any pending timer event */
- /* effectively, this deletes any ISAKMP SA that this state represents */
- unhash_state(st);
+ /* Ditch anything pending on ISAKMP SA being established.
+ * Note: this must be done before the unhash_state to prevent
+ * flush_pending_by_state inadvertently and prematurely
+ * deleting our connection.
+ */
+ flush_pending_by_state(st);
- /* tell kernel to delete any IPSEC SA
- * ??? we ought to tell peer to delete IPSEC SAs
- */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- delete_ipsec_sa(st, FALSE);
- else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
- delete_ipsec_sa(st, TRUE);
+ /* effectively, this deletes any ISAKMP SA that this state represents */
+ unhash_state(st);
- if (c->newest_ipsec_sa == st->st_serialno)
- c->newest_ipsec_sa = SOS_NOBODY;
+ /* tell kernel to delete any IPSEC SA
+ * ??? we ought to tell peer to delete IPSEC SAs
+ */
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ delete_ipsec_sa(st, FALSE);
+ else if (IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(st->st_state))
+ delete_ipsec_sa(st, TRUE);
- if (c->newest_isakmp_sa == st->st_serialno)
- c->newest_isakmp_sa = SOS_NOBODY;
+ if (c->newest_ipsec_sa == st->st_serialno)
+ c->newest_ipsec_sa = SOS_NOBODY;
- st->st_connection = NULL; /* we might be about to free it */
- cur_state = old_cur_state; /* without st_connection, st isn't complete */
- connection_discard(c);
+ if (c->newest_isakmp_sa == st->st_serialno)
+ c->newest_isakmp_sa = SOS_NOBODY;
- release_whack(st);
+ st->st_connection = NULL; /* we might be about to free it */
+ cur_state = old_cur_state; /* without st_connection, st isn't complete */
+ connection_discard(c);
- /* from here on we are just freeing RAM */
+ release_whack(st);
- {
- struct msgid_list *p = st->st_used_msgids;
+ /* from here on we are just freeing RAM */
- while (p != NULL)
{
- struct msgid_list *q = p;
- p = p->next;
- pfree(q);
+ struct msgid_list *p = st->st_used_msgids;
+
+ while (p != NULL)
+ {
+ struct msgid_list *q = p;
+ p = p->next;
+ free(q);
+ }
}
- }
-
- unreference_key(&st->st_peer_pubkey);
-
- if (st->st_sec_in_use)
- mpz_clear(&(st->st_sec));
-
- pfreeany(st->st_tpacket.ptr);
- pfreeany(st->st_rpacket.ptr);
- pfreeany(st->st_p1isa.ptr);
- pfreeany(st->st_gi.ptr);
- pfreeany(st->st_gr.ptr);
- pfreeany(st->st_shared.ptr);
- pfreeany(st->st_ni.ptr);
- pfreeany(st->st_nr.ptr);
- pfreeany(st->st_skeyid.ptr);
- pfreeany(st->st_skeyid_d.ptr);
- pfreeany(st->st_skeyid_a.ptr);
- pfreeany(st->st_skeyid_e.ptr);
- pfreeany(st->st_enc_key.ptr);
- pfreeany(st->st_ah.our_keymat);
- pfreeany(st->st_ah.peer_keymat);
- pfreeany(st->st_esp.our_keymat);
- pfreeany(st->st_esp.peer_keymat);
-
- pfree(st);
+
+ unreference_key(&st->st_peer_pubkey);
+
+ DESTROY_IF(st->st_dh);
+
+ free(st->st_tpacket.ptr);
+ free(st->st_rpacket.ptr);
+ free(st->st_p1isa.ptr);
+ free(st->st_gi.ptr);
+ free(st->st_gr.ptr);
+ free(st->st_shared.ptr);
+ free(st->st_ni.ptr);
+ free(st->st_nr.ptr);
+ free(st->st_skeyid.ptr);
+ free(st->st_skeyid_d.ptr);
+ free(st->st_skeyid_a.ptr);
+ free(st->st_skeyid_e.ptr);
+ free(st->st_enc_key.ptr);
+ free(st->st_ah.our_keymat);
+ free(st->st_ah.peer_keymat);
+ free(st->st_esp.our_keymat);
+ free(st->st_esp.peer_keymat);
+
+ free(st);
}
-/*
+/**
* Is a connection in use by some state?
*/
-bool
-states_use_connection(struct connection *c)
+bool states_use_connection(struct connection *c)
{
- /* are there any states still using it? */
- struct state *st = NULL;
- int i;
+ /* are there any states still using it? */
+ struct state *st = NULL;
+ int i;
- for (i = 0; st == NULL && i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_connection == c)
- return TRUE;
+ for (i = 0; st == NULL && i < STATE_TABLE_SIZE; i++)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ if (st->st_connection == c)
+ return TRUE;
- return FALSE;
+ return FALSE;
}
-/*
- * delete all states that were created for a given connection.
+/**
+ * Delete all states that were created for a given connection.
* if relations == TRUE, then also delete states that share
* the same phase 1 SA.
*/
-void
-delete_states_by_connection(struct connection *c, bool relations)
+void delete_states_by_connection(struct connection *c, bool relations)
{
- int pass;
- /* this kludge avoids an n^2 algorithm */
- enum connection_kind ck = c->kind;
- struct spd_route *sr;
-
- /* save this connection's isakmp SA, since it will get set to later SOS_NOBODY */
- so_serial_t parent_sa = c->newest_isakmp_sa;
-
- if (ck == CK_INSTANCE)
- c->kind = CK_GOING_AWAY;
-
- /* We take two passes so that we delete any ISAKMP SAs last.
- * This allows Delete Notifications to be sent.
- * ?? We could probably double the performance by caching any
- * ISAKMP SA states found in the first pass, avoiding a second.
- */
- for (pass = 0; pass != 2; pass++)
- {
- int i;
-
- /* For each hash chain... */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
+ int pass;
+ /* this kludge avoids an n^2 algorithm */
+ enum connection_kind ck = c->kind;
+ struct spd_route *sr;
+
+ /* save this connection's isakmp SA, since it will get set to later SOS_NOBODY */
+ so_serial_t parent_sa = c->newest_isakmp_sa;
+
+ if (ck == CK_INSTANCE)
+ c->kind = CK_GOING_AWAY;
+
+ /* We take two passes so that we delete any ISAKMP SAs last.
+ * This allows Delete Notifications to be sent.
+ * ?? We could probably double the performance by caching any
+ * ISAKMP SA states found in the first pass, avoiding a second.
+ */
+ for (pass = 0; pass != 2; pass++)
{
- struct state *st;
+ int i;
- /* For each state in the hash chain... */
- for (st = statetable[i]; st != NULL; )
- {
- struct state *this = st;
+ /* For each hash chain... */
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
+ {
+ struct state *st;
+
+ /* For each state in the hash chain... */
+ for (st = statetable[i]; st != NULL; )
+ {
+ struct state *this = st;
- st = st->st_hashchain_next; /* before this is deleted */
+ st = st->st_hashchain_next; /* before this is deleted */
- if ((this->st_connection == c
- || (relations && parent_sa != SOS_NOBODY
- && this->st_clonedfrom == parent_sa))
- && (pass == 1 || !IS_ISAKMP_SA_ESTABLISHED(this->st_state)))
- {
- struct state *old_cur_state
- = cur_state == this? NULL : cur_state;
+ if ((this->st_connection == c
+ || (relations && parent_sa != SOS_NOBODY
+ && this->st_clonedfrom == parent_sa))
+ && (pass == 1 || !IS_ISAKMP_SA_ESTABLISHED(this->st_state)))
+ {
+ struct state *old_cur_state
+ = cur_state == this? NULL : cur_state;
#ifdef DEBUG
- lset_t old_cur_debugging = cur_debugging;
+ lset_t old_cur_debugging = cur_debugging;
#endif
- set_cur_state(this);
- plog("deleting state (%s)"
- , enum_show(&state_names, this->st_state));
- delete_state(this);
- cur_state = old_cur_state;
+ set_cur_state(this);
+ plog("deleting state (%s)"
+ , enum_show(&state_names, this->st_state));
+ delete_state(this);
+ cur_state = old_cur_state;
#ifdef DEBUG
- cur_debugging = old_cur_debugging;
+ cur_debugging = old_cur_debugging;
#endif
+ }
+ }
}
- }
}
- }
-
- sr = &c->spd;
- while (sr != NULL)
- {
- passert(sr->eroute_owner == SOS_NOBODY);
- passert(sr->routing != RT_ROUTED_TUNNEL);
- sr = sr->next;
- }
- c->kind = ck;
+
+ sr = &c->spd;
+ while (sr != NULL)
+ {
+ passert(sr->eroute_owner == SOS_NOBODY);
+ passert(sr->routing != RT_ROUTED_TUNNEL);
+ sr = sr->next;
+ }
+ c->kind = ck;
}
-/* Walk through the state table, and delete each state whose phase 1 (IKE)
+/**
+ * Walk through the state table, and delete each state whose phase 1 (IKE)
* peer is among those given.
*/
-void
-delete_states_by_peer(ip_address *peer)
+void delete_states_by_peer(ip_address *peer)
{
- char peerstr[ADDRTOT_BUF];
- int i;
-
- addrtot(peer, 0, peerstr, sizeof(peerstr));
+ char peerstr[ADDRTOT_BUF];
+ int i;
- /* For each hash chain... */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
+ addrtot(peer, 0, peerstr, sizeof(peerstr));
- /* For each state in the hash chain... */
- for (st = statetable[i]; st != NULL; )
+ /* For each hash chain... */
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- struct state *this = st;
- struct spd_route *sr;
- struct connection *c = this->st_connection;
-
- st = st->st_hashchain_next; /* before this is deleted */
+ struct state *st;
- /* ??? Is it not the case that the peer is the same for all spds? */
- for (sr = &c->spd; sr != NULL; sr = sr->next)
- {
- if (sameaddr(&sr->that.host_addr, peer))
+ /* For each state in the hash chain... */
+ for (st = statetable[i]; st != NULL; )
{
- plog("peer %s for connection %s deleting - claimed to have crashed"
- , peerstr
- , c->name);
- delete_states_by_connection(c, TRUE);
- if (c->kind == CK_INSTANCE)
- delete_connection(c, TRUE);
- break; /* can only delete it once */
+ struct state *this = st;
+ struct spd_route *sr;
+ struct connection *c = this->st_connection;
+
+ st = st->st_hashchain_next; /* before this is deleted */
+
+ /* ??? Is it not the case that the peer is the same for all spds? */
+ for (sr = &c->spd; sr != NULL; sr = sr->next)
+ {
+ if (sameaddr(&sr->that.host_addr, peer))
+ {
+ plog("peer %s for connection %s deleting - claimed to have crashed"
+ , peerstr
+ , c->name);
+ delete_states_by_connection(c, TRUE);
+ if (c->kind == CK_INSTANCE)
+ delete_connection(c, TRUE);
+ break; /* can only delete it once */
+ }
+ }
}
- }
}
- }
}
/* Duplicate a Phase 1 state object, to create a Phase 2 object.
* Caller must schedule an event for this object so that it doesn't leak.
* Caller must insert_state().
*/
-struct state *
-duplicate_state(struct state *st)
+struct state *duplicate_state(struct state *st)
{
- struct state *nst;
-
- DBG(DBG_CONTROL, DBG_log("duplicating state object #%lu",
- st->st_serialno));
-
- /* record use of the Phase 1 state */
- st->st_outbound_count++;
- st->st_outbound_time = now();
-
- nst = new_state();
-
- memcpy(nst->st_icookie, st->st_icookie, COOKIE_SIZE);
- memcpy(nst->st_rcookie, st->st_rcookie, COOKIE_SIZE);
-
- nst->st_connection = st->st_connection;
- nst->st_doi = st->st_doi;
- nst->st_situation = st->st_situation;
- nst->st_clonedfrom = st->st_serialno;
- nst->st_oakley = st->st_oakley;
- nst->st_modecfg = st->st_modecfg;
-
-# define clone_chunk(ch, name) \
- clonetochunk(nst->ch, st->ch.ptr, st->ch.len, name)
-
- clone_chunk(st_skeyid_d, "st_skeyid_d in duplicate_state");
- clone_chunk(st_skeyid_a, "st_skeyid_a in duplicate_state");
- clone_chunk(st_skeyid_e, "st_skeyid_e in duplicate_state");
- clone_chunk(st_enc_key, "st_enc_key in duplicate_state");
-
-# undef clone_chunk
-
- return nst;
+ struct state *nst;
+
+ DBG(DBG_CONTROL, DBG_log("duplicating state object #%lu",
+ st->st_serialno));
+
+ /* record use of the Phase 1 state */
+ st->st_outbound_count++;
+ st->st_outbound_time = now();
+
+ nst = new_state();
+
+ memcpy(nst->st_icookie, st->st_icookie, COOKIE_SIZE);
+ memcpy(nst->st_rcookie, st->st_rcookie, COOKIE_SIZE);
+
+ nst->st_connection = st->st_connection;
+ nst->st_doi = st->st_doi;
+ nst->st_situation = st->st_situation;
+ nst->st_clonedfrom = st->st_serialno;
+ nst->st_oakley = st->st_oakley;
+ nst->st_modecfg = st->st_modecfg;
+ nst->st_skeyid_d = chunk_clone(st->st_skeyid_d);
+ nst->st_skeyid_a = chunk_clone(st->st_skeyid_a);
+ nst->st_skeyid_e = chunk_clone(st->st_skeyid_e);
+ nst->st_enc_key = chunk_clone(st->st_enc_key);
+
+ return nst;
}
#if 1
void for_each_state(void *(f)(struct state *, void *data), void *data)
{
- struct state *st, *ocs = cur_state;
- int i;
- for (i=0; i<STATE_TABLE_SIZE; i++) {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next) {
- set_cur_state(st);
- f(st, data);
+ struct state *st, *ocs = cur_state;
+ int i;
+ for (i=0; i<STATE_TABLE_SIZE; i++) {
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next) {
+ set_cur_state(st);
+ f(st, data);
+ }
}
- }
- cur_state = ocs;
+ cur_state = ocs;
}
#endif
-/*
+/**
* Find a state object.
*/
-struct state *
-find_state(const u_char *icookie
-, const u_char *rcookie
-, const ip_address *peer
-, msgid_t /*network order*/ msgid)
+struct state *find_state(const u_char *icookie, const u_char *rcookie,
+ const ip_address *peer, msgid_t msgid)
{
- struct state *st = *state_hash(icookie, rcookie, peer);
-
- while (st != (struct state *) NULL)
- if (sameaddr(peer, &st->st_connection->spd.that.host_addr)
- && memcmp(icookie, st->st_icookie, COOKIE_SIZE) == 0
- && memcmp(rcookie, st->st_rcookie, COOKIE_SIZE) == 0
- && msgid == st->st_msgid)
- break;
- else
- st = st->st_hashchain_next;
-
- DBG(DBG_CONTROL,
- if (st == NULL)
- DBG_log("state object not found");
- else
- DBG_log("state object #%lu found, in %s"
- , st->st_serialno
- , enum_show(&state_names, st->st_state)));
+ struct state *st = *state_hash(icookie, rcookie, peer);
- return st;
+ while (st != (struct state *) NULL)
+ {
+ if (sameaddr(peer, &st->st_connection->spd.that.host_addr)
+ && memeq(icookie, st->st_icookie, COOKIE_SIZE)
+ && memeq(rcookie, st->st_rcookie, COOKIE_SIZE)
+ && msgid == st->st_msgid)
+ {
+ break;
+ }
+ else
+ {
+ st = st->st_hashchain_next;
+ }
+ }
+ DBG(DBG_CONTROL,
+ if (st == NULL)
+ DBG_log("state object not found");
+ else
+ DBG_log("state object #%lu found, in %s"
+ , st->st_serialno
+ , enum_show(&state_names, st->st_state)));
+
+ return st;
}
-/* Find the state that sent a packet
+/**
+ * Find the state that sent a packet
* ??? this could be expensive -- it should be rate-limited to avoid DoS
*/
-struct state *
-find_sender(size_t packet_len, u_char *packet)
+struct state *find_sender(size_t packet_len, u_char *packet)
{
- int i;
- struct state *st;
-
- if (packet_len >= sizeof(struct isakmp_hdr))
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (st->st_tpacket.ptr != NULL
- && st->st_tpacket.len == packet_len
- && memcmp(st->st_tpacket.ptr, packet, packet_len) == 0)
- return st;
+ int i;
+ struct state *st;
- return NULL;
+ if (packet_len >= sizeof(struct isakmp_hdr))
+ {
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
+ {
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ {
+ if (st->st_tpacket.ptr != NULL
+ && st->st_tpacket.len == packet_len
+ && memeq(st->st_tpacket.ptr, packet, packet_len))
+ {
+ return st;
+ }
+ }
+ }
+ }
+ return NULL;
}
-struct state *
-find_phase2_state_to_delete(const struct state *p1st
-, u_int8_t protoid
-, ipsec_spi_t spi
-, bool *bogus)
+struct state *find_phase2_state_to_delete(const struct state *p1st,
+ u_int8_t protoid, ipsec_spi_t spi,
+ bool *bogus)
{
- struct state *st;
- int i;
+ struct state *st;
+ int i;
- *bogus = FALSE;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ *bogus = FALSE;
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- && p1st->st_connection->host_pair == st->st_connection->host_pair
- && same_peer_ids(p1st->st_connection, st->st_connection, NULL))
- {
- struct ipsec_proto_info *pr = protoid == PROTO_IPSEC_AH
- ? &st->st_ah : &st->st_esp;
-
- if (pr->present)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
{
- if (pr->attrs.spi == spi)
- return st;
- if (pr->our_spi == spi)
- *bogus = TRUE;
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
+ && p1st->st_connection->host_pair == st->st_connection->host_pair
+ && same_peer_ids(p1st->st_connection, st->st_connection, NULL))
+ {
+ struct ipsec_proto_info *pr = protoid == PROTO_IPSEC_AH
+ ? &st->st_ah : &st->st_esp;
+
+ if (pr->present)
+ {
+ if (pr->attrs.spi == spi)
+ return st;
+ if (pr->our_spi == spi)
+ *bogus = TRUE;
+ }
+ }
}
- }
}
- }
- return NULL;
+ return NULL;
}
-/* Find newest Phase 1 negotiation state object for suitable for connection c
+/**
+ * Find newest Phase 1 negotiation state object for suitable for connection c
*/
-struct state *
-find_phase1_state(const struct connection *c, lset_t ok_states)
+struct state *find_phase1_state(const struct connection *c, lset_t ok_states)
{
- struct state
- *st,
- *best = NULL;
- int i;
-
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
- if (LHAS(ok_states, st->st_state)
- && c->host_pair == st->st_connection->host_pair
- && same_peer_ids(c, st->st_connection, NULL)
- && (best == NULL || best->st_serialno < st->st_serialno))
- best = st;
-
- return best;
+ struct state
+ *st,
+ *best = NULL;
+ int i;
+
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ if (LHAS(ok_states, st->st_state)
+ && c->host_pair == st->st_connection->host_pair
+ && same_peer_ids(c, st->st_connection, NULL)
+ && (best == NULL || best->st_serialno < st->st_serialno))
+ best = st;
+
+ return best;
}
-void
-state_eroute_usage(ip_subnet *ours, ip_subnet *his
-, unsigned long count, time_t nw)
+void state_eroute_usage(ip_subnet *ours, ip_subnet *his, unsigned long count,
+ time_t nw)
{
- struct state *st;
- int i;
+ struct state *st;
+ int i;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- struct connection *c = st->st_connection;
-
- /* XXX spd-enum */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
- && c->spd.eroute_owner == st->st_serialno
- && c->spd.routing == RT_ROUTED_TUNNEL
- && samesubnet(&c->spd.this.client, ours)
- && samesubnet(&c->spd.that.client, his))
- {
- if (st->st_outbound_count != count)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
{
- st->st_outbound_count = count;
- st->st_outbound_time = nw;
+ struct connection *c = st->st_connection;
+
+ /* XXX spd-enum */
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state)
+ && c->spd.eroute_owner == st->st_serialno
+ && c->spd.routing == RT_ROUTED_TUNNEL
+ && samesubnet(&c->spd.this.client, ours)
+ && samesubnet(&c->spd.that.client, his))
+ {
+ if (st->st_outbound_count != count)
+ {
+ st->st_outbound_count = count;
+ st->st_outbound_time = nw;
+ }
+ return;
+ }
}
- return;
- }
}
- }
- DBG(DBG_CONTROL,
- {
- char ourst[SUBNETTOT_BUF];
- char hist[SUBNETTOT_BUF];
-
- subnettot(ours, 0, ourst, sizeof(ourst));
- subnettot(his, 0, hist, sizeof(hist));
- DBG_log("unknown tunnel eroute %s -> %s found in scan"
- , ourst, hist);
- });
+ DBG(DBG_CONTROL,
+ {
+ char ourst[SUBNETTOT_BUF];
+ char hist[SUBNETTOT_BUF];
+
+ subnettot(ours, 0, ourst, sizeof(ourst));
+ subnettot(his, 0, hist, sizeof(hist));
+ DBG_log("unknown tunnel eroute %s -> %s found in scan"
+ , ourst, hist);
+ });
}
-void fmt_state(bool all, struct state *st, time_t n
-, char *state_buf, size_t state_buf_len
-, char *state_buf2, size_t state_buf2_len)
+void fmt_state(bool all, struct state *st, time_t n, char *state_buf,
+ size_t state_buf_len, char *state_buf2, size_t state_buf2_len)
{
- /* what the heck is interesting about a state? */
- const struct connection *c = st->st_connection;
-
- long delta = st->st_event->ev_time >= n
- ? (long)(st->st_event->ev_time - n)
- : -(long)(n - st->st_event->ev_time);
-
- char inst[CONN_INST_BUF];
- const char *np1 = c->newest_isakmp_sa == st->st_serialno
- ? "; newest ISAKMP" : "";
- const char *np2 = c->newest_ipsec_sa == st->st_serialno
- ? "; newest IPSEC" : "";
- /* XXX spd-enum */
- const char *eo = c->spd.eroute_owner == st->st_serialno
- ? "; eroute owner" : "";
- const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
- ? "; DPD active" : "";
-
- passert(st->st_event != 0);
-
- fmt_conn_instance(c, inst);
-
- snprintf(state_buf, state_buf_len
- , "#%lu: \"%s\"%s %s (%s); %s in %lds%s%s%s%s"
- , st->st_serialno
- , c->name, inst
- , enum_name(&state_names, st->st_state)
- , state_story[st->st_state - STATE_MAIN_R0]
- , enum_name(&timer_event_names, st->st_event->ev_type)
- , delta
- , np1, np2, eo, dpd);
-
- /* print out SPIs if SAs are established */
- if (state_buf2_len != 0)
- state_buf2[0] = '\0'; /* default to empty */
- if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
- {
-
- bool tunnel;
- char buf[SATOT_BUF*6 + 2*20 + 1];
- const char *p_end = buf + sizeof(buf);
- char *p = buf;
-
-# define add_said(adst, aspi, aproto) { \
- ip_said s; \
- \
- initsaid(adst, aspi, aproto, &s); \
- if (p < p_end - 1) \
- { \
- *p++ = ' '; \
- p += satot(&s, 0, p, p_end - p) - 1; \
- } \
- }
+ /* what the heck is interesting about a state? */
+ const struct connection *c = st->st_connection;
+
+ long delta = st->st_event->ev_time >= n
+ ? (long)(st->st_event->ev_time - n)
+ : -(long)(n - st->st_event->ev_time);
+
+ char inst[CONN_INST_BUF];
+ const char *np1 = c->newest_isakmp_sa == st->st_serialno
+ ? "; newest ISAKMP" : "";
+ const char *np2 = c->newest_ipsec_sa == st->st_serialno
+ ? "; newest IPSEC" : "";
+ /* XXX spd-enum */
+ const char *eo = c->spd.eroute_owner == st->st_serialno
+ ? "; eroute owner" : "";
+ const char *dpd = (all && st->st_dpd && c->dpd_action != DPD_ACTION_NONE)
+ ? "; DPD active" : "";
+
+ passert(st->st_event != 0);
+
+ fmt_conn_instance(c, inst);
+
+ snprintf(state_buf, state_buf_len
+ , "#%lu: \"%s\"%s %s (%s); %N in %lds%s%s%s%s"
+ , st->st_serialno
+ , c->name, inst
+ , enum_name(&state_names, st->st_state)
+ , state_story[st->st_state - STATE_MAIN_R0]
+ , timer_event_names, st->st_event->ev_type
+ , delta
+ , np1, np2, eo, dpd);
+
+ /* print out SPIs if SAs are established */
+ if (state_buf2_len != 0)
+ state_buf2[0] = '\0'; /* default to empty */
+ if (IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ {
-# define add_sa_info(st, inbound) { \
- u_int bytes; \
- time_t use_time; \
- \
- if (get_sa_info(st, inbound, &bytes, &use_time)) \
- { \
- p += snprintf(p, p_end - p, " (%'u bytes", bytes); \
- if (bytes > 0 && use_time != UNDEFINED_TIME) \
- p += snprintf(p, p_end - p, ", %ds ago", (int)(now - use_time)); \
- p += snprintf(p, p_end - p, ")"); \
- } \
- }
+ bool tunnel;
+ char buf[SATOT_BUF*6 + 2*20 + 1];
+ const char *p_end = buf + sizeof(buf);
+ char *p = buf;
+
+# define add_said(adst, aspi, aproto) { \
+ ip_said s; \
+ \
+ initsaid(adst, aspi, aproto, &s); \
+ if (p < p_end - 1) \
+ { \
+ *p++ = ' '; \
+ p += satot(&s, 0, p, p_end - p) - 1; \
+ } \
+ }
- *p = '\0';
- if (st->st_ah.present)
- {
- add_said(&c->spd.that.host_addr, st->st_ah.attrs.spi, SA_AH);
- add_said(&c->spd.this.host_addr, st->st_ah.our_spi, SA_AH);
- }
- if (st->st_esp.present)
- {
- time_t now = time(NULL);
+# define add_sa_info(st, inbound) { \
+ u_int bytes; \
+ time_t use_time; \
+ \
+ if (get_sa_info(st, inbound, &bytes, &use_time)) \
+ { \
+ p += snprintf(p, p_end - p, " (%'u bytes", bytes); \
+ if (bytes > 0 && use_time != UNDEFINED_TIME) \
+ p += snprintf(p, p_end - p, ", %ds ago", (int)(now - use_time)); \
+ p += snprintf(p, p_end - p, ")"); \
+ } \
+ }
- add_said(&c->spd.that.host_addr, st->st_esp.attrs.spi, SA_ESP);
- add_sa_info(st, FALSE);
- add_said(&c->spd.this.host_addr, st->st_esp.our_spi, SA_ESP);
- add_sa_info(st, TRUE);
- }
- if (st->st_ipcomp.present)
- {
- add_said(&c->spd.that.host_addr, st->st_ipcomp.attrs.spi, SA_COMP);
- add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, SA_COMP);
- }
+ *p = '\0';
+ if (st->st_ah.present)
+ {
+ add_said(&c->spd.that.host_addr, st->st_ah.attrs.spi, SA_AH);
+ add_said(&c->spd.this.host_addr, st->st_ah.our_spi, SA_AH);
+ }
+ if (st->st_esp.present)
+ {
+ time_t now = time(NULL);
+
+ add_said(&c->spd.that.host_addr, st->st_esp.attrs.spi, SA_ESP);
+ add_sa_info(st, FALSE);
+ add_said(&c->spd.this.host_addr, st->st_esp.our_spi, SA_ESP);
+ add_sa_info(st, TRUE);
+ }
+ if (st->st_ipcomp.present)
+ {
+ add_said(&c->spd.that.host_addr, st->st_ipcomp.attrs.spi, SA_COMP);
+ add_said(&c->spd.this.host_addr, st->st_ipcomp.our_spi, SA_COMP);
+ }
#ifdef KLIPS
- tunnel = st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
- || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
- p += snprintf(p, p_end - p, "; %s", tunnel? "tunnel":"transport");
+ tunnel = st->st_ah.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_esp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL
+ || st->st_ipcomp.attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL;
+ p += snprintf(p, p_end - p, "; %s", tunnel? "tunnel":"transport");
#endif
- snprintf(state_buf2, state_buf2_len
- , "#%lu: \"%s\"%s%s"
- , st->st_serialno
- , c->name, inst
- , buf);
+ snprintf(state_buf2, state_buf2_len
+ , "#%lu: \"%s\"%s%s"
+ , st->st_serialno
+ , c->name, inst
+ , buf);
-# undef add_said
-# undef add_sa_info
- }
+# undef add_said
+# undef add_sa_info
+ }
}
/*
@@ -831,82 +820,80 @@ void fmt_state(bool all, struct state *st, time_t n
* isakmp_sa (XXX probably wrong)
*
*/
-static int
-state_compare(const void *a, const void *b)
+static int state_compare(const void *a, const void *b)
{
- const struct state *sap = *(const struct state *const *)a;
- struct connection *ca = sap->st_connection;
- const struct state *sbp = *(const struct state *const *)b;
- struct connection *cb = sbp->st_connection;
+ const struct state *sap = *(const struct state *const *)a;
+ struct connection *ca = sap->st_connection;
+ const struct state *sbp = *(const struct state *const *)b;
+ struct connection *cb = sbp->st_connection;
- /* DBG_log("comparing %s to %s", ca->name, cb->name); */
+ /* DBG_log("comparing %s to %s", ca->name, cb->name); */
- return connection_compare(ca, cb);
+ return connection_compare(ca, cb);
}
-void
-show_states_status(bool all, const char *name)
+void show_states_status(bool all, const char *name)
{
- time_t n = now();
- int i;
- char state_buf[LOG_WIDTH];
- char state_buf2[LOG_WIDTH];
- int count;
- struct state **array;
-
- /* make count of states */
- count = 0;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
+ time_t n = now();
+ int i;
+ char state_buf[LOG_WIDTH];
+ char state_buf2[LOG_WIDTH];
+ int count;
+ struct state **array;
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ /* make count of states */
+ count = 0;
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- if (name == NULL || streq(name, st->st_connection->name))
- count++;
- }
- }
+ struct state *st;
- /* build the array */
- array = alloc_bytes(sizeof(struct state *)*count, "state array");
- count = 0;
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ {
+ if (name == NULL || streq(name, st->st_connection->name))
+ count++;
+ }
+ }
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ /* build the array */
+ array = malloc(sizeof(struct state *)*count);
+ count = 0;
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- if (name == NULL || streq(name, st->st_connection->name))
- array[count++]=st;
+ struct state *st;
+
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ {
+ if (name == NULL || streq(name, st->st_connection->name))
+ array[count++]=st;
+ }
}
- }
- /* sort it! */
- qsort(array, count, sizeof(struct state *), state_compare);
+ /* sort it! */
+ qsort(array, count, sizeof(struct state *), state_compare);
- /* now print sorted results */
- for (i = 0; i < count; i++)
- {
- struct state *st;
+ /* now print sorted results */
+ for (i = 0; i < count; i++)
+ {
+ struct state *st;
- st = array[i];
+ st = array[i];
- fmt_state(all, st, n
- , state_buf, sizeof(state_buf)
- , state_buf2, sizeof(state_buf2));
- whack_log(RC_COMMENT, state_buf);
- if (state_buf2[0] != '\0')
- whack_log(RC_COMMENT, state_buf2);
+ fmt_state(all, st, n
+ , state_buf, sizeof(state_buf)
+ , state_buf2, sizeof(state_buf2));
+ whack_log(RC_COMMENT, state_buf);
+ if (state_buf2[0] != '\0')
+ whack_log(RC_COMMENT, state_buf2);
- /* show any associated pending Phase 2s */
- if (IS_PHASE1(st->st_state))
- show_pending_phase2(st->st_connection->host_pair, st);
- }
- if (count > 0)
- whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
+ /* show any associated pending Phase 2s */
+ if (IS_PHASE1(st->st_state))
+ show_pending_phase2(st->st_connection->host_pair, st);
+ }
+ if (count > 0)
+ whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
- /* free the array */
- pfree(array);
+ /* free the array */
+ free(array);
}
/* Given that we've used up a range of unused CPI's,
@@ -915,49 +902,48 @@ show_states_status(bool all, const char *name)
* If we can't find one easily, choose 0 (a bad SPI,
* no matter what order) indicating failure.
*/
-void
-find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
+void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi)
{
- int tries = 0;
- cpi_t base = *latest_cpi;
- cpi_t closest;
- int i;
+ int tries = 0;
+ cpi_t base = *latest_cpi;
+ cpi_t closest;
+ int i;
startover:
- closest = ~0; /* not close at all */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *st;
-
- for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+ closest = ~0; /* not close at all */
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- if (st->st_ipcomp.present)
- {
- cpi_t c = ntohl(st->st_ipcomp.our_spi) - base;
+ struct state *st;
- if (c < closest)
+ for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
{
- if (c == 0)
- {
- /* oops: next spot is occupied; start over */
- if (++tries == 20)
+ if (st->st_ipcomp.present)
{
- /* FAILURE */
- *latest_cpi = *first_busy_cpi = 0;
- return;
+ cpi_t c = ntohl(st->st_ipcomp.our_spi) - base;
+
+ if (c < closest)
+ {
+ if (c == 0)
+ {
+ /* oops: next spot is occupied; start over */
+ if (++tries == 20)
+ {
+ /* FAILURE */
+ *latest_cpi = *first_busy_cpi = 0;
+ return;
+ }
+ base++;
+ if (base > IPCOMP_LAST_NEGOTIATED)
+ base = IPCOMP_FIRST_NEGOTIATED;
+ goto startover; /* really a tail call */
+ }
+ closest = c;
+ }
}
- base++;
- if (base > IPCOMP_LAST_NEGOTIATED)
- base = IPCOMP_FIRST_NEGOTIATED;
- goto startover; /* really a tail call */
- }
- closest = c;
}
- }
}
- }
- *latest_cpi = base; /* base is first in next free range */
- *first_busy_cpi = closest + base; /* and this is the roof */
+ *latest_cpi = base; /* base is first in next free range */
+ *first_busy_cpi = closest + base; /* and this is the roof */
}
/* Muck with high-order 16 bits of this SPI in order to make
@@ -968,38 +954,42 @@ startover:
* If we can't find one easily, return 0 (a bad SPI,
* no matter what order) indicating failure.
*/
-ipsec_spi_t
-uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
+ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st)
{
- int tries = 0;
- int i;
+ int tries = 0;
+ int i;
+ rng_t *rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
startover:
- /* network order makes first two bytes our target */
- get_rnd_bytes((u_char *)&cpi, 2);
-
- /* Make sure that the result is unique.
- * Hard work. If there is no unique value, we'll loop forever!
- */
- for (i = 0; i < STATE_TABLE_SIZE; i++)
- {
- struct state *s;
+ /* network order makes first two bytes our target */
+ rng->get_bytes(rng, 2, (u_char *)&cpi);
- for (s = statetable[i]; s != NULL; s = s->st_hashchain_next)
+ /* Make sure that the result is unique.
+ * Hard work. If there is no unique value, we'll loop forever!
+ */
+ for (i = 0; i < STATE_TABLE_SIZE; i++)
{
- if (s->st_ipcomp.present
- && sameaddr(&s->st_connection->spd.that.host_addr
- , &st->st_connection->spd.that.host_addr)
- && cpi == s->st_ipcomp.attrs.spi)
- {
- if (++tries == 20)
- return 0; /* FAILURE */
- goto startover;
- }
+ struct state *s;
+
+ for (s = statetable[i]; s != NULL; s = s->st_hashchain_next)
+ {
+ if (s->st_ipcomp.present
+ && sameaddr(&s->st_connection->spd.that.host_addr
+ , &st->st_connection->spd.that.host_addr)
+ && cpi == s->st_ipcomp.attrs.spi)
+ {
+ if (++tries == 20)
+ {
+ rng->destroy(rng);
+ return 0; /* FAILURE */
+ }
+ goto startover;
+ }
+ }
}
- }
- return cpi;
+ rng->destroy(rng);
+ return cpi;
}
/*
diff --git a/src/pluto/state.h b/src/pluto/state.h
index 220dce341..a059c52b4 100644
--- a/src/pluto/state.h
+++ b/src/pluto/state.h
@@ -1,6 +1,7 @@
/* state and event objects
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2001 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -11,15 +12,14 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: state.h 3252 2007-10-06 21:24:50Z andreas $
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
-#include <gmp.h> /* GNU MP library */
+
+#include <crypto/diffie_hellman.h>
#include "connections.h"
@@ -40,10 +40,10 @@
* than specified by draft-jenkins-ipsec-rekeying-06.txt.
*/
-typedef u_int32_t msgid_t; /* Network order! */
+typedef u_int32_t msgid_t; /* Network order! */
#define MAINMODE_MSGID ((msgid_t) 0)
-struct state; /* forward declaration of tag */
+struct state; /* forward declaration of tag */
extern bool reserve_msgid(struct state *isakmp_sa, msgid_t msgid);
extern msgid_t generate_msgid(struct state *isakmp_sa);
@@ -54,17 +54,17 @@ extern msgid_t generate_msgid(struct state *isakmp_sa);
* Names are chosen to match corresponding names in state.
*/
struct oakley_trans_attrs {
- u_int16_t encrypt; /* Encryption algorithm */
- u_int16_t enckeylen; /* encryption key len (bits) */
- const struct encrypt_desc *encrypter; /* package of encryption routines */
- u_int16_t hash; /* Hash algorithm */
- const struct hash_desc *hasher; /* package of hashing routines */
- u_int16_t auth; /* Authentication method */
- const struct oakley_group_desc *group; /* Oakley group */
- time_t life_seconds; /* When this SA expires (seconds) */
- u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
+ u_int16_t encrypt; /* Encryption algorithm */
+ u_int16_t enckeylen; /* encryption key len (bits) */
+ const struct encrypt_desc *encrypter; /* package of encryption routines */
+ u_int16_t hash; /* Hash algorithm */
+ const struct hash_desc *hasher; /* package of hashing routines */
+ u_int16_t auth; /* Authentication method */
+ const struct dh_desc *group; /* Diffie-Hellman group */
+ time_t life_seconds; /* When this SA expires (seconds) */
+ u_int32_t life_kilobytes; /* When this SA is exhausted (kilobytes) */
#if 0 /* not yet */
- u_int16_t prf; /* Pseudo Random Function */
+ u_int16_t prf; /* Pseudo Random Function */
#endif
};
@@ -74,28 +74,28 @@ struct oakley_trans_attrs {
* for ESP, and a funny one for IPCOMP.
*/
struct ipsec_trans_attrs {
- u_int8_t transid; /* transform id */
- ipsec_spi_t spi; /* his SPI */
- time_t life_seconds; /* When this SA expires */
- u_int32_t life_kilobytes; /* When this SA expires */
- u_int16_t encapsulation;
- u_int16_t auth;
- u_int16_t key_len;
- u_int16_t key_rounds;
+ u_int8_t transid; /* transform id */
+ ipsec_spi_t spi; /* his SPI */
+ time_t life_seconds; /* When this SA expires */
+ u_int32_t life_kilobytes; /* When this SA expires */
+ u_int16_t encapsulation;
+ u_int16_t auth;
+ u_int16_t key_len;
+ u_int16_t key_rounds;
#if 0 /* not implemented yet */
- u_int16_t cmprs_dict_sz;
- u_int32_t cmprs_alg;
+ u_int16_t cmprs_dict_sz;
+ u_int32_t cmprs_alg;
#endif
};
/* IPsec per protocol state information */
struct ipsec_proto_info {
- bool present; /* was this transform specified? */
- struct ipsec_trans_attrs attrs;
- ipsec_spi_t our_spi;
- u_int16_t keymat_len; /* same for both */
- u_char *our_keymat;
- u_char *peer_keymat;
+ bool present; /* was this transform specified? */
+ struct ipsec_trans_attrs attrs;
+ ipsec_spi_t our_spi;
+ u_int16_t keymat_len; /* same for both */
+ u_char *our_keymat;
+ u_char *peer_keymat;
};
/* state object: record the state of a (possibly nascent) SA
@@ -107,135 +107,133 @@ struct ipsec_proto_info {
*/
struct state
{
- so_serial_t st_serialno; /* serial number (for seniority) */
- so_serial_t st_clonedfrom; /* serial number of parent */
+ so_serial_t st_serialno; /* serial number (for seniority) */
+ so_serial_t st_clonedfrom; /* serial number of parent */
- struct connection *st_connection; /* connection for this SA */
+ struct connection *st_connection; /* connection for this SA */
- int st_whack_sock; /* fd for our Whack TCP socket.
- * Single copy: close when freeing struct.
- */
+ int st_whack_sock; /* fd for our Whack TCP socket.
+ * Single copy: close when freeing struct.
+ */
- struct msg_digest *st_suspended_md; /* suspended state-transition */
+ struct msg_digest *st_suspended_md; /* suspended state-transition */
- struct oakley_trans_attrs st_oakley;
+ struct oakley_trans_attrs st_oakley;
- struct ipsec_proto_info st_ah;
- struct ipsec_proto_info st_esp;
- struct ipsec_proto_info st_ipcomp;
+ struct ipsec_proto_info st_ah;
+ struct ipsec_proto_info st_esp;
+ struct ipsec_proto_info st_ipcomp;
#ifdef KLIPS
- ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
- ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
+ ipsec_spi_t st_tunnel_in_spi; /* KLUDGE */
+ ipsec_spi_t st_tunnel_out_spi; /* KLUDGE */
#endif
- const struct oakley_group_desc *st_pfs_group; /* group for Phase 2 PFS */
+ const struct dh_desc *st_pfs_group; /* group for Phase 2 PFS */
- u_int32_t st_doi; /* Domain of Interpretation */
- u_int32_t st_situation;
+ u_int32_t st_doi; /* Domain of Interpretation */
+ u_int32_t st_situation;
- lset_t st_policy; /* policy for IPsec SA */
+ lset_t st_policy; /* policy for IPsec SA */
- msgid_t st_msgid; /* MSG-ID from header. Network Order! */
+ msgid_t st_msgid; /* MSG-ID from header. Network Order! */
- /* only for a state representing an ISAKMP SA */
- struct msgid_list *st_used_msgids; /* used-up msgids */
+ /* only for a state representing an ISAKMP SA */
+ struct msgid_list *st_used_msgids; /* used-up msgids */
/* symmetric stuff */
/* initiator stuff */
- chunk_t st_gi; /* Initiator public value */
- u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
- chunk_t st_ni; /* Ni nonce */
+ chunk_t st_gi; /* Initiator public value */
+ u_int8_t st_icookie[COOKIE_SIZE];/* Initiator Cookie */
+ chunk_t st_ni; /* Ni nonce */
/* responder stuff */
- chunk_t st_gr; /* Responder public value */
- u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
- chunk_t st_nr; /* Nr nonce */
+ chunk_t st_gr; /* Responder public value */
+ u_int8_t st_rcookie[COOKIE_SIZE];/* Responder Cookie */
+ chunk_t st_nr; /* Nr nonce */
/* my stuff */
- chunk_t st_tpacket; /* Transmitted packet */
+ chunk_t st_tpacket; /* Transmitted packet */
- /* Phase 2 ID payload info about my user */
- u_int8_t st_myuserprotoid; /* IDcx.protoid */
- u_int16_t st_myuserport;
+ /* Phase 2 ID payload info about my user */
+ u_int8_t st_myuserprotoid; /* IDcx.protoid */
+ u_int16_t st_myuserport;
/* his stuff */
- chunk_t st_rpacket; /* Received packet */
+ chunk_t st_rpacket; /* Received packet */
- /* Phase 2 ID payload info about peer's user */
- u_int8_t st_peeruserprotoid; /* IDcx.protoid */
- u_int16_t st_peeruserport;
+ /* Phase 2 ID payload info about peer's user */
+ u_int8_t st_peeruserprotoid; /* IDcx.protoid */
+ u_int16_t st_peeruserport;
/* end of symmetric stuff */
- u_int8_t st_sec_in_use; /* bool: does st_sec hold a value */
- MP_INT st_sec; /* Our local secret value */
-
- chunk_t st_shared; /* Derived shared secret
- * Note: during Quick Mode,
- * presence indicates PFS
- * selected.
- */
-
- /* In a Phase 1 state, preserve peer's public key after authentication */
- struct pubkey *st_peer_pubkey;
-
- enum state_kind st_state; /* State of exchange */
- u_int8_t st_retransmit; /* Number of retransmits */
- unsigned long st_try; /* number of times rekeying attempted */
- /* 0 means the only time */
- time_t st_margin; /* life after EVENT_SA_REPLACE */
- unsigned long st_outbound_count; /* traffic through eroute */
- time_t st_outbound_time; /* time of last change to st_outbound_count */
- chunk_t st_p1isa; /* Phase 1 initiator SA (Payload) for HASH */
- chunk_t st_skeyid; /* Key material */
- chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
- chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
- chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
- u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
- u_char st_new_iv[MAX_DIGEST_LEN];
- u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
- unsigned int st_iv_len;
- unsigned int st_new_iv_len;
- unsigned int st_ph1_iv_len;
-
- chunk_t st_enc_key; /* Oakley Encryption key */
-
- struct event *st_event; /* backpointer for certain events */
- struct state *st_hashchain_next; /* Next in list */
- struct state *st_hashchain_prev; /* Previous in list */
-
- struct {
- bool vars_set;
- bool started;
- } st_modecfg;
-
- struct {
- int attempt;
- bool started;
- bool status;
- } st_xauth;
-
- u_int32_t nat_traversal;
- ip_address nat_oa;
-
- /* RFC 3706 Dead Peer Detection */
- bool st_dpd; /* Peer supports DPD */
- time_t st_last_dpd; /* Time of last DPD transmit */
- u_int32_t st_dpd_seqno; /* Next R_U_THERE to send */
- u_int32_t st_dpd_expectseqno; /* Next R_U_THERE_ACK to receive */
- u_int32_t st_dpd_peerseqno; /* global variables */
- struct event *st_dpd_event; /* backpointer for DPD events */
-
- u_int32_t st_seen_vendorid; /* Bit field about recognized Vendor ID */
+ diffie_hellman_t *st_dh; /* Our local DH secret value */
+ chunk_t st_shared; /* Derived shared secret
+ * Note: during Quick Mode,
+ * presence indicates PFS
+ * selected.
+ */
+
+ /* In a Phase 1 state, preserve peer's public key after authentication */
+ struct pubkey *st_peer_pubkey;
+
+ enum state_kind st_state; /* State of exchange */
+ u_int8_t st_retransmit; /* Number of retransmits */
+ unsigned long st_try; /* number of times rekeying attempted */
+ /* 0 means the only time */
+ time_t st_margin; /* life after EVENT_SA_REPLACE */
+ unsigned long st_outbound_count; /* traffic through eroute */
+ time_t st_outbound_time; /* time of last change to st_outbound_count */
+ chunk_t st_p1isa; /* Phase 1 initiator SA (Payload) for HASH */
+ chunk_t st_skeyid; /* Key material */
+ chunk_t st_skeyid_d; /* KM for non-ISAKMP key derivation */
+ chunk_t st_skeyid_a; /* KM for ISAKMP authentication */
+ chunk_t st_skeyid_e; /* KM for ISAKMP encryption */
+ u_char st_iv[MAX_DIGEST_LEN]; /* IV for encryption */
+ u_char st_new_iv[MAX_DIGEST_LEN];
+ u_char st_ph1_iv[MAX_DIGEST_LEN]; /* IV at end if phase 1 */
+ unsigned int st_iv_len;
+ unsigned int st_new_iv_len;
+ unsigned int st_ph1_iv_len;
+
+ chunk_t st_enc_key; /* Oakley Encryption key */
+
+ struct event *st_event; /* backpointer for certain events */
+ struct state *st_hashchain_next; /* Next in list */
+ struct state *st_hashchain_prev; /* Previous in list */
+
+ struct {
+ bool vars_set;
+ bool started;
+ } st_modecfg;
+
+ struct {
+ int attempt;
+ bool started;
+ bool status;
+ } st_xauth;
+
+ u_int32_t nat_traversal;
+ ip_address nat_oa;
+
+ /* RFC 3706 Dead Peer Detection */
+ bool st_dpd; /* Peer supports DPD */
+ time_t st_last_dpd; /* Time of last DPD transmit */
+ u_int32_t st_dpd_seqno; /* Next R_U_THERE to send */
+ u_int32_t st_dpd_expectseqno; /* Next R_U_THERE_ACK to receive */
+ u_int32_t st_dpd_peerseqno; /* global variables */
+ struct event *st_dpd_event; /* backpointer for DPD events */
+
+ u_int32_t st_seen_vendorid; /* Bit field about recognized Vendor ID */
};
/* global variables */
-extern u_int16_t pluto_port; /* Pluto's port */
+extern u_int16_t pluto_port; /* Pluto's port */
extern bool states_use_connection(struct connection *c);
@@ -247,27 +245,27 @@ extern void insert_state(struct state *st);
extern void unhash_state(struct state *st);
extern void release_whack(struct state *st);
extern void state_eroute_usage(ip_subnet *ours, ip_subnet *his
- , unsigned long count, time_t nw);
+ , unsigned long count, time_t nw);
extern void delete_state(struct state *st);
extern void delete_states_by_connection(struct connection *c, bool relations);
extern struct state
- *duplicate_state(struct state *st),
- *find_state(const u_char *icookie
- , const u_char *rcookie
- , const ip_address *peer
- , msgid_t msgid),
- *state_with_serialno(so_serial_t sn),
- *find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
- , ipsec_spi_t spi, bool *bogus),
- *find_phase1_state(const struct connection *c, lset_t ok_states),
- *find_sender(size_t packet_len, u_char *packet);
+ *duplicate_state(struct state *st),
+ *find_state(const u_char *icookie
+ , const u_char *rcookie
+ , const ip_address *peer
+ , msgid_t msgid),
+ *state_with_serialno(so_serial_t sn),
+ *find_phase2_state_to_delete(const struct state *p1st, u_int8_t protoid
+ , ipsec_spi_t spi, bool *bogus),
+ *find_phase1_state(const struct connection *c, lset_t ok_states),
+ *find_sender(size_t packet_len, u_char *packet);
extern void show_states_status(bool all, const char *name);
extern void for_each_state(void *(f)(struct state *, void *data), void *data);
extern void find_my_cpi_gap(cpi_t *latest_cpi, cpi_t *first_busy_cpi);
extern ipsec_spi_t uniquify_his_cpi(ipsec_spi_t cpi, struct state *st);
extern void fmt_state(bool all, struct state *st, time_t n
- , char *state_buf, size_t state_buf_len
- , char *state_buf2, size_t state_buf_len2);
+ , char *state_buf, size_t state_buf_len
+ , char *state_buf2, size_t state_buf_len2);
extern void delete_states_by_peer(ip_address *peer);
diff --git a/src/pluto/timer.c b/src/pluto/timer.c
index aea293098..ecbee740f 100644
--- a/src/pluto/timer.c
+++ b/src/pluto/timer.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: timer.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdio.h>
@@ -26,36 +24,39 @@
#include <freeswan.h>
+#include <library.h>
+#include <crypto/rngs/rng.h>
+
#include "constants.h"
#include "defs.h"
#include "connections.h"
#include "state.h"
#include "demux.h"
-#include "ipsec_doi.h" /* needs demux.h and state.h */
+#include "ipsec_doi.h" /* needs demux.h and state.h */
#include "kernel.h"
#include "server.h"
#include "log.h"
-#include "rnd.h"
#include "timer.h"
#include "whack.h"
#include "nat_traversal.h"
-/* monotonic version of time(3) */
-time_t
-now(void)
+/**
+ * monotonic version of time(3)
+ */
+time_t now(void)
{
- static time_t delta = 0
- , last_time = 0;
- time_t n = time((time_t)NULL);
-
- passert(n != (time_t)-1);
- if (last_time > n)
- {
- plog("time moved backwards %ld seconds", (long)(last_time - n));
- delta += last_time - n;
- }
- last_time = n;
- return n + delta;
+ static time_t delta = 0
+ , last_time = 0;
+ time_t n = time((time_t)NULL);
+
+ passert(n != (time_t)-1);
+ if (last_time > n)
+ {
+ plog("time moved backwards %ld seconds", (long)(last_time - n));
+ delta += last_time - n;
+ }
+ last_time = n;
+ return n + delta;
}
/* This file has the event handling routines. Events are
@@ -66,467 +67,495 @@ now(void)
static struct event *evlist = (struct event *) NULL;
-/*
+/**
* This routine places an event in the event list.
*/
-void
-event_schedule(enum event_type type, time_t tm, struct state *st)
+void event_schedule(enum event_type type, time_t tm, struct state *st)
{
- struct event *ev = alloc_thing(struct event, "struct event in event_schedule()");
-
- ev->ev_type = type;
- ev->ev_time = tm + now();
- ev->ev_state = st;
-
- /* If the event is associated with a state, put a backpointer to the
- * event in the state object, so we can find and delete the event
- * if we need to (for example, if we receive a reply).
- */
- if (st != NULL)
- {
- if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
+ struct event *ev = malloc_thing(struct event);
+
+ ev->ev_type = type;
+ ev->ev_time = tm + now();
+ ev->ev_state = st;
+
+ /* If the event is associated with a state, put a backpointer to the
+ * event in the state object, so we can find and delete the event
+ * if we need to (for example, if we receive a reply).
+ */
+ if (st != NULL)
+ {
+ if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
+ {
+ passert(st->st_dpd_event == NULL);
+ st->st_dpd_event = ev;
+ }
+ else
+ {
+ passert(st->st_event == NULL);
+ st->st_event = ev;
+ }
+ }
+
+ DBG(DBG_CONTROL,
+ if (st == NULL)
+ DBG_log("inserting event %N, timeout in %lu seconds"
+ , timer_event_names, type, (unsigned long)tm);
+ else
+ DBG_log("inserting event %N, timeout in %lu seconds for #%lu"
+ , timer_event_names, type, (unsigned long)tm
+ , ev->ev_state->st_serialno));
+
+ if (evlist == (struct event *) NULL
+ || evlist->ev_time >= ev->ev_time)
{
- passert(st->st_dpd_event == NULL);
- st->st_dpd_event = ev;
+ ev->ev_next = evlist;
+ evlist = ev;
}
else
{
- passert(st->st_event == NULL);
- st->st_event = ev;
- }
- }
+ struct event *evt;
- DBG(DBG_CONTROL,
- if (st == NULL)
- DBG_log("inserting event %s, timeout in %lu seconds"
- , enum_show(&timer_event_names, type), (unsigned long)tm);
- else
- DBG_log("inserting event %s, timeout in %lu seconds for #%lu"
- , enum_show(&timer_event_names, type), (unsigned long)tm
- , ev->ev_state->st_serialno));
-
- if (evlist == (struct event *) NULL
- || evlist->ev_time >= ev->ev_time)
- {
- ev->ev_next = evlist;
- evlist = ev;
- }
- else
- {
- struct event *evt;
-
- for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
- if (evt->ev_next->ev_time >= ev->ev_time)
- break;
-
-#ifdef NEVER /* this seems to be overkill */
- DBG(DBG_CONTROL,
- if (evt->ev_state == NULL)
- DBG_log("event added after event %s"
- , enum_show(&timer_event_names, evt->ev_type));
- else
- DBG_log("event added after event %s for #%lu"
- , enum_show(&timer_event_names, evt->ev_type)
- , evt->ev_state->st_serialno));
+ for (evt = evlist; evt->ev_next != NULL; evt = evt->ev_next)
+ if (evt->ev_next->ev_time >= ev->ev_time)
+ break;
+
+#ifdef NEVER /* this seems to be overkill */
+ DBG(DBG_CONTROL,
+ if (evt->ev_state == NULL)
+ DBG_log("event added after event %N"
+ , timer_event_names, evt->ev_type);
+ else
+ DBG_log("event added after event %N for #%lu"
+ , timer_event_names, evt->ev_type,
+ , evt->ev_state->st_serialno));
#endif /* NEVER */
- ev->ev_next = evt->ev_next;
- evt->ev_next = ev;
- }
+ ev->ev_next = evt->ev_next;
+ evt->ev_next = ev;
+ }
+}
+
+/**
+ * Generate the secret value for responder cookies, and
+ * schedule an event for refresh.
+ */
+void init_secret(void)
+{
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ rng->get_bytes(rng, sizeof(secret_of_the_day), secret_of_the_day);
+ rng->destroy(rng);
+ event_schedule(EVENT_REINIT_SECRET, EVENT_REINIT_SECRET_DELAY, NULL);
}
-/*
+/**
* Handle the first event on the list.
*/
-void
-handle_timer_event(void)
+void handle_timer_event(void)
{
- time_t tm;
- struct event *ev = evlist;
- int type;
- struct state *st;
- struct connection *c = NULL;
- ip_address peer;
-
- if (ev == (struct event *) NULL) /* Just paranoid */
- {
- DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
- return;
- }
-
- type = ev->ev_type;
- st = ev->ev_state;
-
- tm = now();
-
- if (tm < ev->ev_time)
- {
- DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %s)"
- , (unsigned long)tm, (unsigned long)ev->ev_time
- , enum_show(&timer_event_names, type)));
-
- /* This will happen if the most close-to-expire event was
- * a retransmission or cleanup, and we received a packet
- * at the same time as the event expired. Due to the processing
- * order in call_server(), the packet processing will happen first,
- * and the event will be removed.
- */
- return;
- }
-
- evlist = evlist->ev_next; /* Ok, we'll handle this event */
-
- DBG(DBG_CONTROL,
- if (evlist != (struct event *) NULL)
- DBG_log("event after this is %s in %ld seconds"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long) (evlist->ev_time - tm)));
-
- /* for state-associated events, pick up the state pointer
- * and remove the backpointer from the state object.
- * We'll eventually either schedule a new event, or delete the state.
- */
- passert(GLOBALS_ARE_RESET());
- if (st != NULL)
- {
- c = st->st_connection;
- if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
+ time_t tm;
+ struct event *ev = evlist;
+ int type;
+ struct state *st;
+ struct connection *c = NULL;
+ ip_address peer;
+
+ if (ev == (struct event *) NULL) /* Just paranoid */
{
- passert(st->st_dpd_event == ev);
- st->st_dpd_event = NULL;
+ DBG(DBG_CONTROL, DBG_log("empty event list, yet we're called"));
+ return;
}
- else
+
+ type = ev->ev_type;
+ st = ev->ev_state;
+
+ tm = now();
+
+ if (tm < ev->ev_time)
{
- passert(st->st_event == ev);
- st->st_event = NULL;
+ DBG(DBG_CONTROL, DBG_log("called while no event expired (%lu/%lu, %N)"
+ , (unsigned long)tm, (unsigned long)ev->ev_time
+ , timer_event_names, type));
+
+ /* This will happen if the most close-to-expire event was
+ * a retransmission or cleanup, and we received a packet
+ * at the same time as the event expired. Due to the processing
+ * order in call_server(), the packet processing will happen first,
+ * and the event will be removed.
+ */
+ return;
}
- peer = c->spd.that.host_addr;
- set_cur_state(st);
- }
-
- switch (type)
- {
- case EVENT_REINIT_SECRET:
- passert(st == NULL);
- DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
- init_secret();
- break;
-#ifdef KLIPS
- case EVENT_SHUNT_SCAN:
- passert(st == NULL);
- scan_proc_shunts();
- break;
-#endif
+ evlist = evlist->ev_next; /* Ok, we'll handle this event */
- case EVENT_LOG_DAILY:
- daily_log_event();
- break;
-
- case EVENT_RETRANSMIT:
- /* Time to retransmit, or give up.
- *
- * Generally, we'll only try to send the message
- * MAXIMUM_RETRANSMISSIONS times. Each time we double
- * our patience.
- *
- * As a special case, if this is the first initiating message
- * of a Main Mode exchange, and we have been directed to try
- * forever, we'll extend the number of retransmissions to
- * MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
- * extended attempts having the same patience. The intention
- * is to reduce the bother when nobody is home.
- */
- {
- time_t delay = 0;
-
- DBG(DBG_CONTROL, DBG_log(
- "handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
- , ip_str(&peer), c->name, st->st_serialno));
-
- if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
- delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
- else if (st->st_state == STATE_MAIN_I1
- && c->sa_keying_tries == 0
- && st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
- delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
-
- if (delay != 0)
+ DBG(DBG_CONTROL,
+ if (evlist != (struct event *) NULL)
+ DBG_log("event after this is %N in %ld seconds"
+ , timer_event_names, evlist->ev_type
+ , (long) (evlist->ev_time - tm)));
+
+ /* for state-associated events, pick up the state pointer
+ * and remove the backpointer from the state object.
+ * We'll eventually either schedule a new event, or delete the state.
+ */
+ passert(GLOBALS_ARE_RESET());
+ if (st != NULL)
+ {
+ c = st->st_connection;
+ if (type == EVENT_DPD || type == EVENT_DPD_TIMEOUT)
{
- st->st_retransmit++;
- whack_log(RC_RETRANSMISSION
- , "%s: retransmission; will wait %lus for response"
- , enum_name(&state_names, st->st_state)
- , (unsigned long)delay);
- send_packet(st, "EVENT_RETRANSMIT");
- event_schedule(EVENT_RETRANSMIT, delay, st);
+ passert(st->st_dpd_event == ev);
+ st->st_dpd_event = NULL;
}
- else
+ else
{
- /* check if we've tried rekeying enough times.
- * st->st_try == 0 means that this should be the only try.
- * c->sa_keying_tries == 0 means that there is no limit.
- */
- unsigned long try = st->st_try;
- unsigned long try_limit = c->sa_keying_tries;
- const char *details = "";
-
- switch (st->st_state)
- {
- case STATE_MAIN_I3:
- details = ". Possible authentication failure:"
- " no acceptable response to our"
- " first encrypted message";
- break;
- case STATE_MAIN_I1:
- details = ". No response (or no acceptable response) to our"
- " first IKE message";
- break;
- case STATE_QUICK_I1:
- if (c->newest_ipsec_sa == SOS_NOBODY)
- details = ". No acceptable response to our"
- " first Quick Mode message:"
- " perhaps peer likes no proposal";
+ passert(st->st_event == ev);
+ st->st_event = NULL;
+ }
+ peer = c->spd.that.host_addr;
+ set_cur_state(st);
+ }
+
+ switch (type)
+ {
+ case EVENT_REINIT_SECRET:
+ passert(st == NULL);
+ DBG(DBG_CONTROL, DBG_log("event EVENT_REINIT_SECRET handled"));
+ init_secret();
break;
- default:
+
+#ifdef KLIPS
+ case EVENT_SHUNT_SCAN:
+ passert(st == NULL);
+ scan_proc_shunts();
break;
- }
- loglog(RC_NORETRANSMISSION
- , "max number of retransmissions (%d) reached %s%s"
- , st->st_retransmit
- , enum_show(&state_names, st->st_state), details);
- if (try != 0 && try != try_limit)
- {
- /* A lot like EVENT_SA_REPLACE, but over again.
- * Since we know that st cannot be in use,
- * we can delete it right away.
- */
- char story[80]; /* arbitrary limit */
+#endif
- try++;
- snprintf(story, sizeof(story), try_limit == 0
- ? "starting keying attempt %ld of an unlimited number"
- : "starting keying attempt %ld of at most %ld"
- , try, try_limit);
+ case EVENT_LOG_DAILY:
+ daily_log_event();
+ break;
- if (st->st_whack_sock != NULL_FD)
+ case EVENT_RETRANSMIT:
+ /* Time to retransmit, or give up.
+ *
+ * Generally, we'll only try to send the message
+ * MAXIMUM_RETRANSMISSIONS times. Each time we double
+ * our patience.
+ *
+ * As a special case, if this is the first initiating message
+ * of a Main Mode exchange, and we have been directed to try
+ * forever, we'll extend the number of retransmissions to
+ * MAXIMUM_RETRANSMISSIONS_INITIAL times, with all these
+ * extended attempts having the same patience. The intention
+ * is to reduce the bother when nobody is home.
+ */
{
- /* Release whack because the observer will get bored. */
- loglog(RC_COMMENT, "%s, but releasing whack"
- , story);
- release_pending_whacks(st, story);
+ time_t delay = 0;
+
+ DBG(DBG_CONTROL, DBG_log(
+ "handling event EVENT_RETRANSMIT for %s \"%s\" #%lu"
+ , ip_str(&peer), c->name, st->st_serialno));
+
+ if (st->st_retransmit < MAXIMUM_RETRANSMISSIONS)
+ delay = EVENT_RETRANSMIT_DELAY_0 << (st->st_retransmit + 1);
+ else if (st->st_state == STATE_MAIN_I1
+ && c->sa_keying_tries == 0
+ && st->st_retransmit < MAXIMUM_RETRANSMISSIONS_INITIAL)
+ delay = EVENT_RETRANSMIT_DELAY_0 << MAXIMUM_RETRANSMISSIONS;
+
+ if (delay != 0)
+ {
+ st->st_retransmit++;
+ whack_log(RC_RETRANSMISSION
+ , "%s: retransmission; will wait %lus for response"
+ , enum_name(&state_names, st->st_state)
+ , (unsigned long)delay);
+ send_packet(st, "EVENT_RETRANSMIT");
+ event_schedule(EVENT_RETRANSMIT, delay, st);
+ }
+ else
+ {
+ /* check if we've tried rekeying enough times.
+ * st->st_try == 0 means that this should be the only try.
+ * c->sa_keying_tries == 0 means that there is no limit.
+ */
+ unsigned long try = st->st_try;
+ unsigned long try_limit = c->sa_keying_tries;
+ const char *details = "";
+
+ switch (st->st_state)
+ {
+ case STATE_MAIN_I3:
+ details = ". Possible authentication failure:"
+ " no acceptable response to our"
+ " first encrypted message";
+ break;
+ case STATE_MAIN_I1:
+ details = ". No response (or no acceptable response) to our"
+ " first IKE message";
+ break;
+ case STATE_QUICK_I1:
+ if (c->newest_ipsec_sa == SOS_NOBODY)
+ details = ". No acceptable response to our"
+ " first Quick Mode message:"
+ " perhaps peer likes no proposal";
+ break;
+ default:
+ break;
+ }
+ loglog(RC_NORETRANSMISSION
+ , "max number of retransmissions (%d) reached %s%s"
+ , st->st_retransmit
+ , enum_show(&state_names, st->st_state), details);
+ if (try != 0 && try != try_limit)
+ {
+ /* A lot like EVENT_SA_REPLACE, but over again.
+ * Since we know that st cannot be in use,
+ * we can delete it right away.
+ */
+ char story[80]; /* arbitrary limit */
+
+ try++;
+ snprintf(story, sizeof(story), try_limit == 0
+ ? "starting keying attempt %ld of an unlimited number"
+ : "starting keying attempt %ld of at most %ld"
+ , try, try_limit);
+
+ if (st->st_whack_sock != NULL_FD)
+ {
+ /* Release whack because the observer will get bored. */
+ loglog(RC_COMMENT, "%s, but releasing whack"
+ , story);
+ release_pending_whacks(st, story);
+ }
+ else
+ {
+ /* no whack: just log to syslog */
+ plog("%s", story);
+ }
+ ipsecdoi_replace(st, try);
+ }
+ delete_state(st);
+ }
}
- else
+ break;
+
+ case EVENT_SA_REPLACE:
+ case EVENT_SA_REPLACE_IF_USED:
{
- /* no whack: just log to syslog */
- plog("%s", story);
+ so_serial_t newest = IS_PHASE1(st->st_state)
+ ? c->newest_isakmp_sa : c->newest_ipsec_sa;
+
+ if (newest != st->st_serialno
+ && newest != SOS_NOBODY)
+ {
+ /* not very interesting: no need to replace */
+ DBG(DBG_LIFECYCLE
+ , plog("not replacing stale %s SA: #%lu will do"
+ , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
+ , newest));
+ }
+ else if (type == EVENT_SA_REPLACE_IF_USED
+ && st->st_outbound_time <= tm - c->sa_rekey_margin)
+ {
+ /* we observed no recent use: no need to replace
+ *
+ * The sampling effects mean that st_outbound_time
+ * could be up to SHUNT_SCAN_INTERVAL more recent
+ * than actual traffic because the sampler looks at change
+ * over that interval.
+ * st_outbound_time could also not yet reflect traffic
+ * in the last SHUNT_SCAN_INTERVAL.
+ * We expect that SHUNT_SCAN_INTERVAL is smaller than
+ * c->sa_rekey_margin so that the effects of this will
+ * be unimportant.
+ * This is just an optimization: correctness is not
+ * at stake.
+ *
+ * Note: we are abusing the DBG mechanism to control
+ * normal log output.
+ */
+ DBG(DBG_LIFECYCLE
+ , plog("not replacing stale %s SA: inactive for %lus"
+ , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
+ , (unsigned long)(tm - st->st_outbound_time)));
+ }
+ else
+ {
+ DBG(DBG_LIFECYCLE
+ , plog("replacing stale %s SA"
+ , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
+ ipsecdoi_replace(st, 1);
+ }
+ delete_dpd_event(st);
+ event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
}
- ipsecdoi_replace(st, try);
- }
- delete_state(st);
- }
- }
- break;
-
- case EVENT_SA_REPLACE:
- case EVENT_SA_REPLACE_IF_USED:
- {
- so_serial_t newest = IS_PHASE1(st->st_state)
- ? c->newest_isakmp_sa : c->newest_ipsec_sa;
-
- if (newest != st->st_serialno
- && newest != SOS_NOBODY)
- {
- /* not very interesting: no need to replace */
- DBG(DBG_LIFECYCLE
- , plog("not replacing stale %s SA: #%lu will do"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
- , newest));
- }
- else if (type == EVENT_SA_REPLACE_IF_USED
- && st->st_outbound_time <= tm - c->sa_rekey_margin)
- {
- /* we observed no recent use: no need to replace
- *
- * The sampling effects mean that st_outbound_time
- * could be up to SHUNT_SCAN_INTERVAL more recent
- * than actual traffic because the sampler looks at change
- * over that interval.
- * st_outbound_time could also not yet reflect traffic
- * in the last SHUNT_SCAN_INTERVAL.
- * We expect that SHUNT_SCAN_INTERVAL is smaller than
- * c->sa_rekey_margin so that the effects of this will
- * be unimportant.
- * This is just an optimization: correctness is not
- * at stake.
- *
- * Note: we are abusing the DBG mechanism to control
- * normal log output.
- */
- DBG(DBG_LIFECYCLE
- , plog("not replacing stale %s SA: inactive for %lus"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"
- , (unsigned long)(tm - st->st_outbound_time)));
- }
- else
- {
- DBG(DBG_LIFECYCLE
- , plog("replacing stale %s SA"
- , IS_PHASE1(st->st_state)? "ISAKMP" : "IPsec"));
- ipsecdoi_replace(st, 1);
- }
- delete_dpd_event(st);
- event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
- }
- break;
+ break;
- case EVENT_SA_EXPIRE:
- {
- const char *satype;
- so_serial_t latest;
+ case EVENT_SA_EXPIRE:
+ {
+ const char *satype;
+ so_serial_t latest;
+
+ if (IS_PHASE1(st->st_state))
+ {
+ satype = "ISAKMP";
+ latest = c->newest_isakmp_sa;
+ }
+ else
+ {
+ satype = "IPsec";
+ latest = c->newest_ipsec_sa;
+ }
+
+ if (st->st_serialno != latest)
+ {
+ /* not very interesting: already superseded */
+ DBG(DBG_LIFECYCLE
+ , plog("%s SA expired (superseded by #%lu)"
+ , satype, latest));
+ }
+ else
+ {
+ plog("%s SA expired (%s)", satype
+ , (c->policy & POLICY_DONT_REKEY)
+ ? "--dontrekey"
+ : "LATEST!"
+ );
+ }
+ }
+ /* FALLTHROUGH */
+ case EVENT_SO_DISCARD:
+ /* Delete this state object. It must be in the hash table. */
+ delete_state(st);
+ break;
- if (IS_PHASE1(st->st_state))
- {
- satype = "ISAKMP";
- latest = c->newest_isakmp_sa;
- }
- else
- {
- satype = "IPsec";
- latest = c->newest_ipsec_sa;
- }
+ case EVENT_DPD:
+ dpd_outI(st);
+ break;
+ case EVENT_DPD_TIMEOUT:
+ dpd_timeout(st);
+ break;
+ case EVENT_NAT_T_KEEPALIVE:
+ nat_traversal_ka_event();
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %N"
+ , timer_event_names, type);
+ }
- if (st->st_serialno != latest)
- {
- /* not very interesting: already superseded */
- DBG(DBG_LIFECYCLE
- , plog("%s SA expired (superseded by #%lu)"
- , satype, latest));
- }
- else
- {
- plog("%s SA expired (%s)", satype
- , (c->policy & POLICY_DONT_REKEY)
- ? "--dontrekey"
- : "LATEST!"
- );
- }
- }
- /* FALLTHROUGH */
- case EVENT_SO_DISCARD:
- /* Delete this state object. It must be in the hash table. */
- delete_state(st);
- break;
-
- case EVENT_DPD:
- dpd_outI(st);
- break;
- case EVENT_DPD_TIMEOUT:
- dpd_timeout(st);
- break;
- case EVENT_NAT_T_KEEPALIVE:
- nat_traversal_ka_event();
- break;
- default:
- loglog(RC_LOG_SERIOUS, "INTERNAL ERROR: ignoring unknown expiring event %s"
- , enum_show(&timer_event_names, type));
- }
-
- pfree(ev);
- reset_cur_state();
+ free(ev);
+ reset_cur_state();
}
-/*
+/**
* Return the time until the next event in the queue
* expires (never negative), or -1 if no jobs in queue.
*/
-long
-next_event(void)
+long next_event(void)
{
- time_t tm;
+ time_t tm;
+
+ if (evlist == (struct event *) NULL)
+ return -1;
- if (evlist == (struct event *) NULL)
- return -1;
+ tm = now();
- tm = now();
+ DBG(DBG_CONTROL,
+ if (evlist->ev_state == NULL)
+ DBG_log("next event %N in %ld seconds"
+ , timer_event_names, evlist->ev_type
+ , (long)evlist->ev_time - (long)tm);
+ else
+ DBG_log("next event %N in %ld seconds for #%lu"
+ , timer_event_names, evlist->ev_type
+ , (long)evlist->ev_time - (long)tm
+ , evlist->ev_state->st_serialno));
- DBG(DBG_CONTROL,
- if (evlist->ev_state == NULL)
- DBG_log("next event %s in %ld seconds"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long)evlist->ev_time - (long)tm);
+ if (evlist->ev_time - tm <= 0)
+ return 0;
else
- DBG_log("next event %s in %ld seconds for #%lu"
- , enum_show(&timer_event_names, evlist->ev_type)
- , (long)evlist->ev_time - (long)tm
- , evlist->ev_state->st_serialno));
-
- if (evlist->ev_time - tm <= 0)
- return 0;
- else
- return evlist->ev_time - tm;
+ return evlist->ev_time - tm;
}
-/*
+/**
* Delete an event.
*/
-void
-delete_event(struct state *st)
+void delete_event(struct state *st)
{
- if (st->st_event != (struct event *) NULL)
- {
- struct event **ev;
-
- for (ev = &evlist; ; ev = &(*ev)->ev_next)
+ if (st->st_event != (struct event *) NULL)
{
- if (*ev == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
- enum_show(&timer_event_names, st->st_event->ev_type)));
- break;
- }
- if ((*ev) == st->st_event)
- {
- *ev = (*ev)->ev_next;
-
- if (st->st_event->ev_type == EVENT_RETRANSMIT)
- st->st_retransmit = 0;
- pfree(st->st_event);
- st->st_event = (struct event *) NULL;
-
- break;
- }
+ struct event **ev;
+
+ for (ev = &evlist; ; ev = &(*ev)->ev_next)
+ {
+ if (*ev == NULL)
+ {
+ DBG(DBG_CONTROL, DBG_log("event %N to be deleted not found",
+ timer_event_names, st->st_event->ev_type));
+ break;
+ }
+ if ((*ev) == st->st_event)
+ {
+ *ev = (*ev)->ev_next;
+
+ if (st->st_event->ev_type == EVENT_RETRANSMIT)
+ {
+ st->st_retransmit = 0;
+ }
+ free(st->st_event);
+ st->st_event = (struct event *) NULL;
+
+ break;
+ }
+ }
}
- }
}
-/*
+/**
* Delete a DPD event.
*/
-void
-delete_dpd_event(struct state *st)
+void delete_dpd_event(struct state *st)
{
- if (st->st_dpd_event != (struct event *) NULL)
- {
- struct event **ev;
-
- for (ev = &evlist; ; ev = &(*ev)->ev_next)
- {
- if (*ev == NULL)
- {
- DBG(DBG_CONTROL, DBG_log("event %s to be deleted not found",
- enum_show(&timer_event_names, st->st_dpd_event->ev_type)));
- break;
- }
- if ((*ev) == st->st_dpd_event)
- {
- *ev = (*ev)->ev_next;
- pfree(st->st_dpd_event);
- st->st_dpd_event = (struct event *) NULL;
- break;
- }
- }
- }
+ if (st->st_dpd_event != (struct event *) NULL)
+ {
+ struct event **ev;
+
+ for (ev = &evlist; ; ev = &(*ev)->ev_next)
+ {
+ if (*ev == NULL)
+ {
+ DBG(DBG_CONTROL, DBG_log("event %N to be deleted not found",
+ timer_event_names, st->st_dpd_event->ev_type));
+ break;
+ }
+ if ((*ev) == st->st_dpd_event)
+ {
+ *ev = (*ev)->ev_next;
+ free(st->st_dpd_event);
+ st->st_dpd_event = (struct event *) NULL;
+ break;
+ }
+ }
+ }
}
+/**
+ * Free remaining events
+ */
+void free_events(void)
+{
+ struct event *ev_tmp, *ev;
+
+ ev = evlist;
+ evlist = NULL;
+
+ while (ev)
+ {
+ ev_tmp = ev;
+ ev = ev->ev_next;
+ free(ev_tmp);
+ }
+}
diff --git a/src/pluto/timer.h b/src/pluto/timer.h
index c772d37f9..322aeba6a 100644
--- a/src/pluto/timer.h
+++ b/src/pluto/timer.h
@@ -10,20 +10,18 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: timer.h 3252 2007-10-06 21:24:50Z andreas $
*/
-extern time_t now(void); /* careful version of time(2) */
+extern time_t now(void); /* careful version of time(2) */
-struct state; /* forward declaration */
+struct state; /* forward declaration */
struct event
{
- time_t ev_time;
- int ev_type; /* Event type */
- struct state *ev_state; /* Pointer to relevant state (if any) */
- struct event *ev_next; /* Pointer to next event */
+ time_t ev_time;
+ int ev_type; /* Event type */
+ struct state *ev_state; /* Pointer to relevant state (if any) */
+ struct event *ev_next; /* Pointer to next event */
};
extern void event_schedule(enum event_type type, time_t tm, struct state *st);
@@ -32,3 +30,5 @@ extern long next_event(void);
extern void delete_event(struct state *st);
extern void delete_dpd_event(struct state *st);
extern void daily_log_event(void);
+extern void free_events(void);
+extern void init_secret(void);
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index f957bf39b..ff145eb38 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -1,5 +1,6 @@
/* ISAKMP VendorID
* Copyright (C) 2002-2005 Mathieu Lafon - Arkoon Network Security
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -10,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: vendor.c 5052 2009-03-30 03:47:14Z andreas $
*/
#include <stdlib.h>
@@ -20,10 +19,12 @@
#include <sys/queue.h>
#include <freeswan.h>
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "md5.h"
#include "connections.h"
#include "packet.h"
#include "demux.h"
@@ -88,232 +89,226 @@
#define VID_SUBSTRING (VID_SUBSTRING_DUMPHEXA | VID_SUBSTRING_DUMPASCII | VID_SUBSTRING_MATCH)
struct vid_struct {
- enum known_vendorid id;
- unsigned short flags;
- const char *data;
- const char *descr;
- const char *vid;
- u_int vid_len;
+ enum known_vendorid id;
+ unsigned short flags;
+ const char *data;
+ const char *descr;
+ chunk_t vid;
};
#define DEC_MD5_VID_D(id,str,descr) \
- { VID_##id, VID_MD5HASH, str, descr, NULL, 0 },
+ { VID_##id, VID_MD5HASH, str, descr, { NULL, 0 } },
#define DEC_MD5_VID(id,str) \
- { VID_##id, VID_MD5HASH, str, NULL, NULL, 0 },
-#define DEC_FSWAN_VID(id,str,descr) \
- { VID_##id, VID_FSWAN_HASH, str, descr, NULL, 0 },
+ { VID_##id, VID_MD5HASH, str, NULL, { NULL, 0 } },
static struct vid_struct _vid_tab[] = {
- /* Implementation names */
-
- { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", NULL, 0 },
-
- DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
-
- { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
- "MS NT5 ISAKMPOAKLEY", NULL, NULL, 0 },
-
- DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
- DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
- DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
- DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
- DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
- DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
-
- /* These ones come from SSH vendors.txt */
- DEC_MD5_VID(SSH_IPSEC_1_1_0,
- "Ssh Communications Security IPSEC Express version 1.1.0")
- DEC_MD5_VID(SSH_IPSEC_1_1_1,
- "Ssh Communications Security IPSEC Express version 1.1.1")
- DEC_MD5_VID(SSH_IPSEC_1_1_2,
- "Ssh Communications Security IPSEC Express version 1.1.2")
- DEC_MD5_VID(SSH_IPSEC_1_2_1,
- "Ssh Communications Security IPSEC Express version 1.2.1")
- DEC_MD5_VID(SSH_IPSEC_1_2_2,
- "Ssh Communications Security IPSEC Express version 1.2.2")
- DEC_MD5_VID(SSH_IPSEC_2_0_0,
- "SSH Communications Security IPSEC Express version 2.0.0")
- DEC_MD5_VID(SSH_IPSEC_2_1_0,
- "SSH Communications Security IPSEC Express version 2.1.0")
- DEC_MD5_VID(SSH_IPSEC_2_1_1,
- "SSH Communications Security IPSEC Express version 2.1.1")
- DEC_MD5_VID(SSH_IPSEC_2_1_2,
- "SSH Communications Security IPSEC Express version 2.1.2")
- DEC_MD5_VID(SSH_IPSEC_3_0_0,
- "SSH Communications Security IPSEC Express version 3.0.0")
- DEC_MD5_VID(SSH_IPSEC_3_0_1,
- "SSH Communications Security IPSEC Express version 3.0.1")
- DEC_MD5_VID(SSH_IPSEC_4_0_0,
- "SSH Communications Security IPSEC Express version 4.0.0")
- DEC_MD5_VID(SSH_IPSEC_4_0_1,
- "SSH Communications Security IPSEC Express version 4.0.1")
- DEC_MD5_VID(SSH_IPSEC_4_1_0,
- "SSH Communications Security IPSEC Express version 4.1.0")
- DEC_MD5_VID(SSH_IPSEC_4_2_0,
- "SSH Communications Security IPSEC Express version 4.2.0")
-
- /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
- { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
- "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00",
- 16 },
-
- { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH,
- NULL, "Cisco VPN 3000 Series" , "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14},
-
- { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
- NULL, "Cisco IOS Device", "\x3e\x98\x40\x48", 4},
-
- /*
- * Timestep VID seen:
- * - 54494d455354455020312053475720313532302033313520322e303145303133
- * = 'TIMESTEP 1 SGW 1520 315 2.01E013'
- */
- { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
- NULL, NULL, 0 },
-
- /*
- * Netscreen:
- * 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
- */
- { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
- "HeartBeat_Notify", "HeartBeat Notify", NULL, 0 },
-
- /*
- * MacOS X
- */
- { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
- "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", NULL, 0},
-
- /*
- * Openswan
- */
- DEC_FSWAN_VID(OPENSWAN2, "Openswan 2.2.0", "Openswan 2.2.0")
-
- /* NCP */
- { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
- "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12},
- { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
- "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12},
-
- /*
- * Windows Vista (and Windows Server 2008?)
- */
- DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
- DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
- DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
-
- /*
- * strongSwan
- */
- DEC_MD5_VID(STRONGSWAN, "strongSwan 4.2.14")
- DEC_MD5_VID(STRONGSWAN_4_2_13,"strongSwan 4.2.13")
- DEC_MD5_VID(STRONGSWAN_4_2_12,"strongSwan 4.2.12")
- DEC_MD5_VID(STRONGSWAN_4_2_11,"strongSwan 4.2.11")
- DEC_MD5_VID(STRONGSWAN_4_2_10,"strongSwan 4.2.10")
- DEC_MD5_VID(STRONGSWAN_4_2_9, "strongSwan 4.2.9")
- DEC_MD5_VID(STRONGSWAN_4_2_8, "strongSwan 4.2.8")
- DEC_MD5_VID(STRONGSWAN_4_2_7, "strongSwan 4.2.7")
- DEC_MD5_VID(STRONGSWAN_4_2_6, "strongSwan 4.2.6")
- DEC_MD5_VID(STRONGSWAN_4_2_5, "strongSwan 4.2.5")
- DEC_MD5_VID(STRONGSWAN_4_2_4, "strongSwan 4.2.4")
- DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3")
- DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2")
- DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1")
- DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0")
- DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11")
- DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10")
- DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
- DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
- DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7")
- DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6")
- DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5")
- DEC_MD5_VID(STRONGSWAN_4_1_4, "strongSwan 4.1.4")
- DEC_MD5_VID(STRONGSWAN_4_1_3, "strongSwan 4.1.3")
- DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2")
- DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1")
- DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0")
- DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7")
- DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
- DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
- DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
- DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
- DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
- DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
- DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
-
- DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.9")
- DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.8")
- DEC_MD5_VID(STRONGSWAN_2_8_7, "strongSwan 2.8.7")
- DEC_MD5_VID(STRONGSWAN_2_8_6, "strongSwan 2.8.6")
- DEC_MD5_VID(STRONGSWAN_2_8_5, "strongSwan 2.8.5")
- DEC_MD5_VID(STRONGSWAN_2_8_4, "strongSwan 2.8.4")
- DEC_MD5_VID(STRONGSWAN_2_8_3, "strongSwan 2.8.3")
- DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
- DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
- DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
- DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
- DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
- DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
- DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
- DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
- DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
- DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")
- DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1")
- DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0")
- DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7")
- DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6")
- DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5")
- DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4")
- DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3")
- DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2")
- DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1")
- DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0")
- DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4")
- DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3")
- DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2")
- DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1")
- DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0")
- DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2")
- DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1")
- DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0")
- DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2")
- DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1")
- DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0")
-
- /* NAT-Traversal */
-
- DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
- DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
- DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
- DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
- DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
- DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
- /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
- DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
- DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
- DEC_MD5_VID(NATT_RFC, "RFC 3947")
-
- /* misc */
-
- { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
- "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 },
-
- { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
- "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 },
-
- DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
-
- DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
-
- /**
- * Cisco VPN 3000
- */
- { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
- "FRAGMENTATION", NULL, NULL, 0 },
-
- /* -- */
- { 0, 0, NULL, NULL, NULL, 0 }
+ /* Implementation names */
+
+ { VID_OPENPGP, VID_STRING, "OpenPGP10171", "OpenPGP", { NULL, 0 } },
+
+ DEC_MD5_VID(KAME_RACOON, "KAME/racoon")
+
+ { VID_MS_NT5, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
+ "MS NT5 ISAKMPOAKLEY", NULL, { NULL, 0 } },
+
+ DEC_MD5_VID(SSH_SENTINEL, "SSH Sentinel")
+ DEC_MD5_VID(SSH_SENTINEL_1_1, "SSH Sentinel 1.1")
+ DEC_MD5_VID(SSH_SENTINEL_1_2, "SSH Sentinel 1.2")
+ DEC_MD5_VID(SSH_SENTINEL_1_3, "SSH Sentinel 1.3")
+ DEC_MD5_VID(SSH_SENTINEL_1_4, "SSH Sentinel 1.4")
+ DEC_MD5_VID(SSH_SENTINEL_1_4_1, "SSH Sentinel 1.4.1")
+
+ /* These ones come from SSH vendors.txt */
+ DEC_MD5_VID(SSH_IPSEC_1_1_0,
+ "Ssh Communications Security IPSEC Express version 1.1.0")
+ DEC_MD5_VID(SSH_IPSEC_1_1_1,
+ "Ssh Communications Security IPSEC Express version 1.1.1")
+ DEC_MD5_VID(SSH_IPSEC_1_1_2,
+ "Ssh Communications Security IPSEC Express version 1.1.2")
+ DEC_MD5_VID(SSH_IPSEC_1_2_1,
+ "Ssh Communications Security IPSEC Express version 1.2.1")
+ DEC_MD5_VID(SSH_IPSEC_1_2_2,
+ "Ssh Communications Security IPSEC Express version 1.2.2")
+ DEC_MD5_VID(SSH_IPSEC_2_0_0,
+ "SSH Communications Security IPSEC Express version 2.0.0")
+ DEC_MD5_VID(SSH_IPSEC_2_1_0,
+ "SSH Communications Security IPSEC Express version 2.1.0")
+ DEC_MD5_VID(SSH_IPSEC_2_1_1,
+ "SSH Communications Security IPSEC Express version 2.1.1")
+ DEC_MD5_VID(SSH_IPSEC_2_1_2,
+ "SSH Communications Security IPSEC Express version 2.1.2")
+ DEC_MD5_VID(SSH_IPSEC_3_0_0,
+ "SSH Communications Security IPSEC Express version 3.0.0")
+ DEC_MD5_VID(SSH_IPSEC_3_0_1,
+ "SSH Communications Security IPSEC Express version 3.0.1")
+ DEC_MD5_VID(SSH_IPSEC_4_0_0,
+ "SSH Communications Security IPSEC Express version 4.0.0")
+ DEC_MD5_VID(SSH_IPSEC_4_0_1,
+ "SSH Communications Security IPSEC Express version 4.0.1")
+ DEC_MD5_VID(SSH_IPSEC_4_1_0,
+ "SSH Communications Security IPSEC Express version 4.1.0")
+ DEC_MD5_VID(SSH_IPSEC_4_2_0,
+ "SSH Communications Security IPSEC Express version 4.2.0")
+
+ /* note: md5('CISCO-UNITY') = 12f5f28c457168a9702d9fe274cc02d4 */
+ { VID_CISCO_UNITY, VID_KEEP, NULL, "Cisco-Unity",
+ { "\x12\xf5\xf2\x8c\x45\x71\x68\xa9\x70\x2d\x9f\xe2\x74\xcc\x01\x00", 16 } },
+
+ { VID_CISCO3K, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "Cisco VPN 3000 Series" ,
+ { "\x1f\x07\xf7\x0e\xaa\x65\x14\xd3\xb0\xfa\x96\x54\x2a\x50", 14 } },
+
+ { VID_CISCO_IOS, VID_KEEP | VID_SUBSTRING_MATCH,
+ NULL, "Cisco IOS Device", { "\x3e\x98\x40\x48", 4 } },
+
+ /*
+ * Timestep VID seen:
+ * - 54494d455354455020312053475720313532302033313520322e303145303133
+ * = 'TIMESTEP 1 SGW 1520 315 2.01E013'
+ */
+ { VID_TIMESTEP, VID_STRING | VID_SUBSTRING_DUMPASCII, "TIMESTEP",
+ NULL, { NULL, 0 } },
+
+ /*
+ * Netscreen:
+ * 4865617274426561745f4e6f74696679386b0100 (HeartBeat_Notify + 386b0100)
+ */
+ { VID_MISC_HEARTBEAT_NOTIFY, VID_STRING | VID_SUBSTRING_DUMPHEXA,
+ "HeartBeat_Notify", "HeartBeat Notify", { NULL, 0 } },
+ /*
+ * MacOS X
+ */
+ { VID_MACOSX, VID_STRING|VID_SUBSTRING_DUMPHEXA, "Mac OSX 10.x",
+ "\x4d\xf3\x79\x28\xe9\xfc\x4f\xd1\xb3\x26\x21\x70\xd5\x15\xc6\x62", { NULL, 0 } },
+
+ /* NCP */
+ { VID_NCP_SERVER, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Server",
+ { "\xc6\xf5\x7a\xc3\x98\xf4\x93\x20\x81\x45\xb7\x58", 12 } },
+ { VID_NCP_CLIENT, VID_KEEP | VID_SUBSTRING_MATCH, NULL, "NCP Client",
+ { "\xeb\x4c\x1b\x78\x8a\xfd\x4a\x9c\xb7\x73\x0a\x68", 12 } },
+
+ /*
+ * Windows Vista (and Windows Server 2008?)
+ */
+ DEC_MD5_VID(VISTA_AUTHIP, "MS-Negotiation Discovery Capable")
+ DEC_MD5_VID(VISTA_AUTHIP2, "IKE CGA version 1")
+ DEC_MD5_VID(VISTA_AUTHIP3, "MS-MamieExists")
+
+ /*
+ * strongSwan
+ */
+ DEC_MD5_VID(STRONGSWAN, "strongSwan 4.3.2")
+ DEC_MD5_VID(STRONGSWAN_4_3_1, "strongSwan 4.3.1")
+ DEC_MD5_VID(STRONGSWAN_4_3_0, "strongSwan 4.3.0")
+ DEC_MD5_VID(STRONGSWAN_4_2_15,"strongSwan 4.2.15")
+ DEC_MD5_VID(STRONGSWAN_4_2_14,"strongSwan 4.2.14")
+ DEC_MD5_VID(STRONGSWAN_4_2_13,"strongSwan 4.2.13")
+ DEC_MD5_VID(STRONGSWAN_4_2_12,"strongSwan 4.2.12")
+ DEC_MD5_VID(STRONGSWAN_4_2_11,"strongSwan 4.2.11")
+ DEC_MD5_VID(STRONGSWAN_4_2_10,"strongSwan 4.2.10")
+ DEC_MD5_VID(STRONGSWAN_4_2_9, "strongSwan 4.2.9")
+ DEC_MD5_VID(STRONGSWAN_4_2_8, "strongSwan 4.2.8")
+ DEC_MD5_VID(STRONGSWAN_4_2_7, "strongSwan 4.2.7")
+ DEC_MD5_VID(STRONGSWAN_4_2_6, "strongSwan 4.2.6")
+ DEC_MD5_VID(STRONGSWAN_4_2_5, "strongSwan 4.2.5")
+ DEC_MD5_VID(STRONGSWAN_4_2_4, "strongSwan 4.2.4")
+ DEC_MD5_VID(STRONGSWAN_4_2_3, "strongSwan 4.2.3")
+ DEC_MD5_VID(STRONGSWAN_4_2_2, "strongSwan 4.2.2")
+ DEC_MD5_VID(STRONGSWAN_4_2_1, "strongSwan 4.2.1")
+ DEC_MD5_VID(STRONGSWAN_4_2_0, "strongSwan 4.2.0")
+ DEC_MD5_VID(STRONGSWAN_4_1_11,"strongSwan 4.1.11")
+ DEC_MD5_VID(STRONGSWAN_4_1_10,"strongSwan 4.1.10")
+ DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
+ DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
+ DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7")
+ DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6")
+ DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5")
+ DEC_MD5_VID(STRONGSWAN_4_1_4, "strongSwan 4.1.4")
+ DEC_MD5_VID(STRONGSWAN_4_1_3, "strongSwan 4.1.3")
+ DEC_MD5_VID(STRONGSWAN_4_1_2, "strongSwan 4.1.2")
+ DEC_MD5_VID(STRONGSWAN_4_1_1, "strongSwan 4.1.1")
+ DEC_MD5_VID(STRONGSWAN_4_1_0, "strongSwan 4.1.0")
+ DEC_MD5_VID(STRONGSWAN_4_0_7, "strongSwan 4.0.7")
+ DEC_MD5_VID(STRONGSWAN_4_0_6, "strongSwan 4.0.6")
+ DEC_MD5_VID(STRONGSWAN_4_0_5, "strongSwan 4.0.5")
+ DEC_MD5_VID(STRONGSWAN_4_0_4, "strongSwan 4.0.4")
+ DEC_MD5_VID(STRONGSWAN_4_0_3, "strongSwan 4.0.3")
+ DEC_MD5_VID(STRONGSWAN_4_0_2, "strongSwan 4.0.2")
+ DEC_MD5_VID(STRONGSWAN_4_0_1, "strongSwan 4.0.1")
+ DEC_MD5_VID(STRONGSWAN_4_0_0, "strongSwan 4.0.0")
+
+ DEC_MD5_VID(STRONGSWAN_2_8_9, "strongSwan 2.8.9")
+ DEC_MD5_VID(STRONGSWAN_2_8_8, "strongSwan 2.8.8")
+ DEC_MD5_VID(STRONGSWAN_2_8_7, "strongSwan 2.8.7")
+ DEC_MD5_VID(STRONGSWAN_2_8_6, "strongSwan 2.8.6")
+ DEC_MD5_VID(STRONGSWAN_2_8_5, "strongSwan 2.8.5")
+ DEC_MD5_VID(STRONGSWAN_2_8_4, "strongSwan 2.8.4")
+ DEC_MD5_VID(STRONGSWAN_2_8_3, "strongSwan 2.8.3")
+ DEC_MD5_VID(STRONGSWAN_2_8_2, "strongSwan 2.8.2")
+ DEC_MD5_VID(STRONGSWAN_2_8_1, "strongSwan 2.8.1")
+ DEC_MD5_VID(STRONGSWAN_2_8_0, "strongSwan 2.8.0")
+ DEC_MD5_VID(STRONGSWAN_2_7_3, "strongSwan 2.7.3")
+ DEC_MD5_VID(STRONGSWAN_2_7_2, "strongSwan 2.7.2")
+ DEC_MD5_VID(STRONGSWAN_2_7_1, "strongSwan 2.7.1")
+ DEC_MD5_VID(STRONGSWAN_2_7_0, "strongSwan 2.7.0")
+ DEC_MD5_VID(STRONGSWAN_2_6_4, "strongSwan 2.6.4")
+ DEC_MD5_VID(STRONGSWAN_2_6_3, "strongSwan 2.6.3")
+ DEC_MD5_VID(STRONGSWAN_2_6_2, "strongSwan 2.6.2")
+ DEC_MD5_VID(STRONGSWAN_2_6_1, "strongSwan 2.6.1")
+ DEC_MD5_VID(STRONGSWAN_2_6_0, "strongSwan 2.6.0")
+ DEC_MD5_VID(STRONGSWAN_2_5_7, "strongSwan 2.5.7")
+ DEC_MD5_VID(STRONGSWAN_2_5_6, "strongSwan 2.5.6")
+ DEC_MD5_VID(STRONGSWAN_2_5_5, "strongSwan 2.5.5")
+ DEC_MD5_VID(STRONGSWAN_2_5_4, "strongSwan 2.5.4")
+ DEC_MD5_VID(STRONGSWAN_2_5_3, "strongSwan 2.5.3")
+ DEC_MD5_VID(STRONGSWAN_2_5_2, "strongSwan 2.5.2")
+ DEC_MD5_VID(STRONGSWAN_2_5_1, "strongSwan 2.5.1")
+ DEC_MD5_VID(STRONGSWAN_2_5_0, "strongSwan 2.5.0")
+ DEC_MD5_VID(STRONGSWAN_2_4_4, "strongSwan 2.4.4")
+ DEC_MD5_VID(STRONGSWAN_2_4_3, "strongSwan 2.4.3")
+ DEC_MD5_VID(STRONGSWAN_2_4_2, "strongSwan 2.4.2")
+ DEC_MD5_VID(STRONGSWAN_2_4_1, "strongSwan 2.4.1")
+ DEC_MD5_VID(STRONGSWAN_2_4_0, "strongSwan 2.4.0")
+ DEC_MD5_VID(STRONGSWAN_2_3_2, "strongSwan 2.3.2")
+ DEC_MD5_VID(STRONGSWAN_2_3_1, "strongSwan 2.3.1")
+ DEC_MD5_VID(STRONGSWAN_2_3_0, "strongSwan 2.3.0")
+ DEC_MD5_VID(STRONGSWAN_2_2_2, "strongSwan 2.2.2")
+ DEC_MD5_VID(STRONGSWAN_2_2_1, "strongSwan 2.2.1")
+ DEC_MD5_VID(STRONGSWAN_2_2_0, "strongSwan 2.2.0")
+
+ /* NAT-Traversal */
+
+ DEC_MD5_VID(NATT_STENBERG_01, "draft-stenberg-ipsec-nat-traversal-01")
+ DEC_MD5_VID(NATT_STENBERG_02, "draft-stenberg-ipsec-nat-traversal-02")
+ DEC_MD5_VID(NATT_HUTTUNEN, "ESPThruNAT")
+ DEC_MD5_VID(NATT_HUTTUNEN_ESPINUDP, "draft-huttunen-ipsec-esp-in-udp-00.txt")
+ DEC_MD5_VID(NATT_IETF_00, "draft-ietf-ipsec-nat-t-ike-00")
+ DEC_MD5_VID(NATT_IETF_02, "draft-ietf-ipsec-nat-t-ike-02")
+ /* hash in draft-ietf-ipsec-nat-t-ike-02 contains '\n'... Accept both */
+ DEC_MD5_VID_D(NATT_IETF_02_N, "draft-ietf-ipsec-nat-t-ike-02\n", "draft-ietf-ipsec-nat-t-ike-02_n")
+ DEC_MD5_VID(NATT_IETF_03, "draft-ietf-ipsec-nat-t-ike-03")
+ DEC_MD5_VID(NATT_RFC, "RFC 3947")
+
+ /* misc */
+
+ { VID_MISC_XAUTH, VID_KEEP, NULL, "XAUTH",
+ { "\x09\x00\x26\x89\xdf\xd6\xb7\x12", 8 } },
+
+ { VID_MISC_DPD, VID_KEEP, NULL, "Dead Peer Detection",
+ { "\xaf\xca\xd7\x13\x68\xa1\xf1\xc9\x6b\x86\x96\xfc\x77\x57\x01\x00", 16 } },
+
+ DEC_MD5_VID(MISC_FRAGMENTATION, "FRAGMENTATION")
+
+ DEC_MD5_VID(INITIAL_CONTACT, "Vid-Initial-Contact")
+
+ /**
+ * Cisco VPN 3000
+ */
+ { VID_MISC_FRAGMENTATION, VID_MD5HASH | VID_SUBSTRING_DUMPHEXA,
+ "FRAGMENTATION", NULL, { NULL, 0 } },
+
+ /* -- */
+ { 0, 0, NULL, NULL, { NULL, 0 } }
};
@@ -321,239 +316,211 @@ static const char _hexdig[] = "0123456789abcdef";
static int _vid_struct_init = 0;
-void
-init_vendorid(void)
+void init_vendorid(void)
{
- struct vid_struct *vid;
- MD5_CTX ctx;
- int i;
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ struct vid_struct *vid;
- for (vid = _vid_tab; vid->id; vid++)
- {
- if (vid->flags & VID_STRING)
- {
- /** VendorID is a string **/
- vid->vid = strdup(vid->data);
- vid->vid_len = strlen(vid->data);
- }
- else if (vid->flags & VID_MD5HASH)
+ for (vid = _vid_tab; vid->id; vid++)
{
- /** VendorID is a string to hash with MD5 **/
- char *vidm = malloc(MD5_DIGEST_SIZE);
-
- vid->vid = vidm;
- if (vidm)
- {
- MD5Init(&ctx);
- MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
- MD5Final(vidm, &ctx);
- vid->vid_len = MD5_DIGEST_SIZE;
- }
- }
- else if (vid->flags & VID_FSWAN_HASH)
- {
- /** FreeS/WAN 2.00+ specific hash **/
-#define FSWAN_VID_SIZE 12
- unsigned char hash[MD5_DIGEST_SIZE];
- char *vidm = malloc(FSWAN_VID_SIZE);
-
- vid->vid = vidm;
- if (vidm)
- {
- MD5Init(&ctx);
- MD5Update(&ctx, (const u_char *)vid->data, strlen(vid->data));
- MD5Final(hash, &ctx);
- vidm[0] = 'O';
- vidm[1] = 'E';
-#if FSWAN_VID_SIZE - 2 <= MD5_DIGEST_SIZE
- memcpy(vidm + 2, hash, FSWAN_VID_SIZE - 2);
-#else
- memcpy(vidm + 2, hash, MD5_DIGEST_SIZE);
- memset(vidm + 2 + MD5_DIGEST_SIZE, '\0',
- FSWAN_VID_SIZE - 2 - MD5_DIGEST_SIZE);
-#endif
- for (i = 2; i < FSWAN_VID_SIZE; i++)
+ if (vid->flags & VID_STRING)
+ {
+ /** VendorID is a string **/
+ vid->vid = chunk_create((u_char *)vid->data, strlen(vid->data));
+ vid->vid = chunk_clone(vid->vid);
+ }
+ else if (vid->flags & VID_MD5HASH)
+ {
+ chunk_t vid_data = { (u_char *)vid->data, strlen(vid->data) };
+
+ /** VendorID is a string to hash with MD5 **/
+ hasher->allocate_hash(hasher, vid_data, &vid->vid);
+ }
+
+ if (vid->descr == NULL)
{
- vidm[i] &= 0x7f;
- vidm[i] |= 0x40;
+ /** Find something to display **/
+ vid->descr = vid->data;
}
- vid->vid_len = FSWAN_VID_SIZE;
- }
}
+ hasher->destroy(hasher);
+ _vid_struct_init = 1;
+}
+
+void free_vendorid(void)
+{
+ struct vid_struct *vid;
- if (vid->descr == NULL)
+ for (vid = _vid_tab; vid->id; vid++)
{
- /** Find something to display **/
- vid->descr = vid->data;
+ if (vid->flags & (VID_STRING | VID_MD5HASH | VID_FSWAN_HASH))
+ {
+ free(vid->vid.ptr);
+ }
}
- }
- _vid_struct_init = 1;
}
-static void
-handle_known_vendorid (struct msg_digest *md
-, const char *vidstr, size_t len, struct vid_struct *vid)
+static void handle_known_vendorid (struct msg_digest *md, const char *vidstr,
+ size_t len, struct vid_struct *vid)
{
- char vid_dump[128];
- bool vid_useful = FALSE;
- size_t i, j;
-
- switch (vid->id) {
- /* Remote side supports OpenPGP certificates */
- case VID_OPENPGP:
- md->openpgp = TRUE;
- vid_useful = TRUE;
- break;
-
- /*
- * Use most recent supported NAT-Traversal method and ignore the
- * other ones (implementations will send all supported methods but
- * only one will be used)
- *
- * Note: most recent == higher id in vendor.h
- */
- case VID_NATT_IETF_00:
- if (!nat_traversal_support_non_ike)
- break;
- if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
- {
- md->nat_traversal_vid = vid->id;
- vid_useful = TRUE;
+ char vid_dump[128];
+ bool vid_useful = FALSE;
+ size_t i, j;
+
+ switch (vid->id) {
+ /* Remote side supports OpenPGP certificates */
+ case VID_OPENPGP:
+ md->openpgp = TRUE;
+ vid_useful = TRUE;
+ break;
+
+ /*
+ * Use most recent supported NAT-Traversal method and ignore the
+ * other ones (implementations will send all supported methods but
+ * only one will be used)
+ *
+ * Note: most recent == higher id in vendor.h
+ */
+ case VID_NATT_IETF_00:
+ if (!nat_traversal_support_non_ike)
+ break;
+ if ((nat_traversal_enabled) && (!md->nat_traversal_vid))
+ {
+ md->nat_traversal_vid = vid->id;
+ vid_useful = TRUE;
+ }
+ break;
+ case VID_NATT_IETF_02:
+ case VID_NATT_IETF_02_N:
+ case VID_NATT_IETF_03:
+ case VID_NATT_RFC:
+ if (nat_traversal_support_port_floating
+ && md->nat_traversal_vid < vid->id)
+ {
+ md->nat_traversal_vid = vid->id;
+ vid_useful = TRUE;
+ }
+ break;
+
+ /* Remote side would like to do DPD with us on this connection */
+ case VID_MISC_DPD:
+ md->dpd = TRUE;
+ vid_useful = TRUE;
+ break;
+ case VID_MISC_XAUTH:
+ vid_useful = TRUE;
+ break;
+ default:
+ break;
}
- break;
- case VID_NATT_IETF_02:
- case VID_NATT_IETF_02_N:
- case VID_NATT_IETF_03:
- case VID_NATT_RFC:
- if (nat_traversal_support_port_floating
- && md->nat_traversal_vid < vid->id)
+
+ if (vid->flags & VID_SUBSTRING_DUMPHEXA)
{
- md->nat_traversal_vid = vid->id;
- vid_useful = TRUE;
+ /* Dump description + Hexa */
+ memset(vid_dump, 0, sizeof(vid_dump));
+ snprintf(vid_dump, sizeof(vid_dump), "%s ",
+ vid->descr ? vid->descr : "");
+ for (i = strlen(vid_dump), j = vid->vid.len;
+ j < len && i < sizeof(vid_dump) - 2;
+ i += 2, j++)
+ {
+ vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
+ vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
+ }
}
- break;
-
- /* Remote side would like to do DPD with us on this connection */
- case VID_MISC_DPD:
- md->dpd = TRUE;
- vid_useful = TRUE;
- break;
- case VID_MISC_XAUTH:
- vid_useful = TRUE;
- break;
- default:
- break;
- }
-
- if (vid->flags & VID_SUBSTRING_DUMPHEXA)
- {
- /* Dump description + Hexa */
- memset(vid_dump, 0, sizeof(vid_dump));
- snprintf(vid_dump, sizeof(vid_dump), "%s ",
- vid->descr ? vid->descr : "");
- for (i = strlen(vid_dump), j = vid->vid_len;
- j < len && i < sizeof(vid_dump) - 2;
- i += 2, j++)
+ else if (vid->flags & VID_SUBSTRING_DUMPASCII)
{
- vid_dump[i] = _hexdig[(vidstr[j] >> 4) & 0xF];
- vid_dump[i+1] = _hexdig[vidstr[j] & 0xF];
+ /* Dump ASCII content */
+ memset(vid_dump, 0, sizeof(vid_dump));
+ for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
+ {
+ vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
+ }
}
- }
- else if (vid->flags & VID_SUBSTRING_DUMPASCII)
- {
- /* Dump ASCII content */
- memset(vid_dump, 0, sizeof(vid_dump));
- for (i = 0; i < len && i < sizeof(vid_dump) - 1; i++)
+ else
{
- vid_dump[i] = (isprint(vidstr[i])) ? vidstr[i] : '.';
+ /* Dump description (descr) */
+ snprintf(vid_dump, sizeof(vid_dump), "%s",
+ vid->descr ? vid->descr : "");
}
- }
- else
- {
- /* Dump description (descr) */
- snprintf(vid_dump, sizeof(vid_dump), "%s",
- vid->descr ? vid->descr : "");
- }
-
- loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
- vid_useful ? "received" : "ignoring", vid_dump);
+
+ loglog(RC_LOG_SERIOUS, "%s Vendor ID payload [%s]",
+ vid_useful ? "received" : "ignoring", vid_dump);
}
-void
-handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
+void handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
{
- struct vid_struct *pvid;
+ struct vid_struct *pvid;
- if (!_vid_struct_init)
- init_vendorid();
+ if (!_vid_struct_init)
+ init_vendorid();
- /*
- * Find known VendorID in _vid_tab
- */
- for (pvid = _vid_tab; pvid->id; pvid++)
- {
- if (pvid->vid && vid && pvid->vid_len && len)
+ /*
+ * Find known VendorID in _vid_tab
+ */
+ for (pvid = _vid_tab; pvid->id; pvid++)
{
- if (pvid->vid_len == len)
- {
- if (memcmp(pvid->vid, vid, len) == 0)
+ if (pvid->vid.ptr && vid && pvid->vid.len && len)
{
- handle_known_vendorid(md, vid, len, pvid);
- return;
+ if (pvid->vid.len == len)
+ {
+ if (memeq(pvid->vid.ptr, vid, len))
+ {
+ handle_known_vendorid(md, vid, len, pvid);
+ return;
+ }
+ }
+ else if ((pvid->vid.len < len) && (pvid->flags & VID_SUBSTRING))
+ {
+ if (memeq(pvid->vid.ptr, vid, pvid->vid.len))
+ {
+ handle_known_vendorid(md, vid, len, pvid);
+ return;
+ }
+ }
}
- }
- else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
- {
- if (memcmp(pvid->vid, vid, pvid->vid_len) == 0)
- {
- handle_known_vendorid(md, vid, len, pvid);
- return;
- }
- }
}
- }
- /*
- * Unknown VendorID. Log the beginning.
- */
- {
- char log_vid[2*MAX_LOG_VID_LEN+1];
- size_t i;
+ /*
+ * Unknown VendorID. Log the beginning.
+ */
+ {
+ char log_vid[2*MAX_LOG_VID_LEN+1];
+ size_t i;
- memset(log_vid, 0, sizeof(log_vid));
+ memset(log_vid, 0, sizeof(log_vid));
- for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
- {
- log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
- log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
+ for (i = 0; i < len && i < MAX_LOG_VID_LEN; i++)
+ {
+ log_vid[2*i] = _hexdig[(vid[i] >> 4) & 0xF];
+ log_vid[2*i+1] = _hexdig[vid[i] & 0xF];
+ }
+ loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
+ log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
}
- loglog(RC_LOG_SERIOUS, "ignoring Vendor ID payload [%s%s]",
- log_vid, (len>MAX_LOG_VID_LEN) ? "..." : "");
- }
}
/**
* Add a vendor id payload to the msg
*/
-bool
-out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
+bool out_vendorid (u_int8_t np, pb_stream *outs, enum known_vendorid vid)
{
- struct vid_struct *pvid;
+ struct vid_struct *pvid;
- if (!_vid_struct_init)
- init_vendorid();
+ if (!_vid_struct_init)
+ init_vendorid();
- for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++);
+ for (pvid = _vid_tab; pvid->id && pvid->id != vid; pvid++);
- if (pvid->id != vid)
- return STF_INTERNAL_ERROR; /* not found */
- if (!pvid->vid)
- return STF_INTERNAL_ERROR; /* not initialized */
+ if (pvid->id != vid)
+ return STF_INTERNAL_ERROR; /* not found */
+ if (!pvid->vid.ptr)
+ return STF_INTERNAL_ERROR; /* not initialized */
- DBG(DBG_EMITTING,
- DBG_log("out_vendorid(): sending [%s]", pvid->descr)
- )
- return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
- pvid->vid, pvid->vid_len, "V_ID");
+ DBG(DBG_EMITTING,
+ DBG_log("out_vendorid(): sending [%s]", pvid->descr)
+ )
+ return out_generic_raw(np, &isakmp_vendor_id_desc, outs,
+ pvid->vid.ptr, pvid->vid.len, "V_ID");
}
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
index 2c8c24b34..164c1aa6d 100644
--- a/src/pluto/vendor.h
+++ b/src/pluto/vendor.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: vendor.h 5052 2009-03-30 03:47:14Z andreas $
*/
#ifndef _VENDOR_H_
@@ -19,140 +17,144 @@
enum known_vendorid {
/* 1 - 100 : Implementation names */
- VID_OPENPGP = 1,
- VID_KAME_RACOON = 2,
- VID_MS_NT5 = 3,
- VID_SSH_SENTINEL = 4,
- VID_SSH_SENTINEL_1_1 = 5,
- VID_SSH_SENTINEL_1_2 = 6,
- VID_SSH_SENTINEL_1_3 = 7,
- VID_SSH_SENTINEL_1_4 = 8,
- VID_SSH_SENTINEL_1_4_1 = 9,
- VID_SSH_IPSEC_1_1_0 = 10,
- VID_SSH_IPSEC_1_1_1 = 11,
- VID_SSH_IPSEC_1_1_2 = 12,
- VID_SSH_IPSEC_1_2_1 = 13,
- VID_SSH_IPSEC_1_2_2 = 14,
- VID_SSH_IPSEC_2_0_0 = 15,
- VID_SSH_IPSEC_2_1_0 = 16,
- VID_SSH_IPSEC_2_1_1 = 17,
- VID_SSH_IPSEC_2_1_2 = 18,
- VID_SSH_IPSEC_3_0_0 = 19,
- VID_SSH_IPSEC_3_0_1 = 20,
- VID_SSH_IPSEC_4_0_0 = 21,
- VID_SSH_IPSEC_4_0_1 = 22,
- VID_SSH_IPSEC_4_1_0 = 23,
- VID_SSH_IPSEC_4_2_0 = 24,
- VID_CISCO_UNITY = 25,
- VID_CISCO3K = 26,
- VID_CISCO_IOS = 27,
- VID_TIMESTEP = 28,
- VID_SAFENET = 29,
- VID_MACOSX = 30,
- VID_OPENSWAN2 = 31,
- VID_NCP_SERVER = 32,
- VID_NCP_CLIENT = 33,
- VID_VISTA_AUTHIP = 34,
- VID_VISTA_AUTHIP2 = 35,
- VID_VISTA_AUTHIP3 = 36,
+ VID_OPENPGP = 1,
+ VID_KAME_RACOON = 2,
+ VID_MS_NT5 = 3,
+ VID_SSH_SENTINEL = 4,
+ VID_SSH_SENTINEL_1_1 = 5,
+ VID_SSH_SENTINEL_1_2 = 6,
+ VID_SSH_SENTINEL_1_3 = 7,
+ VID_SSH_SENTINEL_1_4 = 8,
+ VID_SSH_SENTINEL_1_4_1 = 9,
+ VID_SSH_IPSEC_1_1_0 = 10,
+ VID_SSH_IPSEC_1_1_1 = 11,
+ VID_SSH_IPSEC_1_1_2 = 12,
+ VID_SSH_IPSEC_1_2_1 = 13,
+ VID_SSH_IPSEC_1_2_2 = 14,
+ VID_SSH_IPSEC_2_0_0 = 15,
+ VID_SSH_IPSEC_2_1_0 = 16,
+ VID_SSH_IPSEC_2_1_1 = 17,
+ VID_SSH_IPSEC_2_1_2 = 18,
+ VID_SSH_IPSEC_3_0_0 = 19,
+ VID_SSH_IPSEC_3_0_1 = 20,
+ VID_SSH_IPSEC_4_0_0 = 21,
+ VID_SSH_IPSEC_4_0_1 = 22,
+ VID_SSH_IPSEC_4_1_0 = 23,
+ VID_SSH_IPSEC_4_2_0 = 24,
+ VID_CISCO_UNITY = 25,
+ VID_CISCO3K = 26,
+ VID_CISCO_IOS = 27,
+ VID_TIMESTEP = 28,
+ VID_SAFENET = 29,
+ VID_MACOSX = 30,
+ VID_NCP_SERVER = 31,
+ VID_NCP_CLIENT = 32,
+ VID_VISTA_AUTHIP = 33,
+ VID_VISTA_AUTHIP2 = 34,
+ VID_VISTA_AUTHIP3 = 35,
- VID_STRONGSWAN = 37,
- VID_STRONGSWAN_2_2_0 = 38,
- VID_STRONGSWAN_2_2_1 = 39,
- VID_STRONGSWAN_2_2_2 = 40,
- VID_STRONGSWAN_2_3_0 = 41,
- VID_STRONGSWAN_2_3_1 = 42,
- VID_STRONGSWAN_2_3_2 = 43,
- VID_STRONGSWAN_2_4_0 = 44,
- VID_STRONGSWAN_2_4_1 = 45,
- VID_STRONGSWAN_2_4_2 = 46,
- VID_STRONGSWAN_2_4_3 = 47,
- VID_STRONGSWAN_2_4_4 = 48,
- VID_STRONGSWAN_2_5_0 = 49,
- VID_STRONGSWAN_2_5_1 = 50,
- VID_STRONGSWAN_2_5_2 = 51,
- VID_STRONGSWAN_2_5_3 = 52,
- VID_STRONGSWAN_2_5_4 = 53,
- VID_STRONGSWAN_2_5_5 = 54,
- VID_STRONGSWAN_2_5_6 = 55,
- VID_STRONGSWAN_2_5_7 = 56,
- VID_STRONGSWAN_2_6_0 = 57,
- VID_STRONGSWAN_2_6_1 = 58,
- VID_STRONGSWAN_2_6_2 = 59,
- VID_STRONGSWAN_2_6_3 = 60,
- VID_STRONGSWAN_2_6_4 = 61,
- VID_STRONGSWAN_2_7_0 = 62,
- VID_STRONGSWAN_2_7_1 = 63,
- VID_STRONGSWAN_2_7_2 = 64,
- VID_STRONGSWAN_2_7_3 = 65,
- VID_STRONGSWAN_2_8_0 = 66,
- VID_STRONGSWAN_2_8_1 = 67,
- VID_STRONGSWAN_2_8_2 = 68,
- VID_STRONGSWAN_2_8_3 = 69,
- VID_STRONGSWAN_2_8_4 = 70,
- VID_STRONGSWAN_2_8_5 = 71,
- VID_STRONGSWAN_2_8_6 = 72,
- VID_STRONGSWAN_2_8_7 = 73,
- VID_STRONGSWAN_2_8_8 = 74,
- VID_STRONGSWAN_2_8_9 = 75,
+ VID_STRONGSWAN = 37,
+ VID_STRONGSWAN_2_2_0 = 38,
+ VID_STRONGSWAN_2_2_1 = 39,
+ VID_STRONGSWAN_2_2_2 = 40,
+ VID_STRONGSWAN_2_3_0 = 41,
+ VID_STRONGSWAN_2_3_1 = 42,
+ VID_STRONGSWAN_2_3_2 = 43,
+ VID_STRONGSWAN_2_4_0 = 44,
+ VID_STRONGSWAN_2_4_1 = 45,
+ VID_STRONGSWAN_2_4_2 = 46,
+ VID_STRONGSWAN_2_4_3 = 47,
+ VID_STRONGSWAN_2_4_4 = 48,
+ VID_STRONGSWAN_2_5_0 = 49,
+ VID_STRONGSWAN_2_5_1 = 50,
+ VID_STRONGSWAN_2_5_2 = 51,
+ VID_STRONGSWAN_2_5_3 = 52,
+ VID_STRONGSWAN_2_5_4 = 53,
+ VID_STRONGSWAN_2_5_5 = 54,
+ VID_STRONGSWAN_2_5_6 = 55,
+ VID_STRONGSWAN_2_5_7 = 56,
+ VID_STRONGSWAN_2_6_0 = 57,
+ VID_STRONGSWAN_2_6_1 = 58,
+ VID_STRONGSWAN_2_6_2 = 59,
+ VID_STRONGSWAN_2_6_3 = 60,
+ VID_STRONGSWAN_2_6_4 = 61,
+ VID_STRONGSWAN_2_7_0 = 62,
+ VID_STRONGSWAN_2_7_1 = 63,
+ VID_STRONGSWAN_2_7_2 = 64,
+ VID_STRONGSWAN_2_7_3 = 65,
+ VID_STRONGSWAN_2_8_0 = 66,
+ VID_STRONGSWAN_2_8_1 = 67,
+ VID_STRONGSWAN_2_8_2 = 68,
+ VID_STRONGSWAN_2_8_3 = 69,
+ VID_STRONGSWAN_2_8_4 = 70,
+ VID_STRONGSWAN_2_8_5 = 71,
+ VID_STRONGSWAN_2_8_6 = 72,
+ VID_STRONGSWAN_2_8_7 = 73,
+ VID_STRONGSWAN_2_8_8 = 74,
+ VID_STRONGSWAN_2_8_9 = 75,
- VID_STRONGSWAN_4_0_0 = 80,
- VID_STRONGSWAN_4_0_1 = 81,
- VID_STRONGSWAN_4_0_2 = 82,
- VID_STRONGSWAN_4_0_3 = 83,
- VID_STRONGSWAN_4_0_4 = 84,
- VID_STRONGSWAN_4_0_5 = 85,
- VID_STRONGSWAN_4_0_6 = 86,
- VID_STRONGSWAN_4_0_7 = 87,
- VID_STRONGSWAN_4_1_0 = 88,
- VID_STRONGSWAN_4_1_1 = 89,
- VID_STRONGSWAN_4_1_2 = 90,
- VID_STRONGSWAN_4_1_3 = 91,
- VID_STRONGSWAN_4_1_4 = 92,
- VID_STRONGSWAN_4_1_5 = 93,
- VID_STRONGSWAN_4_1_6 = 94,
- VID_STRONGSWAN_4_1_7 = 95,
- VID_STRONGSWAN_4_1_8 = 96,
- VID_STRONGSWAN_4_1_9 = 97,
- VID_STRONGSWAN_4_1_10 = 98,
- VID_STRONGSWAN_4_1_11 = 99,
+ VID_STRONGSWAN_4_0_0 = 80,
+ VID_STRONGSWAN_4_0_1 = 81,
+ VID_STRONGSWAN_4_0_2 = 82,
+ VID_STRONGSWAN_4_0_3 = 83,
+ VID_STRONGSWAN_4_0_4 = 84,
+ VID_STRONGSWAN_4_0_5 = 85,
+ VID_STRONGSWAN_4_0_6 = 86,
+ VID_STRONGSWAN_4_0_7 = 87,
+ VID_STRONGSWAN_4_1_0 = 88,
+ VID_STRONGSWAN_4_1_1 = 89,
+ VID_STRONGSWAN_4_1_2 = 90,
+ VID_STRONGSWAN_4_1_3 = 91,
+ VID_STRONGSWAN_4_1_4 = 92,
+ VID_STRONGSWAN_4_1_5 = 93,
+ VID_STRONGSWAN_4_1_6 = 94,
+ VID_STRONGSWAN_4_1_7 = 95,
+ VID_STRONGSWAN_4_1_8 = 96,
+ VID_STRONGSWAN_4_1_9 = 97,
+ VID_STRONGSWAN_4_1_10 = 98,
+ VID_STRONGSWAN_4_1_11 = 99,
- VID_STRONGSWAN_4_2_0 =100,
- VID_STRONGSWAN_4_2_1 =101,
- VID_STRONGSWAN_4_2_2 =102,
- VID_STRONGSWAN_4_2_3 =103,
- VID_STRONGSWAN_4_2_4 =104,
- VID_STRONGSWAN_4_2_5 =105,
- VID_STRONGSWAN_4_2_6 =106,
- VID_STRONGSWAN_4_2_7 =107,
- VID_STRONGSWAN_4_2_8 =108,
- VID_STRONGSWAN_4_2_9 =109,
- VID_STRONGSWAN_4_2_10 =110,
- VID_STRONGSWAN_4_2_11 =111,
- VID_STRONGSWAN_4_2_12 =112,
- VID_STRONGSWAN_4_2_13 =113,
+ VID_STRONGSWAN_4_2_0 =100,
+ VID_STRONGSWAN_4_2_1 =101,
+ VID_STRONGSWAN_4_2_2 =102,
+ VID_STRONGSWAN_4_2_3 =103,
+ VID_STRONGSWAN_4_2_4 =104,
+ VID_STRONGSWAN_4_2_5 =105,
+ VID_STRONGSWAN_4_2_6 =106,
+ VID_STRONGSWAN_4_2_7 =107,
+ VID_STRONGSWAN_4_2_8 =108,
+ VID_STRONGSWAN_4_2_9 =109,
+ VID_STRONGSWAN_4_2_10 =110,
+ VID_STRONGSWAN_4_2_11 =111,
+ VID_STRONGSWAN_4_2_12 =112,
+ VID_STRONGSWAN_4_2_13 =113,
+ VID_STRONGSWAN_4_2_14 =114,
+ VID_STRONGSWAN_4_2_15 =115,
+ VID_STRONGSWAN_4_3_0 =116,
+ VID_STRONGSWAN_4_3_1 =117,
/* 101 - 200 : NAT-Traversal */
- VID_NATT_STENBERG_01 =151,
- VID_NATT_STENBERG_02 =152,
- VID_NATT_HUTTUNEN =153,
- VID_NATT_HUTTUNEN_ESPINUDP =154,
- VID_NATT_IETF_00 =155,
- VID_NATT_IETF_02_N =156,
- VID_NATT_IETF_02 =157,
- VID_NATT_IETF_03 =158,
- VID_NATT_RFC =159,
+ VID_NATT_STENBERG_01 =151,
+ VID_NATT_STENBERG_02 =152,
+ VID_NATT_HUTTUNEN =153,
+ VID_NATT_HUTTUNEN_ESPINUDP =154,
+ VID_NATT_IETF_00 =155,
+ VID_NATT_IETF_02_N =156,
+ VID_NATT_IETF_02 =157,
+ VID_NATT_IETF_03 =158,
+ VID_NATT_RFC =159,
/* 201 - 300 : Misc */
- VID_MISC_XAUTH =201,
- VID_MISC_DPD =202,
- VID_MISC_HEARTBEAT_NOTIFY =203,
- VID_MISC_FRAGMENTATION =204,
- VID_INITIAL_CONTACT =205,
- VID_CISCO3K_FRAGMENTATION =206
+ VID_MISC_XAUTH =201,
+ VID_MISC_DPD =202,
+ VID_MISC_HEARTBEAT_NOTIFY =203,
+ VID_MISC_FRAGMENTATION =204,
+ VID_INITIAL_CONTACT =205,
+ VID_CISCO3K_FRAGMENTATION =206
};
void init_vendorid(void);
+void free_vendorid(void);
struct msg_digest;
void handle_vendorid (struct msg_digest *md, const char *vid, size_t len);
diff --git a/src/pluto/virtual.c b/src/pluto/virtual.c
index 4a81ee283..2067bde01 100644
--- a/src/pluto/virtual.c
+++ b/src/pluto/virtual.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: virtual.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <freeswan.h>
@@ -35,9 +33,9 @@
#define F_VIRTUAL_HOST 32
struct virtual_t {
- unsigned short flags;
- unsigned short n_net;
- ip_subnet net[0];
+ unsigned short flags;
+ unsigned short n_net;
+ ip_subnet net[0];
};
static ip_subnet *private_net_ok=NULL, *private_net_ko=NULL;
@@ -49,123 +47,119 @@ static unsigned short private_net_ok_len=0, private_net_ko_len=0;
*/
static bool
_read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko,
- bool *isok)
+ bool *isok)
{
- bool ok;
- int af;
-
- if ((len > 4) && (strncmp(src, "%v4:", 4)==0))
- {
- af = AF_INET;
- }
- else if ((len > 4) && (strncmp(src, "%v6:", 4)==0))
- {
- af = AF_INET6;
- }
- else
- {
- return FALSE;
- }
+ bool ok;
+ int af;
+
+ if ((len > 4) && (strneq(src, "%v4:", 4)))
+ {
+ af = AF_INET;
+ }
+ else if ((len > 4) && (strneq(src, "%v6:", 4)))
+ {
+ af = AF_INET6;
+ }
+ else
+ {
+ return FALSE;
+ }
- ok = (src[4] != '!');
- src += ok ? 4 : 5;
- len -= ok ? 4 : 5;
+ ok = (src[4] != '!');
+ src += ok ? 4 : 5;
+ len -= ok ? 4 : 5;
- if (!len)
- return FALSE;
- if (!ok && !dstko)
- return FALSE;
+ if (!len)
+ return FALSE;
+ if (!ok && !dstko)
+ return FALSE;
- passert ( ((ok)?(dst):(dstko))!=NULL );
+ passert ( ((ok)?(dst):(dstko))!=NULL );
- if (ttosubnet(src, len, af, ((ok)?(dst):(dstko))))
- {
- return FALSE;
- }
- if (isok)
- *isok = ok;
- return TRUE;
+ if (ttosubnet(src, len, af, ((ok)?(dst):(dstko))))
+ {
+ return FALSE;
+ }
+ if (isok)
+ *isok = ok;
+ return TRUE;
}
void
init_virtual_ip(const char *private_list)
{
- const char *next, *str=private_list;
- unsigned short ign = 0, i_ok, i_ko;
- ip_subnet sub;
- bool ok;
-
- /** Count **/
- private_net_ok_len=0;
- private_net_ko_len=0;
-
- while (str)
- {
- next = strchr(str,',');
- if (!next)
- next = str + strlen(str);
- if (_read_subnet(str, next-str, &sub, &sub, &ok))
- if (ok)
- private_net_ok_len++;
- else
- private_net_ko_len++;
- else
- ign++;
- str = *next ? next+1 : NULL;
- }
-
- if (!ign)
- {
- /** Allocate **/
- if (private_net_ok_len)
- {
- private_net_ok = (ip_subnet *)alloc_bytes(
- (private_net_ok_len*sizeof(ip_subnet)),
- "private_net_ok subnets");
- }
- if (private_net_ko_len)
- {
- private_net_ko = (ip_subnet *)alloc_bytes(
- (private_net_ko_len*sizeof(ip_subnet)),
- "private_net_ko subnets");
- }
- if ((private_net_ok_len && !private_net_ok)
- || (private_net_ko_len && !private_net_ko))
- {
- loglog(RC_LOG_SERIOUS,
- "can't alloc in init_virtual_ip");
- pfreeany(private_net_ok);
- private_net_ok = NULL;
- pfreeany(private_net_ko);
- private_net_ko = NULL;
- }
- else
- {
- /** Fill **/
- str = private_list;
- i_ok = 0;
- i_ko = 0;
+ const char *next, *str=private_list;
+ unsigned short ign = 0, i_ok, i_ko;
+ ip_subnet sub;
+ bool ok;
- while (str)
- {
+ /** Count **/
+ private_net_ok_len=0;
+ private_net_ko_len=0;
+
+ while (str)
+ {
next = strchr(str,',');
if (!next)
- next = str + strlen(str);
- if (_read_subnet(str, next-str,
- &(private_net_ok[i_ok]), &(private_net_ko[i_ko]), &ok))
+ next = str + strlen(str);
+ if (_read_subnet(str, next-str, &sub, &sub, &ok))
+ if (ok)
+ private_net_ok_len++;
+ else
+ private_net_ko_len++;
+ else
+ ign++;
+ str = *next ? next+1 : NULL;
+ }
+
+ if (!ign)
+ {
+ /** Allocate **/
+ if (private_net_ok_len)
{
- if (ok)
- i_ok++;
- else
- i_ko++;
+ private_net_ok = (ip_subnet *)malloc(private_net_ok_len * sizeof(ip_subnet));
+ }
+ if (private_net_ko_len)
+ {
+ private_net_ko = (ip_subnet *)malloc(private_net_ko_len * sizeof(ip_subnet));
+ }
+ if ((private_net_ok_len && !private_net_ok)
+ || (private_net_ko_len && !private_net_ko))
+ {
+ loglog(RC_LOG_SERIOUS,
+ "can't alloc in init_virtual_ip");
+ free(private_net_ok);
+ private_net_ok = NULL;
+ free(private_net_ko);
+ private_net_ko = NULL;
+ }
+ else
+ {
+ /** Fill **/
+ str = private_list;
+ i_ok = 0;
+ i_ko = 0;
+
+ while (str)
+ {
+ next = strchr(str,',');
+ if (!next)
+ next = str + strlen(str);
+ if (_read_subnet(str, next-str,
+ &(private_net_ok[i_ok]), &(private_net_ko[i_ko]), &ok))
+ {
+ if (ok)
+ i_ok++;
+ else
+ i_ko++;
+ }
+ str = *next ? next+1 : NULL;
+ }
}
- str = *next ? next+1 : NULL;
- }
}
- }
- else
- loglog(RC_LOG_SERIOUS,
- "%d bad entries in virtual_private - none loaded", ign);
+ else
+ loglog(RC_LOG_SERIOUS,
+ "%d bad entries in virtual_private - none loaded", ign);
}
/**
@@ -188,147 +182,146 @@ init_virtual_ip(const char *private_list)
struct virtual_t
*create_virtual(const struct connection *c, const char *string)
{
- unsigned short flags=0, n_net=0, i;
- const char *str = string, *next, *first_net=NULL;
- ip_subnet sub;
- struct virtual_t *v;
+ unsigned short flags=0, n_net=0, i;
+ const char *str = string, *next, *first_net=NULL;
+ ip_subnet sub;
+ struct virtual_t *v;
- if (!string || string[0] == '\0')
- return NULL;
+ if (!string || string[0] == '\0')
+ return NULL;
- if (strlen(string) >= 6 && strncmp(string,"vhost:",6) == 0)
- {
- flags |= F_VIRTUAL_HOST;
- str += 6;
- }
- else if (strlen(string) >= 5 && strncmp(string,"vnet:",5) == 0)
- str += 5;
- else
- goto fail;
-
- /**
- * Parse string : fill flags & count subnets
- */
- while ((str) && (*str))
- {
- next = strchr(str,',');
- if (!next) next = str + strlen(str);
- if (next-str == 3 && strncmp(str, "%no", 3) == 0)
- flags |= F_VIRTUAL_NO;
-#if 0
- else if (next-str == 4 && strncmp(str, "%ike", 4) == 0)
- flags |= F_VIRTUAL_IKE_CONFIG;
- else if (next-str == 5 && strncmp(str, "%dhcp", 5) == 0)
- flags |= F_VIRTUAL_DHCP;
-#endif
- else if (next-str == 5 && strncmp(str, "%priv", 5) == 0)
- flags |= F_VIRTUAL_PRIVATE;
- else if (next-str == 4 && strncmp(str, "%all", 4) == 0)
- flags |= F_VIRTUAL_ALL;
- else if (_read_subnet(str, next-str, &sub, NULL, NULL))
+ if (strlen(string) >= 6 && strneq(string,"vhost:",6))
{
- n_net++;
- if (!first_net)
- first_net = str;
+ flags |= F_VIRTUAL_HOST;
+ str += 6;
}
+ else if (strlen(string) >= 5 && strneq(string,"vnet:",5))
+ str += 5;
else
- goto fail;
-
- str = *next ? next+1 : NULL;
- }
-
- v = (struct virtual_t *)alloc_bytes(
- sizeof(struct virtual_t) + (n_net*sizeof(ip_subnet)),
- "virtual description");
- if (!v) goto fail;
-
- v->flags = flags;
- v->n_net = n_net;
- if (n_net && first_net)
- {
+ goto fail;
+
/**
- * Save subnets in newly allocated struct
+ * Parse string : fill flags & count subnets
*/
- for (str = first_net, i = 0; str && *str; )
+ while ((str) && (*str))
{
- next = strchr(str,',');
- if (!next) next = str + strlen(str);
- if (_read_subnet(str, next-str, &(v->net[i]), NULL, NULL))
- i++;
- str = *next ? next+1 : NULL;
+ next = strchr(str,',');
+ if (!next) next = str + strlen(str);
+ if (next-str == 3 && strneq(str, "%no", 3))
+ flags |= F_VIRTUAL_NO;
+#if 0
+ else if (next-str == 4 && strneq(str, "%ike", 4))
+ flags |= F_VIRTUAL_IKE_CONFIG;
+ else if (next-str == 5 && strneq(str, "%dhcp", 5))
+ flags |= F_VIRTUAL_DHCP;
+#endif
+ else if (next-str == 5 && strneq(str, "%priv", 5))
+ flags |= F_VIRTUAL_PRIVATE;
+ else if (next-str == 4 && strneq(str, "%all", 4))
+ flags |= F_VIRTUAL_ALL;
+ else if (_read_subnet(str, next-str, &sub, NULL, NULL))
+ {
+ n_net++;
+ if (!first_net)
+ first_net = str;
+ }
+ else
+ goto fail;
+
+ str = *next ? next+1 : NULL;
}
- }
- return v;
+ v = (struct virtual_t *)malloc(sizeof(struct virtual_t) +
+ (n_net * sizeof(ip_subnet)));
+ if (!v) goto fail;
+
+ v->flags = flags;
+ v->n_net = n_net;
+ if (n_net && first_net)
+ {
+ /**
+ * Save subnets in newly allocated struct
+ */
+ for (str = first_net, i = 0; str && *str; )
+ {
+ next = strchr(str,',');
+ if (!next) next = str + strlen(str);
+ if (_read_subnet(str, next-str, &(v->net[i]), NULL, NULL))
+ i++;
+ str = *next ? next+1 : NULL;
+ }
+ }
+
+ return v;
fail:
- plog("invalid virtual string [%s] - "
- "virtual selection disabled for connection '%s'", string, c->name);
- return NULL;
+ plog("invalid virtual string [%s] - "
+ "virtual selection disabled for connection '%s'", string, c->name);
+ return NULL;
}
bool
is_virtual_end(const struct end *that)
{
- return ((that->virt)?TRUE:FALSE);
+ return ((that->virt)?TRUE:FALSE);
}
bool
is_virtual_connection(const struct connection *c)
{
- return ((c->spd.that.virt)?TRUE:FALSE);
+ return ((c->spd.that.virt)?TRUE:FALSE);
}
static bool
net_in_list(const ip_subnet *peer_net, const ip_subnet *list,
- unsigned short len)
+ unsigned short len)
{
- unsigned short i;
+ unsigned short i;
- if (!list || !len)
- return FALSE;
+ if (!list || !len)
+ return FALSE;
- for (i = 0; i < len; i++)
- {
- if (subnetinsubnet(peer_net, &(list[i])))
- return TRUE;
- }
- return FALSE;
+ for (i = 0; i < len; i++)
+ {
+ if (subnetinsubnet(peer_net, &(list[i])))
+ return TRUE;
+ }
+ return FALSE;
}
bool
is_virtual_net_allowed(const struct connection *c, const ip_subnet *peer_net,
- const ip_address *his_addr)
+ const ip_address *his_addr)
{
- if (c->spd.that.virt == NULL)
- return FALSE;
+ if (c->spd.that.virt == NULL)
+ return FALSE;
- if ((c->spd.that.virt->flags & F_VIRTUAL_HOST)
- && !subnetishost(peer_net))
- return FALSE;
+ if ((c->spd.that.virt->flags & F_VIRTUAL_HOST)
+ && !subnetishost(peer_net))
+ return FALSE;
- if ((c->spd.that.virt->flags & F_VIRTUAL_NO)
- && subnetishost(peer_net) && addrinsubnet(his_addr, peer_net))
- return TRUE;
+ if ((c->spd.that.virt->flags & F_VIRTUAL_NO)
+ && subnetishost(peer_net) && addrinsubnet(his_addr, peer_net))
+ return TRUE;
- if ((c->spd.that.virt->flags & F_VIRTUAL_PRIVATE)
- && net_in_list(peer_net, private_net_ok, private_net_ok_len)
- && !net_in_list(peer_net, private_net_ko, private_net_ko_len))
- return TRUE;
+ if ((c->spd.that.virt->flags & F_VIRTUAL_PRIVATE)
+ && net_in_list(peer_net, private_net_ok, private_net_ok_len)
+ && !net_in_list(peer_net, private_net_ko, private_net_ko_len))
+ return TRUE;
- if (c->spd.that.virt->n_net
- && net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net))
- return TRUE;
-
- if (c->spd.that.virt->flags & F_VIRTUAL_ALL)
- {
- /** %all must only be used for testing - log it **/
- loglog(RC_LOG_SERIOUS, "Warning - "
- "v%s:%%all must only be used for testing",
- (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net");
- return TRUE;
- }
+ if (c->spd.that.virt->n_net
+ && net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net))
+ return TRUE;
+
+ if (c->spd.that.virt->flags & F_VIRTUAL_ALL)
+ {
+ /** %all must only be used for testing - log it **/
+ loglog(RC_LOG_SERIOUS, "Warning - "
+ "v%s:%%all must only be used for testing",
+ (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net");
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
diff --git a/src/pluto/virtual.h b/src/pluto/virtual.h
index 9fe9bdd8d..e64407c81 100644
--- a/src/pluto/virtual.h
+++ b/src/pluto/virtual.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: virtual.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _VIRTUAL_IP_H
@@ -20,12 +18,12 @@
extern void init_virtual_ip(const char *private_list);
extern struct virtual_t *create_virtual(const struct connection *c,
- const char *string);
+ const char *string);
extern bool is_virtual_end(const struct end *that);
extern bool is_virtual_connection(const struct connection *c);
extern bool is_virtual_net_allowed(const struct connection *c,
- const ip_subnet *peer_net, const ip_address *his_addr);
+ const ip_subnet *peer_net, const ip_address *his_addr);
#endif /* _VIRTUAL_IP_H */
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
index c61de6edc..0953f18f5 100644
--- a/src/pluto/x509.c
+++ b/src/pluto/x509.c
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
* Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2000-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: x509.c 3252 2007-10-06 21:24:50Z andreas $
*/
#include <stdlib.h>
@@ -26,16 +24,16 @@
#include <sys/types.h>
#include <freeswan.h>
-#include <ipsec_policy.h>
+
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+#include <crypto/hashers/hasher.h>
#include "constants.h"
#include "defs.h"
-#include "mp_defs.h"
#include "log.h"
#include "id.h"
-#include "asn1.h"
-#include <asn1/oid.h>
-#include "pkcs1.h"
#include "x509.h"
#include "crl.h"
#include "ca.h"
@@ -44,298 +42,243 @@
#include "whack.h"
#include "fetch.h"
#include "ocsp.h"
-#include "sha1.h"
-
-/* chained lists of X.509 end certificates */
+/**
+ * Chained lists of X.509 end certificates
+ */
static x509cert_t *x509certs = NULL;
-/* ASN.1 definition of a basicConstraints extension */
-
+/**
+ * ASN.1 definition of a basicConstraints extension
+ */
static const asn1Object_t basicConstraintsObjects[] = {
- { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "CA", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 1 */
- { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
+ { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
+ { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define BASIC_CONSTRAINTS_CA 1
-#define BASIC_CONSTRAINTS_ROOF 4
-
-/* ASN.1 definition of time */
-static const asn1Object_t timeObjects[] = {
- { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT |
- ASN1_BODY }, /* 0 */
- { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "generalizeTime", ASN1_GENERALIZEDTIME, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define TIME_UTC 0
-#define TIME_GENERALIZED 2
-#define TIME_ROOF 4
-
-/* ASN.1 definition of a keyIdentifier */
-
-static const asn1Object_t keyIdentifierObjects[] = {
- { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
-};
-
-/* ASN.1 definition of a authorityKeyIdentifier extension */
-
-static const asn1Object_t authorityKeyIdentifierObjects[] = {
- { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 3 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT |
- ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
+/**
+ * ASN.1 definition of a authorityKeyIdentifier extension
+ */
+static const asn1Object_t authKeyIdentifierObjects[] = {
+ { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
-#define AUTH_KEY_ID_KEY_ID 1
+#define AUTH_KEY_ID_KEY_ID 1
#define AUTH_KEY_ID_CERT_ISSUER 3
#define AUTH_KEY_ID_CERT_SERIAL 5
-#define AUTH_KEY_ID_ROOF 7
-
-/* ASN.1 definition of a authorityInfoAccess extension */
-static const asn1Object_t authorityInfoAccessObjects[] = {
- { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
+/**
+ * ASN.1 definition of a authorityInfoAccess extension
+ */
+static const asn1Object_t authInfoAccessObjects[] = {
+ { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define AUTH_INFO_ACCESS_METHOD 2
#define AUTH_INFO_ACCESS_LOCATION 3
-#define AUTH_INFO_ACCESS_ROOF 5
-
-/* ASN.1 definition of a extendedKeyUsage extension */
+/**
+ * ASN.1 definition of a extendedKeyUsage extension
+ */
static const asn1Object_t extendedKeyUsageObjects[] = {
- { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define EXT_KEY_USAGE_PURPOSE_ID 1
-#define EXT_KEY_USAGE_ROOF 3
-
-/* ASN.1 definition of generalNames */
+/**
+ * ASN.1 definition of generalNames
+ */
static const asn1Object_t generalNamesObjects[] = {
- { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
+ { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define GENERAL_NAMES_GN 1
-#define GENERAL_NAMES_ROOF 3
-
-/* ASN.1 definition of generalName */
+/**
+ * ASN.1 definition of generalName
+ */
static const asn1Object_t generalNameObjects[] = {
- { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 0 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT |
- ASN1_BODY }, /* 4 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT |
- ASN1_BODY }, /* 6 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT |
- ASN1_BODY }, /* 10 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "uniformResourceIdentifier", ASN1_CONTEXT_S_6, ASN1_OPT |
- ASN1_BODY }, /* 12 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
- { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT |
- ASN1_BODY }, /* 16 */
- { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
+ { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
+ { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
+ { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
+ { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 17 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
-#define GN_OBJ_OTHER_NAME 0
-#define GN_OBJ_RFC822_NAME 2
-#define GN_OBJ_DNS_NAME 4
-#define GN_OBJ_X400_ADDRESS 6
+#define GN_OBJ_OTHER_NAME 0
+#define GN_OBJ_RFC822_NAME 2
+#define GN_OBJ_DNS_NAME 4
+#define GN_OBJ_X400_ADDRESS 6
#define GN_OBJ_DIRECTORY_NAME 8
#define GN_OBJ_EDI_PARTY_NAME 10
-#define GN_OBJ_URI 12
-#define GN_OBJ_IP_ADDRESS 14
+#define GN_OBJ_URI 12
+#define GN_OBJ_IP_ADDRESS 14
#define GN_OBJ_REGISTERED_ID 16
-#define GN_OBJ_ROOF 18
-
-/* ASN.1 definition of otherName */
+/**
+ * ASN.1 definition of otherName
+ */
static const asn1Object_t otherNameObjects[] = {
- {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
- {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
+ {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
+ {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY }, /* 1 */
+ {0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define ON_OBJ_ID_TYPE 0
#define ON_OBJ_VALUE 1
-#define ON_OBJ_ROOF 2
-
-/* ASN.1 definition of crlDistributionPoints */
+/**
+ * ASN.1 definition of crlDistributionPoints
+ */
static const asn1Object_t crlDistributionPointsObjects[] = {
- { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 2 */
- { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 3 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 3, "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_BODY }, /* 5 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT |
- ASN1_BODY }, /* 10 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
+ { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
+ { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
+ { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
+ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
#define CRL_DIST_POINTS_FULLNAME 3
-#define CRL_DIST_POINTS_ROOF 13
-
-/* ASN.1 definition of an X.509v3 certificate */
+/**
+ * ASN.1 definition of an X.509v3 x509_cert
+ */
static const asn1Object_t certObjects[] = {
- { 0, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
- { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
- { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 2, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
- { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
- { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 14 */
- { 5, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 15 */
- { 5, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 16 */
- { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 17 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 19 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 21 */
- { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 22 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 23 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 24 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 25 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 26 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 27 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 28 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 29 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 30 */
+ { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
+ { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
+ { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
+ { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
+ { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
+ { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_RAW }, /* 11 */
+ { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 14 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 16 */
+ { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 17 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 18 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 19 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 20 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 21 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 22 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 23 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 24 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 25 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
-#define X509_OBJ_CERTIFICATE 0
-#define X509_OBJ_TBS_CERTIFICATE 1
-#define X509_OBJ_VERSION 3
-#define X509_OBJ_SERIAL_NUMBER 4
-#define X509_OBJ_SIG_ALG 5
-#define X509_OBJ_ISSUER 6
-#define X509_OBJ_NOT_BEFORE 8
-#define X509_OBJ_NOT_AFTER 9
-#define X509_OBJ_SUBJECT 10
-#define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
-#define X509_OBJ_SUBJECT_PUBLIC_KEY 13
-#define X509_OBJ_RSA_PUBLIC_KEY 14
-#define X509_OBJ_MODULUS 15
-#define X509_OBJ_PUBLIC_EXPONENT 16
-#define X509_OBJ_EXTN_ID 24
-#define X509_OBJ_CRITICAL 25
-#define X509_OBJ_EXTN_VALUE 26
-#define X509_OBJ_ALGORITHM 29
-#define X509_OBJ_SIGNATURE 30
-#define X509_OBJ_ROOF 31
-
+#define X509_OBJ_CERTIFICATE 0
+#define X509_OBJ_TBS_CERTIFICATE 1
+#define X509_OBJ_VERSION 3
+#define X509_OBJ_SERIAL_NUMBER 4
+#define X509_OBJ_SIG_ALG 5
+#define X509_OBJ_ISSUER 6
+#define X509_OBJ_NOT_BEFORE 8
+#define X509_OBJ_NOT_AFTER 9
+#define X509_OBJ_SUBJECT 10
+#define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
+#define X509_OBJ_EXTN_ID 19
+#define X509_OBJ_CRITICAL 20
+#define X509_OBJ_EXTN_VALUE 21
+#define X509_OBJ_ALGORITHM 24
+#define X509_OBJ_SIGNATURE 25
const x509cert_t empty_x509cert = {
- NULL , /* *next */
- UNDEFINED_TIME, /* installed */
- 0 , /* count */
- FALSE , /* smartcard */
- AUTH_NONE , /* authority_flags */
- { NULL, 0 } , /* certificate */
- { NULL, 0 } , /* tbsCertificate */
- 1 , /* version */
- { NULL, 0 } , /* serialNumber */
- OID_UNKNOWN , /* sigAlg */
- { NULL, 0 } , /* issuer */
- /* validity */
- 0 , /* notBefore */
- 0 , /* notAfter */
- { NULL, 0 } , /* subject */
- /* subjectPublicKeyInfo */
- OID_UNKNOWN , /* subjectPublicKeyAlgorithm */
- { NULL, 0 } , /* subjectPublicKey */
- { NULL, 0 } , /* modulus */
- { NULL, 0 } , /* publicExponent */
- /* issuerUniqueID */
- /* subjectUniqueID */
- /* extensions */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- FALSE , /* isCA */
- FALSE , /* isOcspSigner */
- { NULL, 0 } , /* subjectKeyID */
- { NULL, 0 } , /* authKeyID */
- { NULL, 0 } , /* authKeySerialNumber */
- { NULL, 0 } , /* accessLocation */
- NULL , /* subjectAltName */
- NULL , /* crlDistributionPoints */
- OID_UNKNOWN , /* algorithm */
- { NULL, 0 } /* signature */
+ NULL , /* *next */
+ UNDEFINED_TIME, /* installed */
+ 0 , /* count */
+ FALSE , /* smartcard */
+ AUTH_NONE , /* authority_flags */
+ { NULL, 0 } , /* certificate */
+ { NULL, 0 } , /* tbsCertificate */
+ 1 , /* version */
+ { NULL, 0 } , /* serialNumber */
+ OID_UNKNOWN , /* sigAlg */
+ { NULL, 0 } , /* issuer */
+ /* validity */
+ 0 , /* notBefore */
+ 0 , /* notAfter */
+ { NULL, 0 } , /* subject */
+ NULL , /* public_key */
+ /* issuerUniqueID */
+ /* subjectUniqueID */
+ /* extensions */
+ /* extension */
+ /* extnID */
+ /* critical */
+ /* extnValue */
+ FALSE , /* isCA */
+ FALSE , /* isOcspSigner */
+ { NULL, 0 } , /* subjectKeyID */
+ { NULL, 0 } , /* authKeyID */
+ { NULL, 0 } , /* authKeySerialNumber */
+ { NULL, 0 } , /* accessLocation */
+ NULL , /* subjectAltName */
+ NULL , /* crlDistributionPoints */
+ OID_UNKNOWN , /* algorithm */
+ { NULL, 0 } /* signature */
};
/* coding of X.501 distinguished name */
typedef struct {
- const u_char *name;
- chunk_t oid;
- u_char type;
+ const u_char *name;
+ chunk_t oid;
+ u_char type;
} x501rdn_t;
/* X.501 acronyms for well known object identifiers (OIDs) */
static u_char oid_ND[] = {0x02, 0x82, 0x06, 0x01,
- 0x0A, 0x07, 0x14};
+ 0x0A, 0x07, 0x14};
static u_char oid_UID[] = {0x09, 0x92, 0x26, 0x89, 0x93,
- 0xF2, 0x2C, 0x64, 0x01, 0x01};
+ 0xF2, 0x2C, 0x64, 0x01, 0x01};
static u_char oid_DC[] = {0x09, 0x92, 0x26, 0x89, 0x93,
- 0xF2, 0x2C, 0x64, 0x01, 0x19};
+ 0xF2, 0x2C, 0x64, 0x01, 0x19};
static u_char oid_CN[] = {0x55, 0x04, 0x03};
static u_char oid_S[] = {0x55, 0x04, 0x04};
static u_char oid_SN[] = {0x55, 0x04, 0x05};
@@ -351,13 +294,13 @@ static u_char oid_G[] = {0x55, 0x04, 0x2A};
static u_char oid_I[] = {0x55, 0x04, 0x2B};
static u_char oid_ID[] = {0x55, 0x04, 0x2D};
static u_char oid_EN[] = {0x60, 0x86, 0x48, 0x01, 0x86,
- 0xF8, 0x42, 0x03, 0x01, 0x03};
+ 0xF8, 0x42, 0x03, 0x01, 0x03};
static u_char oid_E[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
- 0x0D, 0x01, 0x09, 0x01};
+ 0x0D, 0x01, 0x09, 0x01};
static u_char oid_UN[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
- 0x0D, 0x01, 0x09, 0x02};
+ 0x0D, 0x01, 0x09, 0x02};
static u_char oid_TCGID[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
- 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
+ 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
static const x501rdn_t x501rdns[] = {
{"ND" , {oid_ND, 7}, ASN1_PRINTABLESTRING},
@@ -391,1850 +334,1804 @@ static const x501rdn_t x501rdns[] = {
#define X501_RDN_ROOF 26
static u_char ASN1_subjectAltName_oid_str[] = {
- 0x06, 0x03, 0x55, 0x1D, 0x11
+ 0x06, 0x03, 0x55, 0x1D, 0x11
};
-static const chunk_t ASN1_subjectAltName_oid = strchunk(ASN1_subjectAltName_oid_str);
+static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
-static void
-update_chunk(chunk_t *ch, int n)
+static void update_chunk(chunk_t *ch, int n)
{
- n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
- ch->ptr += n; ch->len -= n;
+ n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
+ ch->ptr += n; ch->len -= n;
}
-/*
+/**
* Pointer is set to the first RDN in a DN
*/
-static err_t
-init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
+static err_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
{
- *rdn = empty_chunk;
- *attribute = empty_chunk;
-
- /* a DN is a SEQUENCE OF RDNs */
+ *rdn = chunk_empty;
+ *attribute = chunk_empty;
- if (*dn.ptr != ASN1_SEQUENCE)
- {
- return "DN is not a SEQUENCE";
- }
+ /* a DN is a SEQUENCE OF RDNs */
- rdn->len = asn1_length(&dn);
+ if (*dn.ptr != ASN1_SEQUENCE)
+ {
+ return "DN is not a SEQUENCE";
+ }
- if (rdn->len == ASN1_INVALID_LENGTH)
- return "Invalid RDN length";
+ rdn->len = asn1_length(&dn);
- rdn->ptr = dn.ptr;
+ if (rdn->len == ASN1_INVALID_LENGTH)
+ {
+ return "Invalid RDN length";
+ }
+ rdn->ptr = dn.ptr;
- /* are there any RDNs ? */
- *next = rdn->len > 0;
+ /* are there any RDNs ? */
+ *next = rdn->len > 0;
- return NULL;
+ return NULL;
}
-/*
+/**
* Fetches the next RDN in a DN
*/
-static err_t
-get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
-, asn1_t *type, bool *next)
+static err_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid,
+ chunk_t *value, asn1_t *type, bool *next)
{
- chunk_t body;
+ chunk_t body;
- /* initialize return values */
- *oid = empty_chunk;
- *value = empty_chunk;
+ /* initialize return values */
+ *oid = chunk_empty;
+ *value = chunk_empty;
- /* if all attributes have been parsed, get next rdn */
- if (attribute->len <= 0)
- {
- /* an RDN is a SET OF attributeTypeAndValue */
- if (*rdn->ptr != ASN1_SET)
- return "RDN is not a SET";
-
- attribute->len = asn1_length(rdn);
-
- if (attribute->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute length";
-
- attribute->ptr = rdn->ptr;
-
- /* advance to start of next RDN */
- rdn->ptr += attribute->len;
- rdn->len -= attribute->len;
- }
-
- /* an attributeTypeAndValue is a SEQUENCE */
- if (*attribute->ptr != ASN1_SEQUENCE)
- return "attributeTypeAndValue is not a SEQUENCE";
-
- /* extract the attribute body */
- body.len = asn1_length(attribute);
-
- if (body.len == ASN1_INVALID_LENGTH)
- return "Invalid attribute body length";
+ /* if all attributes have been parsed, get next rdn */
+ if (attribute->len <= 0)
+ {
+ /* an RDN is a SET OF attributeTypeAndValue */
+ if (*rdn->ptr != ASN1_SET)
+ {
+ return "RDN is not a SET";
+ }
+ attribute->len = asn1_length(rdn);
+
+ if (attribute->len == ASN1_INVALID_LENGTH)
+ {
+ return "Invalid attribute length";
+ }
+ attribute->ptr = rdn->ptr;
- body.ptr = attribute->ptr;
-
- /* advance to start of next attribute */
- attribute->ptr += body.len;
- attribute->len -= body.len;
+ /* advance to start of next RDN */
+ rdn->ptr += attribute->len;
+ rdn->len -= attribute->len;
+ }
- /* attribute type is an OID */
- if (*body.ptr != ASN1_OID)
- return "attributeType is not an OID";
+ /* an attributeTypeAndValue is a SEQUENCE */
+ if (*attribute->ptr != ASN1_SEQUENCE)
+ {
+ return "attributeTypeAndValue is not a SEQUENCE";
+ }
- /* extract OID */
- oid->len = asn1_length(&body);
-
- if (oid->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute OID length";
+ /* extract the attribute body */
+ body.len = asn1_length(attribute);
+
+ if (body.len == ASN1_INVALID_LENGTH)
+ {
+ return "Invalid attribute body length";
+ }
+ body.ptr = attribute->ptr;
+
+ /* advance to start of next attribute */
+ attribute->ptr += body.len;
+ attribute->len -= body.len;
- oid->ptr = body.ptr;
+ /* attribute type is an OID */
+ if (*body.ptr != ASN1_OID)
+ {
+ return "attributeType is not an OID";
+ }
- /* advance to the attribute value */
- body.ptr += oid->len;
- body.len -= oid->len;
+ /* extract OID */
+ oid->len = asn1_length(&body);
+
+ if (oid->len == ASN1_INVALID_LENGTH)
+ {
+ return "Invalid attribute OID length";
+ }
+ oid->ptr = body.ptr;
- /* extract string type */
- *type = *body.ptr;
+ /* advance to the attribute value */
+ body.ptr += oid->len;
+ body.len -= oid->len;
- /* extract string value */
- value->len = asn1_length(&body);
-
- if (value->len == ASN1_INVALID_LENGTH)
- return "Invalid attribute string length";
+ /* extract string type */
+ *type = *body.ptr;
- value->ptr = body.ptr;
+ /* extract string value */
+ value->len = asn1_length(&body);
+
+ if (value->len == ASN1_INVALID_LENGTH)
+ {
+ return "Invalid attribute string length";
+ }
+ value->ptr = body.ptr;
- /* are there any RDNs left? */
- *next = rdn->len > 0 || attribute->len > 0;
+ /* are there any RDNs left? */
+ *next = rdn->len > 0 || attribute->len > 0;
- return NULL;
+ return NULL;
}
-/*
+/**
* Parses an ASN.1 distinguished name int its OID/value pairs
*/
-static err_t
-dn_parse(chunk_t dn, chunk_t *str)
+static err_t dn_parse(chunk_t dn, chunk_t *str)
{
- chunk_t rdn, oid, attribute, value;
- asn1_t type;
- int oid_code;
- bool next;
- bool first = TRUE;
+ chunk_t rdn, oid, attribute, value;
+ asn1_t type;
+ int oid_code;
+ bool next;
+ bool first = TRUE;
- err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
+ err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
- if (ugh != NULL) /* a parsing error has occured */
- return ugh;
+ if (ugh != NULL) /* a parsing error has occured */
+ {
+ return ugh;
+ }
- while (next)
- {
- ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
+ while (next)
+ {
+ ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
- if (ugh != NULL) /* a parsing error has occured */
- return ugh;
+ if (ugh != NULL) /* a parsing error has occured */
+ {
+ return ugh;
+ }
- if (first) /* first OID/value pair */
- first = FALSE;
- else /* separate OID/value pair by a comma */
- update_chunk(str, snprintf(str->ptr,str->len,", "));
+ if (first) /* first OID/value pair */
+ {
+ first = FALSE;
+ }
+ else /* separate OID/value pair by a comma */
+ {
+ update_chunk(str, snprintf(str->ptr,str->len,", "));
+ }
- /* print OID */
- oid_code = known_oid(oid);
- if (oid_code == OID_UNKNOWN) /* OID not found in list */
- hex_str(oid, str);
- else
- update_chunk(str, snprintf(str->ptr,str->len,"%s",
- oid_names[oid_code].name));
+ /* print OID */
+ oid_code = asn1_known_oid(oid);
+ if (oid_code == OID_UNKNOWN) /* OID not found in list */
+ {
+ hex_str(oid, str);
+ }
+ else
+ {
+ update_chunk(str, snprintf(str->ptr,str->len,"%s",
+ oid_names[oid_code].name));
+ }
- /* print value */
- update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
- (int)value.len,value.ptr));
- }
- return NULL;
+ /* print value */
+ update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
+ (int)value.len,value.ptr));
+ }
+ return NULL;
}
-/*
+/**
* Count the number of wildcard RDNs in a distinguished name
*/
-int
-dn_count_wildcards(chunk_t dn)
+int dn_count_wildcards(chunk_t dn)
{
- chunk_t rdn, attribute, oid, value;
- asn1_t type;
- bool next;
- int wildcards = 0;
+ chunk_t rdn, attribute, oid, value;
+ asn1_t type;
+ bool next;
+ int wildcards = 0;
- err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
+ err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
- if (ugh != NULL) /* a parsing error has occured */
- return -1;
+ if (ugh != NULL) /* a parsing error has occured */
+ {
+ return -1;
+ }
- while (next)
- {
- ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
+ while (next)
+ {
+ ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
- if (ugh != NULL) /* a parsing error has occured */
- return -1;
- if (value.len == 1 && *value.ptr == '*')
- wildcards++; /* we have found a wildcard RDN */
- }
- return wildcards;
+ if (ugh != NULL) /* a parsing error has occured */
+ {
+ return -1;
+ }
+ if (value.len == 1 && *value.ptr == '*')
+ {
+ wildcards++; /* we have found a wildcard RDN */
+ }
+ }
+ return wildcards;
}
-/*
+/**
* Prints a binary string in hexadecimal form
*/
-void
-hex_str(chunk_t bin, chunk_t *str)
+void hex_str(chunk_t bin, chunk_t *str)
{
- u_int i;
- update_chunk(str, snprintf(str->ptr,str->len,"0x"));
- for (i=0; i < bin.len; i++)
- update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
+ u_int i;
+ update_chunk(str, snprintf(str->ptr,str->len,"0x"));
+ for (i=0; i < bin.len; i++)
+ update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
}
-/* Converts a binary DER-encoded ASN.1 distinguished name
+/** Converts a binary DER-encoded ASN.1 distinguished name
* into LDAP-style human-readable ASCII format
*/
-int
-dntoa(char *dst, size_t dstlen, chunk_t dn)
+int dntoa(char *dst, size_t dstlen, chunk_t dn)
{
- err_t ugh = NULL;
- chunk_t str;
-
- str.ptr = dst;
- str.len = dstlen;
- ugh = dn_parse(dn, &str);
+ err_t ugh = NULL;
+ chunk_t str;
- if (ugh != NULL) /* error, print DN as hex string */
- {
- DBG(DBG_PARSING,
- DBG_log("error in DN parsing: %s", ugh)
- )
str.ptr = dst;
str.len = dstlen;
- hex_str(dn, &str);
- }
- return (int)(dstlen - str.len);
+ ugh = dn_parse(dn, &str);
+
+ if (ugh != NULL) /* error, print DN as hex string */
+ {
+ DBG(DBG_PARSING,
+ DBG_log("error in DN parsing: %s", ugh)
+ )
+ str.ptr = dst;
+ str.len = dstlen;
+ hex_str(dn, &str);
+ }
+ return (int)(dstlen - str.len);
}
-/*
+/**
* Same as dntoa but prints a special string for a null dn
*/
-int
-dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
+int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
{
- if (dn.ptr == NULL)
- return snprintf(dst, dstlen, "%s", null_dn);
+ if (dn.ptr == NULL)
+ {
+ return snprintf(dst, dstlen, "%s", null_dn);
+ }
+ else
+ {
+ return dntoa(dst, dstlen, dn);
+ }
+}
+
+
+/**
+ * Codes ASN.1 lengths up to a size of 16'777'215 bytes
+ */
+static void code_asn1_length(size_t length, chunk_t *code)
+{
+ if (length < 128)
+ {
+ code->ptr[0] = length;
+ code->len = 1;
+ }
+ else if (length < 256)
+ {
+ code->ptr[0] = 0x81;
+ code->ptr[1] = (u_char) length;
+ code->len = 2;
+ }
+ else if (length < 65536)
+ {
+ code->ptr[0] = 0x82;
+ code->ptr[1] = length >> 8;
+ code->ptr[2] = length & 0x00ff;
+ code->len = 3;
+ }
else
- return dntoa(dst, dstlen, dn);
+ {
+ code->ptr[0] = 0x83;
+ code->ptr[1] = length >> 16;
+ code->ptr[2] = (length >> 8) & 0x00ff;
+ code->ptr[3] = length & 0x0000ff;
+ code->len = 4;
+ }
}
-/* Converts an LDAP-style human-readable ASCII-encoded
+/**
+ * Converts an LDAP-style human-readable ASCII-encoded
* ASN.1 distinguished name into binary DER-encoded format
*/
-err_t
-atodn(char *src, chunk_t *dn)
+err_t atodn(char *src, chunk_t *dn)
{
/* finite state machine for atodn */
- typedef enum {
- SEARCH_OID = 0,
- READ_OID = 1,
- SEARCH_NAME = 2,
- READ_NAME = 3,
- UNKNOWN_OID = 4
- } state_t;
-
- u_char oid_len_buf[3];
- u_char name_len_buf[3];
- u_char rdn_seq_len_buf[3];
- u_char rdn_set_len_buf[3];
- u_char dn_seq_len_buf[3];
-
- chunk_t asn1_oid_len = { oid_len_buf, 0 };
- chunk_t asn1_name_len = { name_len_buf, 0 };
- chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
- chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
- chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
- chunk_t oid = empty_chunk;
- chunk_t name = empty_chunk;
-
- int whitespace = 0;
- int rdn_seq_len = 0;
- int rdn_set_len = 0;
- int dn_seq_len = 0;
- int pos = 0;
-
- err_t ugh = NULL;
-
- u_char *dn_ptr = dn->ptr + 4;
-
- state_t state = SEARCH_OID;
-
- do
- {
- switch (state)
+ typedef enum {
+ SEARCH_OID = 0,
+ READ_OID = 1,
+ SEARCH_NAME = 2,
+ READ_NAME = 3,
+ UNKNOWN_OID = 4
+ } state_t;
+
+ u_char oid_len_buf[3];
+ u_char name_len_buf[3];
+ u_char rdn_seq_len_buf[3];
+ u_char rdn_set_len_buf[3];
+ u_char dn_seq_len_buf[3];
+
+ chunk_t asn1_oid_len = { oid_len_buf, 0 };
+ chunk_t asn1_name_len = { name_len_buf, 0 };
+ chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
+ chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
+ chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
+ chunk_t oid = chunk_empty;
+ chunk_t name = chunk_empty;
+
+ int whitespace = 0;
+ int rdn_seq_len = 0;
+ int rdn_set_len = 0;
+ int dn_seq_len = 0;
+ int pos = 0;
+
+ err_t ugh = NULL;
+
+ u_char *dn_ptr = dn->ptr + 4;
+
+ state_t state = SEARCH_OID;
+
+ do
{
- case SEARCH_OID:
- if (*src != ' ' && *src != '/' && *src != ',')
- {
- oid.ptr = src;
- oid.len = 1;
- state = READ_OID;
- }
- break;
- case READ_OID:
- if (*src != ' ' && *src != '=')
- oid.len++;
- else
- {
- for (pos = 0; pos < X501_RDN_ROOF; pos++)
+ switch (state)
{
- if (strlen(x501rdns[pos].name) == oid.len &&
- strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
- break; /* found a valid OID */
- }
- if (pos == X501_RDN_ROOF)
- {
- ugh = "unknown OID in distinguished name";
- state = UNKNOWN_OID;
- break;
+ case SEARCH_OID:
+ if (*src != ' ' && *src != '/' && *src != ',')
+ {
+ oid.ptr = src;
+ oid.len = 1;
+ state = READ_OID;
+ }
+ break;
+ case READ_OID:
+ if (*src != ' ' && *src != '=')
+ {
+ oid.len++;
+ }
+ else
+ {
+ for (pos = 0; pos < X501_RDN_ROOF; pos++)
+ {
+ if (strlen(x501rdns[pos].name) == oid.len &&
+ strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
+ {
+ break; /* found a valid OID */
+ }
+ }
+ if (pos == X501_RDN_ROOF)
+ {
+ ugh = "unknown OID in distinguished name";
+ state = UNKNOWN_OID;
+ break;
+ }
+ code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
+
+ /* reset oid and change state */
+ oid = chunk_empty;
+ state = SEARCH_NAME;
+ }
+ break;
+ case SEARCH_NAME:
+ if (*src != ' ' && *src != '=')
+ {
+ name.ptr = src;
+ name.len = 1;
+ whitespace = 0;
+ state = READ_NAME;
+ }
+ break;
+ case READ_NAME:
+ if (*src != ',' && *src != '/' && *src != '\0')
+ {
+ name.len++;
+ if (*src == ' ')
+ {
+ whitespace++;
+ }
+ else
+ {
+ whitespace = 0;
+ }
+ }
+ else
+ {
+ name.len -= whitespace;
+ code_asn1_length(name.len, &asn1_name_len);
+
+ /* compute the length of the relative distinguished name sequence */
+ rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
+ 1 + asn1_name_len.len + name.len;
+ code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
+
+ /* compute the length of the relative distinguished name set */
+ rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
+ code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
+
+ /* encode the relative distinguished name */
+ *dn_ptr++ = ASN1_SET;
+ chunkcpy(dn_ptr, asn1_rdn_set_len);
+ *dn_ptr++ = ASN1_SEQUENCE;
+ chunkcpy(dn_ptr, asn1_rdn_seq_len);
+ *dn_ptr++ = ASN1_OID;
+ chunkcpy(dn_ptr, asn1_oid_len);
+ chunkcpy(dn_ptr, x501rdns[pos].oid);
+ /* encode the ASN.1 character string type of the name */
+ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
+ && !asn1_is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
+ chunkcpy(dn_ptr, asn1_name_len);
+ chunkcpy(dn_ptr, name);
+
+ /* accumulate the length of the distinguished name sequence */
+ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
+
+ /* reset name and change state */
+ name = chunk_empty;
+ state = SEARCH_OID;
+ }
+ break;
+ case UNKNOWN_OID:
+ break;
}
- code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
-
- /* reset oid and change state */
- oid = empty_chunk;
- state = SEARCH_NAME;
- }
- break;
- case SEARCH_NAME:
- if (*src != ' ' && *src != '=')
- {
- name.ptr = src;
- name.len = 1;
- whitespace = 0;
- state = READ_NAME;
- }
- break;
- case READ_NAME:
- if (*src != ',' && *src != '/' && *src != '\0')
- {
- name.len++;
- if (*src == ' ')
- whitespace++;
- else
- whitespace = 0;
- }
- else
- {
- name.len -= whitespace;
- code_asn1_length(name.len, &asn1_name_len);
-
- /* compute the length of the relative distinguished name sequence */
- rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
- 1 + asn1_name_len.len + name.len;
- code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
-
- /* compute the length of the relative distinguished name set */
- rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
- code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
-
- /* encode the relative distinguished name */
- *dn_ptr++ = ASN1_SET;
- chunkcpy(dn_ptr, asn1_rdn_set_len);
- *dn_ptr++ = ASN1_SEQUENCE;
- chunkcpy(dn_ptr, asn1_rdn_seq_len);
- *dn_ptr++ = ASN1_OID;
- chunkcpy(dn_ptr, asn1_oid_len);
- chunkcpy(dn_ptr, x501rdns[pos].oid);
- /* encode the ASN.1 character string type of the name */
- *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
- chunkcpy(dn_ptr, asn1_name_len);
- chunkcpy(dn_ptr, name);
-
- /* accumulate the length of the distinguished name sequence */
- dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
-
- /* reset name and change state */
- name = empty_chunk;
- state = SEARCH_OID;
- }
- break;
- case UNKNOWN_OID:
- break;
- }
- } while (*src++ != '\0');
-
- /* complete the distinguished name sequence*/
- code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
- dn->ptr += 3 - asn1_dn_seq_len.len;
- dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
- dn_ptr = dn->ptr;
- *dn_ptr++ = ASN1_SEQUENCE;
- chunkcpy(dn_ptr, asn1_dn_seq_len);
- return ugh;
+ } while (*src++ != '\0');
+
+ /* complete the distinguished name sequence*/
+ code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
+ dn->ptr += 3 - asn1_dn_seq_len.len;
+ dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
+ dn_ptr = dn->ptr;
+ *dn_ptr++ = ASN1_SEQUENCE;
+ chunkcpy(dn_ptr, asn1_dn_seq_len);
+ return ugh;
}
-/* compare two distinguished names by
- * comparing the individual RDNs
+/**
+ * compare two distinguished names by comparing the individual RDNs
*/
-bool
-same_dn(chunk_t a, chunk_t b)
+bool same_dn(chunk_t a, chunk_t b)
{
- chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
- chunk_t oid_a, oid_b, value_a, value_b;
- asn1_t type_a, type_b;
- bool next_a, next_b;
+ chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
+ chunk_t oid_a, oid_b, value_a, value_b;
+ asn1_t type_a, type_b;
+ bool next_a, next_b;
- /* same lengths for the DNs */
- if (a.len != b.len)
- return FALSE;
+ /* same lengths for the DNs */
+ if (a.len != b.len)
+ {
+ return FALSE;
+ }
- /* try a binary comparison first */
- if (memcmp(a.ptr, b.ptr, b.len) == 0)
- return TRUE;
-
- /* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
- return FALSE;
+ /* try a binary comparison first */
+ if (memeq(a.ptr, b.ptr, b.len))
+ {
+ return TRUE;
+ }
- /* fetch next RDN pair */
- while (next_a && next_b)
- {
- /* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
+ /* initialize DN parsing */
+ if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
+ || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
{
- return FALSE;
+ return FALSE;
}
- /* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
- return FALSE;
+ /* fetch next RDN pair */
+ while (next_a && next_b)
+ {
+ /* parse next RDNs and check for errors */
+ if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
+ || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
+ {
+ return FALSE;
+ }
+
+ /* OIDs must agree */
+ if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ {
+ return FALSE;
+ }
- /* same lengths for values */
- if (value_a.len != value_b.len)
- return FALSE;
+ /* same lengths for values */
+ if (value_a.len != value_b.len)
+ {
+ return FALSE;
+ }
- /* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
- (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
- {
- if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
+ /* printableStrings and email RDNs require uppercase comparison */
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ {
+ if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+ {
+ return FALSE;
+ }
+ }
}
- else
+ /* both DNs must have same number of RDNs */
+ if (next_a || next_b)
{
- if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
return FALSE;
}
- }
- /* both DNs must have same number of RDNs */
- if (next_a || next_b)
- return FALSE;
- /* the two DNs are equal! */
- return TRUE;
+ /* the two DNs are equal! */
+ return TRUE;
}
-/* compare two distinguished names by comparing the individual RDNs.
+/**
+ * Compare two distinguished names by comparing the individual RDNs.
* A single'*' character designates a wildcard RDN in DN b.
*/
-bool
-match_dn(chunk_t a, chunk_t b, int *wildcards)
+bool match_dn(chunk_t a, chunk_t b, int *wildcards)
{
- chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
- chunk_t oid_a, oid_b, value_a, value_b;
- asn1_t type_a, type_b;
- bool next_a, next_b;
+ chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
+ chunk_t oid_a, oid_b, value_a, value_b;
+ asn1_t type_a, type_b;
+ bool next_a, next_b;
- /* initialize wildcard counter */
- *wildcards = 0;
+ /* initialize wildcard counter */
+ *wildcards = 0;
- /* initialize DN parsing */
- if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
- || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
- return FALSE;
-
- /* fetch next RDN pair */
- while (next_a && next_b)
- {
- /* parse next RDNs and check for errors */
- if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
- || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
+ /* initialize DN parsing */
+ if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
+ || init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
{
- return FALSE;
+ return FALSE;
}
- /* OIDs must agree */
- if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
- return FALSE;
-
- /* does rdn_b contain a wildcard? */
- if (value_b.len == 1 && *value_b.ptr == '*')
+ /* fetch next RDN pair */
+ while (next_a && next_b)
{
- (*wildcards)++;
- continue;
- }
+ /* parse next RDNs and check for errors */
+ if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
+ || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
+ {
+ return FALSE;
+ }
- /* same lengths for values */
- if (value_a.len != value_b.len)
- return FALSE;
+ /* OIDs must agree */
+ if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+ {
+ return FALSE;
+ }
- /* printableStrings and email RDNs require uppercase comparison */
- if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
- (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
- {
- if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
- return FALSE;
+ /* does rdn_b contain a wildcard? */
+ if (value_b.len == 1 && *value_b.ptr == '*')
+ {
+ (*wildcards)++;
+ continue;
+ }
+
+ /* same lengths for values */
+ if (value_a.len != value_b.len)
+ {
+ return FALSE;
+ }
+
+ /* printableStrings and email RDNs require uppercase comparison */
+ if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
+ (type_a == ASN1_IA5STRING && asn1_known_oid(oid_a) == OID_PKCS9_EMAIL)))
+ {
+ if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+ {
+ return FALSE;
+ }
+ }
}
- else
+
+ /* both DNs must have same number of RDNs */
+ if (next_a || next_b)
{
- if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
return FALSE;
}
- }
- /* both DNs must have same number of RDNs */
- if (next_a || next_b)
- return FALSE;
- /* the two DNs match! */
- return TRUE;
+ /* the two DNs match! */
+ return TRUE;
}
-/*
- * compare two X.509 certificates by comparing their signatures
+/**
+ * Compare two X.509 certificates by comparing their signatures
*/
-bool
-same_x509cert(const x509cert_t *a, const x509cert_t *b)
+bool same_x509cert(const x509cert_t *a, const x509cert_t *b)
{
- return same_chunk(a->signature, b->signature);
+ return chunk_equals(a->signature, b->signature);
}
-/* for each link pointing to the certificate
- " increase the count by one
+/**
+ * For each link pointing to the certificate increase the count by one
*/
-void
-share_x509cert(x509cert_t *cert)
+void share_x509cert(x509cert_t *cert)
{
- if (cert != NULL)
- cert->count++;
+ if (cert != NULL)
+ {
+ cert->count++;
+ }
}
-/*
- * add a X.509 user/host certificate to the chained list
+/**
+ * Add a X.509 user/host certificate to the chained list
*/
-x509cert_t*
-add_x509cert(x509cert_t *cert)
+x509cert_t* add_x509cert(x509cert_t *cert)
{
- x509cert_t *c = x509certs;
+ x509cert_t *c = x509certs;
- while (c != NULL)
- {
- if (same_x509cert(c, cert)) /* already in chain, free cert */
+ while (c != NULL)
{
- free_x509cert(cert);
- return c;
+ if (same_x509cert(c, cert)) /* already in chain, free cert */
+ {
+ free_x509cert(cert);
+ return c;
+ }
+ c = c->next;
}
- c = c->next;
- }
- /* insert new cert at the root of the chain */
- lock_certs_and_keys("add_x509cert");
- cert->next = x509certs;
- x509certs = cert;
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log(" x509 cert inserted")
- )
- unlock_certs_and_keys("add_x509cert");
- return cert;
+ /* insert new cert at the root of the chain */
+ lock_certs_and_keys("add_x509cert");
+ cert->next = x509certs;
+ x509certs = cert;
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log(" x509 cert inserted")
+ )
+ unlock_certs_and_keys("add_x509cert");
+ return cert;
}
-/*
- * choose either subject DN or a subjectAltName as connection end ID
+/**
+ * Choose either subject DN or a subjectAltName as connection end ID
*/
-void
-select_x509cert_id(x509cert_t *cert, struct id *end_id)
+void select_x509cert_id(x509cert_t *cert, struct id *end_id)
{
- bool copy_subject_dn = TRUE; /* ID is subject DN */
+ bool copy_subject_dn = TRUE; /* ID is subject DN */
- if (end_id->kind != ID_NONE) /* check for matching subjectAltName */
- {
- generalName_t *gn = cert->subjectAltName;
-
- while (gn != NULL)
+ if (end_id->kind != ID_ANY) /* check for matching subjectAltName */
{
- struct id id = empty_id;
+ generalName_t *gn = cert->subjectAltName;
- gntoid(&id, gn);
- if (same_id(&id, end_id))
- {
- copy_subject_dn = FALSE; /* take subjectAltName instead */
- break;
- }
- gn = gn->next;
+ while (gn != NULL)
+ {
+ struct id id = empty_id;
+
+ gntoid(&id, gn);
+ if (same_id(&id, end_id))
+ {
+ copy_subject_dn = FALSE; /* take subjectAltName instead */
+ break;
+ }
+ gn = gn->next;
+ }
}
- }
- if (copy_subject_dn)
- {
- if (end_id->kind != ID_NONE && end_id->kind != ID_DER_ASN1_DN)
+ if (copy_subject_dn)
{
- char buf[BUF_LEN];
+ if (end_id->kind != ID_ANY && end_id->kind != ID_DER_ASN1_DN)
+ {
+ char buf[BUF_LEN];
- idtoa(end_id, buf, BUF_LEN);
- plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf);
+ idtoa(end_id, buf, BUF_LEN);
+ plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf);
+ }
+ end_id->kind = ID_DER_ASN1_DN;
+ end_id->name.len = cert->subject.len;
+ end_id->name.ptr = temporary_cyclic_buffer();
+ memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);
}
- end_id->kind = ID_DER_ASN1_DN;
- end_id->name.len = cert->subject.len;
- end_id->name.ptr = temporary_cyclic_buffer();
- memcpy(end_id->name.ptr, cert->subject.ptr, cert->subject.len);
- }
}
-/*
- * check for equality between two key identifiers
+/**
+ * Check for equality between two key identifiers
*/
-bool
-same_keyid(chunk_t a, chunk_t b)
+bool same_keyid(chunk_t a, chunk_t b)
{
- if (a.ptr == NULL || b.ptr == NULL)
- return FALSE;
-
- return same_chunk(a, b);
+ if (a.ptr == NULL || b.ptr == NULL)
+ {
+ return FALSE;
+ }
+ return chunk_equals(a, b);
}
-/*
- * check for equality between two serial numbers
+/**
+ * Check for equality between two serial numbers
*/
-bool
-same_serial(chunk_t a, chunk_t b)
+bool same_serial(chunk_t a, chunk_t b)
{
- /* do not compare serial numbers if one of them is not defined */
- if (a.ptr == NULL || b.ptr == NULL)
- return TRUE;
-
- return same_chunk(a, b);
+ /* do not compare serial numbers if one of them is not defined */
+ if (a.ptr == NULL || b.ptr == NULL)
+ {
+ return TRUE;
+ }
+ return chunk_equals(a, b);
}
-/*
- * get a X.509 certificate with a given issuer found at a certain position
+/**
+ * Get a X.509 certificate with a given issuer found at a certain position
*/
-x509cert_t*
-get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid, x509cert_t *chain)
+x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
+ x509cert_t *chain)
{
- x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
+ x509cert_t *cert = (chain != NULL)? chain->next : x509certs;
- while (cert != NULL)
- {
- if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)
- : (same_dn(issuer, cert->issuer)
- && same_serial(serial, cert->authKeySerialNumber)))
+ while (cert != NULL)
{
- return cert;
+ if ((keyid.ptr != NULL) ? same_keyid(keyid, cert->authKeyID)
+ : (same_dn(issuer, cert->issuer)
+ && same_serial(serial, cert->authKeySerialNumber)))
+ {
+ return cert;
+ }
+ cert = cert->next;
}
- cert = cert->next;
- }
- return NULL;
+ return NULL;
}
-/*
- * encode a linked list of subjectAltNames
+/**
+ * Encode a linked list of subjectAltNames
*/
-chunk_t
-build_subjectAltNames(generalName_t *subjectAltNames)
+chunk_t build_subjectAltNames(generalName_t *subjectAltNames)
{
- u_char *pos;
- chunk_t names;
- size_t len = 0;
- generalName_t *gn = subjectAltNames;
-
+ u_char *pos;
+ chunk_t names;
+ size_t len = 0;
+ generalName_t *gn = subjectAltNames;
+
/* compute the total size of the ASN.1 attributes object */
- while (gn != NULL)
- {
- len += gn->name.len;
- gn = gn->next;
- }
+ while (gn != NULL)
+ {
+ len += gn->name.len;
+ gn = gn->next;
+ }
- pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
+ pos = asn1_build_object(&names, ASN1_SEQUENCE, len);
- gn = subjectAltNames;
- while (gn != NULL)
- {
- chunkcpy(pos, gn->name);
- gn = gn->next;
- }
+ gn = subjectAltNames;
+ while (gn != NULL)
+ {
+ chunkcpy(pos, gn->name);
+ gn = gn->next;
+ }
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_subjectAltName_oid
- , asn1_wrap(ASN1_OCTET_STRING, "m", names));
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_subjectAltName_oid
+ , asn1_wrap(ASN1_OCTET_STRING, "m", names));
}
-/*
- * build a to-be-signed X.509 certificate body
+/**
+ * Build a to-be-signed X.509 certificate body
*/
-static chunk_t
-build_tbs_x509cert(x509cert_t *cert, const RSA_public_key_t *rsa)
+static chunk_t build_tbs_x509cert(x509cert_t *cert, public_key_t *rsa)
{
- /* version is always X.509v3 */
- chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
+ /* version is always X.509v3 */
+ chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
- chunk_t extensions = empty_chunk;
+ chunk_t extensions = chunk_empty;
- if (cert->subjectAltName != NULL)
- {
- extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m"
- , asn1_wrap(ASN1_SEQUENCE, "m"
- , build_subjectAltNames(cert->subjectAltName)));
- }
+ chunk_t key = rsa->get_encoding(rsa);
- return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm"
- , version
- , asn1_simple_object(ASN1_INTEGER, cert->serialNumber)
- , asn1_algorithmIdentifier(cert->sigAlg)
- , cert->issuer
- , asn1_wrap(ASN1_SEQUENCE, "mm"
- , timetoasn1(&cert->notBefore, ASN1_UTCTIME)
- , timetoasn1(&cert->notAfter, ASN1_UTCTIME)
- )
- , cert->subject
- , pkcs1_build_publicKeyInfo(rsa)
- , extensions
- );
+ chunk_t keyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", key));
+
+ if (cert->subjectAltName != NULL)
+ {
+ extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m"
+ , asn1_wrap(ASN1_SEQUENCE, "m"
+ , build_subjectAltNames(cert->subjectAltName)));
+ }
+
+ return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm"
+ , version
+ , asn1_integer("c", cert->serialNumber)
+ , asn1_algorithmIdentifier(cert->sigAlg)
+ , cert->issuer
+ , asn1_wrap(ASN1_SEQUENCE, "mm"
+ , asn1_from_time(&cert->notBefore, ASN1_UTCTIME)
+ , asn1_from_time(&cert->notAfter, ASN1_UTCTIME)
+ )
+ , cert->subject
+ , keyInfo
+ , extensions
+ );
}
-/*
- * build a DER-encoded X.509 certificate
+/**
+ * Build a DER-encoded X.509 certificate
*/
-void
-build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
-, const RSA_private_key_t *signer_key)
+void build_x509cert(x509cert_t *cert, public_key_t *cert_key,
+ private_key_t *signer_key)
{
- chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
+ chunk_t tbs_cert = build_tbs_x509cert(cert, cert_key);
- chunk_t signature = pkcs1_build_signature(tbs_cert, cert->sigAlg
- , signer_key, TRUE);
+ chunk_t signature = x509_build_signature(tbs_cert, cert->sigAlg
+ , signer_key, TRUE);
- cert->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm"
- , tbs_cert
- , asn1_algorithmIdentifier(cert->sigAlg)
- , signature);
+ cert->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm"
+ , tbs_cert
+ , asn1_algorithmIdentifier(cert->sigAlg)
+ , signature);
}
-/*
- * free the dynamic memory used to store generalNames
+/**
+ * Free the dynamic memory used to store generalNames
*/
-void
-free_generalNames(generalName_t* gn, bool free_name)
+void free_generalNames(generalName_t* gn, bool free_name)
{
- while (gn != NULL)
- {
- generalName_t *gn_top = gn;
- if (free_name)
+ while (gn != NULL)
{
- pfree(gn->name.ptr);
+ generalName_t *gn_top = gn;
+ if (free_name)
+ {
+ free(gn->name.ptr);
+ }
+ gn = gn->next;
+ free(gn_top);
}
- gn = gn->next;
- pfree(gn_top);
- }
}
-/*
- * free a X.509 certificate
+/**
+ * Free a X.509 certificate
*/
-void
-free_x509cert(x509cert_t *cert)
+void free_x509cert(x509cert_t *cert)
{
- if (cert != NULL)
- {
- free_generalNames(cert->subjectAltName, FALSE);
- free_generalNames(cert->crlDistributionPoints, FALSE);
- pfreeany(cert->certificate.ptr);
- pfree(cert);
- cert = NULL;
- }
+ if (cert != NULL)
+ {
+ DESTROY_IF(cert->public_key);
+ free_generalNames(cert->subjectAltName, FALSE);
+ free_generalNames(cert->crlDistributionPoints, FALSE);
+ free(cert->certificate.ptr);
+ free(cert);
+ cert = NULL;
+ }
}
-/* release of a certificate decreases the count by one
- " the certificate is freed when the counter reaches zero
+/**
+ * Release of a certificate decreases the count by one
+ * the certificate is freed when the counter reaches zero
*/
-void
-release_x509cert(x509cert_t *cert)
+void release_x509cert(x509cert_t *cert)
{
- if (cert != NULL && --cert->count == 0)
- {
- x509cert_t **pp = &x509certs;
- while (*pp != cert)
- pp = &(*pp)->next;
- *pp = cert->next;
- free_x509cert(cert);
- }
+ if (cert != NULL && --cert->count == 0)
+ {
+ x509cert_t **pp = &x509certs;
+ while (*pp != cert)
+ {
+ pp = &(*pp)->next;
+ }
+ *pp = cert->next;
+ free_x509cert(cert);
+ }
}
-
-/*
- * stores a chained list of end certs and CA certs
+/**
+ * Stores a chained list of end certs and CA certs
*/
-void
-store_x509certs(x509cert_t **firstcert, bool strict)
+void store_x509certs(x509cert_t **firstcert, bool strict)
{
- x509cert_t *cacerts = NULL;
- x509cert_t **pp = firstcert;
+ x509cert_t *cacerts = NULL;
+ x509cert_t **pp = firstcert;
- /* first extract CA certs, discarding root CA certs */
+ /* first extract CA certs, discarding root CA certs */
- while (*pp != NULL)
- {
- x509cert_t *cert = *pp;
-
- if (cert->isCA)
+ while (*pp != NULL)
{
- *pp = cert->next;
-
- /* we don't accept self-signed CA certs */
- if (same_dn(cert->issuer, cert->subject))
- {
- plog("self-signed cacert rejected");
- free_x509cert(cert);
- }
- else
- {
- /* insertion into temporary chain of candidate CA certs */
- cert->next = cacerts;
- cacerts = cert;
- }
+ x509cert_t *cert = *pp;
+
+ if (cert->isCA)
+ {
+ *pp = cert->next;
+
+ /* we don't accept self-signed CA certs */
+ if (same_dn(cert->issuer, cert->subject))
+ {
+ plog("self-signed cacert rejected");
+ free_x509cert(cert);
+ }
+ else
+ {
+ /* insertion into temporary chain of candidate CA certs */
+ cert->next = cacerts;
+ cacerts = cert;
+ }
+ }
+ else
+ {
+ pp = &cert->next;
+ }
}
- else
- pp = &cert->next;
- }
- /* now verify the candidate CA certs */
-
- while (cacerts != NULL)
- {
- x509cert_t *cert = cacerts;
+ /* now verify the candidate CA certs */
- cacerts = cacerts->next;
-
- if (trust_authcert_candidate(cert, cacerts))
- {
- add_authcert(cert, AUTH_CA);
- }
- else
+ while (cacerts != NULL)
{
- plog("intermediate cacert rejected");
- free_x509cert(cert);
- }
- }
-
- /* now verify the end certificates */
+ x509cert_t *cert = cacerts;
+
+ cacerts = cacerts->next;
- pp = firstcert;
+ if (trust_authcert_candidate(cert, cacerts))
+ {
+ add_authcert(cert, AUTH_CA);
+ }
+ else
+ {
+ plog("intermediate cacert rejected");
+ free_x509cert(cert);
+ }
+ }
+
+ /* now verify the end certificates */
- while (*pp != NULL)
- {
- time_t valid_until;
- x509cert_t *cert = *pp;
+ pp = firstcert;
- if (verify_x509cert(cert, strict, &valid_until))
+ while (*pp != NULL)
{
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("public key validated")
- )
- add_x509_public_key(cert, valid_until, DAL_SIGNED);
- }
- else
- {
- plog("X.509 certificate rejected");
+ time_t valid_until;
+ x509cert_t *cert = *pp;
+
+ if (verify_x509cert(cert, strict, &valid_until))
+ {
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log("public key validated")
+ )
+ add_x509_public_key(cert, valid_until, DAL_SIGNED);
+ }
+ else
+ {
+ plog("X.509 certificate rejected");
+ }
+ *pp = cert->next;
+ free_x509cert(cert);
}
- *pp = cert->next;
- free_x509cert(cert);
- }
}
-/*
- * decrypts an RSA signature using the issuer's certificate
+/**
+ * Check if a signature over binary blob is genuine
*/
-static bool
-decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
- chunk_t *digest)
+bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
+ const x509cert_t *issuer_cert)
{
- switch (alg)
- {
- chunk_t decrypted;
-
- case OID_RSA_ENCRYPTION:
- case OID_MD2_WITH_RSA:
- case OID_MD5_WITH_RSA:
- case OID_SHA1_WITH_RSA:
- case OID_SHA1_WITH_RSA_OIW:
- case OID_SHA256_WITH_RSA:
- case OID_SHA384_WITH_RSA:
- case OID_SHA512_WITH_RSA:
+ public_key_t *key = issuer_cert->public_key;
+ signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
+
+ if (scheme == SIGN_UNKNOWN)
{
- mpz_t s;
- RSA_public_key_t rsa;
-
- init_RSA_public_key(&rsa, issuer_cert->publicExponent
- , issuer_cert->modulus);
-
- /* decrypt the signature s = s^e mod n */
- n_to_mpz(s, sig.ptr, sig.len);
- mpz_powm(s, s, &rsa.e, &rsa.n);
-
- /* convert back to bytes */
- decrypted = mpz_to_n(s, rsa.k);
- DBG(DBG_PARSING,
- DBG_dump_chunk(" decrypted signature: ", decrypted)
- )
-
- /* copy the least significant bits of decrypted signature
- * into the digest string
- */
- memcpy(digest->ptr, decrypted.ptr + decrypted.len - digest->len,
- digest->len);
-
- /* free memory */
- free_RSA_public_content(&rsa);
- pfree(decrypted.ptr);
- mpz_clear(s);
- return TRUE;
+ return FALSE;
}
- default:
- digest->len = 0;
- return FALSE;
- }
+ return key->verify(key, scheme, tbs, sig);
}
-/*
- * Check if a signature over binary blob is genuine
+/**
+ * Build an ASN.1 encoded PKCS#1 signature over a binary blob
*/
-bool
-check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
-, const x509cert_t *issuer_cert)
+chunk_t x509_build_signature(chunk_t tbs, int algorithm, private_key_t *key,
+ bool bit_string)
{
- u_char digest_buf[MAX_DIGEST_LEN];
- u_char decrypted_buf[MAX_DIGEST_LEN];
- chunk_t digest = {digest_buf, MAX_DIGEST_LEN};
- chunk_t decrypted = {decrypted_buf, MAX_DIGEST_LEN};
-
- DBG(DBG_PARSING,
- if (digest_alg != OID_UNKNOWN)
- DBG_log("signature digest algorithm: '%s'",oid_names[digest_alg].name);
- else
- DBG_log("unknown signature digest algorithm");
- )
+ chunk_t signature;
+ signature_scheme_t scheme = signature_scheme_from_oid(algorithm);
- if (!compute_digest(tbs, digest_alg, &digest))
- {
- plog(" digest algorithm not supported");
- return FALSE;
- }
-
- DBG(DBG_PARSING,
- DBG_dump_chunk(" digest:", digest)
- )
-
- decrypted.len = digest.len; /* we want the same digest length */
-
- DBG(DBG_PARSING,
- if (enc_alg != OID_UNKNOWN)
- DBG_log("signature encryption algorithm: '%s'",oid_names[enc_alg].name);
- else
- DBG_log("unknown signature encryption algorithm");
- )
-
- if (!decrypt_sig(sig, enc_alg, issuer_cert, &decrypted))
- {
- plog(" decryption algorithm not supported");
- return FALSE;
- }
-
- /* check if digests are equal */
- return !memcmp(decrypted.ptr, digest.ptr, digest.len);
+ if (scheme == SIGN_UNKNOWN || !key->sign(key, scheme, tbs, &signature))
+ {
+ return chunk_empty;
+ }
+ return (bit_string) ? asn1_bitstring("m", signature)
+ : asn1_wrap(ASN1_OCTET_STRING, "m", signature);
}
-/*
- * extracts the basicConstraints extension
+/**
+ * Extracts the basicConstraints extension
*/
-static bool
-parse_basicConstraints(chunk_t blob, int level0)
+static bool parse_basicConstraints(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- bool isCA = FALSE;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < BASIC_CONSTRAINTS_ROOF) {
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool isCA = FALSE;
- if (!extract_object(basicConstraintsObjects, &objectID,
- &object,&level, &ctx))
- break;
+ parser = asn1_parser_create(basicConstraintsObjects, blob);
+ parser->set_top_level(parser, level0);
- if (objectID == BASIC_CONSTRAINTS_CA)
+ while (parser->iterate(parser, &objectID, &object))
{
- isCA = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(isCA)?"TRUE":"FALSE");
- )
+ if (objectID == BASIC_CONSTRAINTS_CA)
+ {
+ isCA = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(isCA)?"TRUE":"FALSE");
+ )
+ }
}
- objectID++;
- }
- return isCA;
+ parser->destroy(parser);
+
+ return isCA;
}
-/*
+/**
* Converts a X.500 generalName into an ID
*/
-void
-gntoid(struct id *id, const generalName_t *gn)
+void gntoid(struct id *id, const generalName_t *gn)
{
- switch(gn->kind)
- {
- case GN_DNS_NAME: /* ID type: ID_FQDN */
- id->kind = ID_FQDN;
- id->name = gn->name;
- break;
- case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
+ switch(gn->kind)
{
- const struct af_info *afi = &af_inet4_info;
- err_t ugh = NULL;
+ case GN_DNS_NAME: /* ID type: ID_FQDN */
+ id->kind = ID_FQDN;
+ id->name = gn->name;
+ break;
+ case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
+ {
+ const struct af_info *afi = &af_inet4_info;
+ err_t ugh = NULL;
- id->kind = afi->id_addr;
- ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
+ id->kind = afi->id_addr;
+ ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
+ }
+ break;
+ case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
+ id->kind = ID_USER_FQDN;
+ id->name = gn->name;
+ break;
+ default:
+ id->kind = ID_ANY;
+ id->name = chunk_empty;
}
- break;
- case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
- id->kind = ID_USER_FQDN;
- id->name = gn->name;
- break;
- default:
- id->kind = ID_NONE;
- id->name = empty_chunk;
- }
}
-/* compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
+/**
+ * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
* as the 160 bit SHA-1 hash of the public key
*/
-void
-compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
+bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID)
{
- SHA1_CTX context;
-
- SHA1Init(&context);
- SHA1Update(&context
- , cert->subjectPublicKey.ptr
- , cert->subjectPublicKey.len);
- SHA1Final(subjectKeyID.ptr, &context);
- subjectKeyID.len = SHA1_DIGEST_SIZE;
+ identification_t *keyid;
+ chunk_t encoding;
+
+ keyid = cert->public_key->get_id(cert->public_key, ID_PUBKEY_SHA1);
+ if (keyid == NULL)
+ {
+ plog(" unable to compute subjectKeyID");
+ return FALSE;
+ }
+ encoding = keyid->get_encoding(keyid);
+ memcpy(subjectKeyID.ptr, encoding.ptr, subjectKeyID.len);
+ return TRUE;
}
-/*
- * extracts an otherName
+/**
+ * Extracts an otherName
*/
-static bool
-parse_otherName(chunk_t blob, int level0)
+static bool parse_otherName(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
- int oid = OID_UNKNOWN;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int oid = OID_UNKNOWN;
+ bool success = FALSE;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < ON_OBJ_ROOF)
- {
- if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
- return FALSE;
+ parser = asn1_parser_create(otherNameObjects, blob);
+ parser->set_top_level(parser, level0);
- switch (objectID)
+ while (parser->iterate(parser, &objectID, &object))
{
- case ON_OBJ_ID_TYPE:
- oid = known_oid(object);
- break;
- case ON_OBJ_VALUE:
- if (oid == OID_XMPP_ADDR)
- {
- if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING
- , level + 1, "xmppAddr"))
+ switch (objectID)
{
- return FALSE;
+ case ON_OBJ_ID_TYPE:
+ oid = asn1_known_oid(object);
+ break;
+ case ON_OBJ_VALUE:
+ if (oid == OID_XMPP_ADDR)
+ {
+ if (!asn1_parse_simple_object(&object, ASN1_UTF8STRING,
+ parser->get_level(parser) + 1, "xmppAddr"))
+ {
+ goto end;
+ }
+ }
+ break;
+ default:
+ break;
}
- }
- break;
- default:
- break;
}
- objectID++;
- }
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
-/*
- * extracts a generalName
+/**
+ * Extracts a generalName
*/
-static generalName_t*
-parse_generalName(chunk_t blob, int level0)
+static generalName_t* parse_generalName(chunk_t blob, int level0)
{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ u_char buf[BUF_LEN];
+ asn1_parser_t *parser;
+ chunk_t object;
+ generalName_t *gn = NULL;
+ int objectID;
- while (objectID < GN_OBJ_ROOF)
- {
- bool valid_gn = FALSE;
+ parser = asn1_parser_create(generalNameObjects, blob);
+ parser->set_top_level(parser, level0);
- if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- switch (objectID) {
- case GN_OBJ_RFC822_NAME:
- case GN_OBJ_DNS_NAME:
- case GN_OBJ_URI:
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'", (int)object.len, object.ptr);
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_DIRECTORY_NAME:
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'", buf)
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_IP_ADDRESS:
- DBG(DBG_PARSING,
- DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
- *(object.ptr+2), *(object.ptr+3));
- )
- valid_gn = TRUE;
- break;
- case GN_OBJ_OTHER_NAME:
- if (!parse_otherName(object, level + 1))
- return NULL;
- break;
- case GN_OBJ_X400_ADDRESS:
- case GN_OBJ_EDI_PARTY_NAME:
- case GN_OBJ_REGISTERED_ID:
- break;
- default:
- break;
- }
-
- if (valid_gn)
+ while (parser->iterate(parser, &objectID, &object))
{
- generalName_t *gn = alloc_thing(generalName_t, "generalName");
- gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
- gn->name = object;
- gn->next = NULL;
- return gn;
- }
- objectID++;
- }
- return NULL;
-}
-
-
-/*
- * extracts one or several GNs and puts them into a chained list
- */
-static generalName_t*
-parse_generalNames(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- generalName_t *top_gn = NULL;
-
- asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
+ bool valid_gn = FALSE;
+
+ switch (objectID) {
+ case GN_OBJ_RFC822_NAME:
+ case GN_OBJ_DNS_NAME:
+ case GN_OBJ_URI:
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'", (int)object.len, object.ptr);
+ )
+ valid_gn = TRUE;
+ break;
+ case GN_OBJ_DIRECTORY_NAME:
+ DBG(DBG_PARSING,
+ dntoa(buf, BUF_LEN, object);
+ DBG_log(" '%s'", buf)
+ )
+ valid_gn = TRUE;
+ break;
+ case GN_OBJ_IP_ADDRESS:
+ DBG(DBG_PARSING,
+ DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
+ *(object.ptr+2), *(object.ptr+3));
+ )
+ valid_gn = TRUE;
+ break;
+ case GN_OBJ_OTHER_NAME:
+ if (!parse_otherName(object, parser->get_level(parser)+1))
+ {
+ goto end;
+ }
+ break;
+ case GN_OBJ_X400_ADDRESS:
+ case GN_OBJ_EDI_PARTY_NAME:
+ case GN_OBJ_REGISTERED_ID:
+ break;
+ default:
+ break;
+ }
- while (objectID < GENERAL_NAMES_ROOF)
- {
- if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- if (objectID == GENERAL_NAMES_GN)
- {
- generalName_t *gn = parse_generalName(object, level+1);
- if (gn != NULL)
- {
- gn->next = top_gn;
- top_gn = gn;
- }
+ if (valid_gn)
+ {
+ gn = malloc_thing(generalName_t);
+ gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
+ gn->name = object;
+ gn->next = NULL;
+ goto end;
+ }
}
- objectID++;
- }
- return top_gn;
+
+end:
+ parser->destroy(parser);
+ return gn;
}
-/*
- * returns a directoryName
+/**
+ * Extracts one or several GNs and puts them into a chained list
*/
-chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
+static generalName_t* parse_generalNames(chunk_t blob, int level0, bool implicit)
{
- chunk_t name = empty_chunk;
- generalName_t * gn = parse_generalNames(blob, level, implicit);
-
- if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
- name= gn->name;
-
- free_generalNames(gn, FALSE);
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ generalName_t *top_gn = NULL;
+
+ parser = asn1_parser_create(generalNamesObjects, blob);
+ parser->set_top_level(parser, level0);
+ parser->set_flags(parser, implicit, FALSE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == GENERAL_NAMES_GN)
+ {
+ generalName_t *gn = parse_generalName(object,
+ parser->get_level(parser)+1);
+ if (gn)
+ {
+ gn->next = top_gn;
+ top_gn = gn;
+ }
+ }
+ }
+ parser->destroy(parser);
- return name;
+ return top_gn;
}
-/*
- * extracts and converts a UTCTIME or GENERALIZEDTIME object
+/**
+ * Returns a directoryName
*/
-time_t
-parse_time(chunk_t blob, int level0)
+chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ chunk_t name = chunk_empty;
+ generalName_t * gn = parse_generalNames(blob, level, implicit);
- while (objectID < TIME_ROOF)
- {
- if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
- return UNDEFINED_TIME;
-
- if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
+ if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
{
- return asn1totime(&object, (objectID == TIME_UTC)
- ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
+ name= gn->name;
}
- objectID++;
- }
- return UNDEFINED_TIME;
- }
-
-/*
- * extracts a keyIdentifier
- */
-static chunk_t
-parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
-
- extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
- return object;
+ free_generalNames(gn, FALSE);
+ return name;
}
-/*
- * extracts an authoritykeyIdentifier
+/**
+ * Extracts an authoritykeyIdentifier
*/
-void
-parse_authorityKeyIdentifier(chunk_t blob, int level0
- , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
+void parse_authorityKeyIdentifier(chunk_t blob, int level0,
+ chunk_t *authKeyID,
+ chunk_t *authKeySerialNumber)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(authKeyIdentifierObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case AUTH_KEY_ID_KEY_ID:
+ *authKeyID = object;
+ break;
+ case AUTH_KEY_ID_CERT_ISSUER:
+ {
+ generalName_t * gn = parse_generalNames(object,
+ parser->get_level(parser) + 1, TRUE);
- while (objectID < AUTH_KEY_ID_ROOF)
- {
- if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- case AUTH_KEY_ID_KEY_ID:
- *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
- break;
- case AUTH_KEY_ID_CERT_ISSUER:
- {
- generalName_t * gn = parse_generalNames(object, level+1, TRUE);
-
- free_generalNames(gn, FALSE);
- }
- break;
- case AUTH_KEY_ID_CERT_SERIAL:
- *authKeySerialNumber = object;
- break;
- default:
- break;
+ free_generalNames(gn, FALSE);
+ }
+ break;
+ case AUTH_KEY_ID_CERT_SERIAL:
+ *authKeySerialNumber = object;
+ break;
+ default:
+ break;
+ }
}
- objectID++;
- }
+ parser->destroy(parser);
}
-/*
- * extracts an authorityInfoAcess location
+/**
+ * Extracts an authorityInfoAcess location
*/
-static void
-parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
+static void parse_authorityInfoAccess(chunk_t blob, int level0,
+ chunk_t *accessLocation)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int accessMethod = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int accessMethod = OID_UNKNOWN;
- while (objectID < AUTH_INFO_ACCESS_ROOF)
- {
- if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
- return;
-
- switch (objectID) {
- case AUTH_INFO_ACCESS_METHOD:
- accessMethod = known_oid(object);
- break;
- case AUTH_INFO_ACCESS_LOCATION:
- {
- switch (accessMethod)
+ parser = asn1_parser_create(authInfoAccessObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
{
- case OID_OCSP:
- if (*object.ptr == ASN1_CONTEXT_S_6)
- {
- if (asn1_length(&object) == ASN1_INVALID_LENGTH)
- return;
-
- DBG(DBG_PARSING,
- DBG_log(" '%.*s'",(int)object.len, object.ptr)
- )
-
- /* only HTTP(S) URIs accepted */
- if (strncasecmp(object.ptr, "http", 4) == 0)
+ case AUTH_INFO_ACCESS_METHOD:
+ accessMethod = asn1_known_oid(object);
+ break;
+ case AUTH_INFO_ACCESS_LOCATION:
{
- *accessLocation = object;
- return;
+ switch (accessMethod)
+ {
+ case OID_OCSP:
+ if (*object.ptr == ASN1_CONTEXT_S_6)
+ {
+ if (asn1_length(&object) == ASN1_INVALID_LENGTH)
+ {
+ goto end;
+ }
+ DBG(DBG_PARSING,
+ DBG_log(" '%.*s'",(int)object.len, object.ptr)
+ )
+
+ /* only HTTP(S) URIs accepted */
+ if (strncasecmp(object.ptr, "http", 4) == 0)
+ {
+ *accessLocation = object;
+ goto end;
+ }
+ }
+ plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
+ break;
+ default:
+ /* unkown accessMethod, ignoring */
+ break;
+ }
}
- }
- plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
- break;
+ break;
default:
- /* unkown accessMethod, ignoring */
- break;
+ break;
}
- }
- break;
- default:
- break;
}
- objectID++;
- }
-
+
+end:
+ parser->destroy(parser);
}
-/*
- * extracts extendedKeyUsage OIDs
+/**
+ * Extracts extendedKeyUsage OIDs
*/
-static bool
-parse_extendedKeyUsage(chunk_t blob, int level0)
+static bool parse_extendedKeyUsage(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool ocsp_signing = FALSE;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(extendedKeyUsageObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == EXT_KEY_USAGE_PURPOSE_ID
+ && asn1_known_oid(object) == OID_OCSP_SIGNING)
+ {
+ ocsp_signing = TRUE;
+ }
+ }
+ parser->destroy(parser);
- while (objectID < EXT_KEY_USAGE_ROOF)
- {
- if (!extract_object(extendedKeyUsageObjects, &objectID
- , &object, &level, &ctx))
- return FALSE;
-
- if (objectID == EXT_KEY_USAGE_PURPOSE_ID
- && known_oid(object) == OID_OCSP_SIGNING)
- return TRUE;
- objectID++;
- }
- return FALSE;
+ return ocsp_signing;
}
-/* extracts one or several crlDistributionPoints and puts them into
- * a chained list
+/**
+ * Extracts one or several crlDistributionPoints
+ * and puts them into a chained list
*/
-static generalName_t*
-parse_crlDistributionPoints(chunk_t blob, int level0)
+static generalName_t* parse_crlDistributionPoints(chunk_t blob, int level0)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
- generalName_t *top_gn = NULL; /* top of the chained list */
- generalName_t **tail_gn = &top_gn; /* tail of the chained list */
+ generalName_t *top_gn = NULL; /* top of the chained list */
+ generalName_t **tail_gn = &top_gn; /* tail of the chained list */
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < CRL_DIST_POINTS_ROOF)
- {
- if (!extract_object(crlDistributionPointsObjects, &objectID,
- &object, &level, &ctx))
- return NULL;
-
- if (objectID == CRL_DIST_POINTS_FULLNAME)
+ parser = asn1_parser_create(crlDistributionPointsObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
{
- generalName_t *gn = parse_generalNames(object, level+1, TRUE);
- /* append extracted generalNames to existing chained list */
- *tail_gn = gn;
- /* find new tail of the chained list */
- while (gn != NULL)
- {
- tail_gn = &gn->next; gn = gn->next;
- }
+ if (objectID == CRL_DIST_POINTS_FULLNAME)
+ {
+ generalName_t *gn;
+
+ gn = parse_generalNames(object, parser->get_level(parser)+1, TRUE);
+ /* append extracted generalNames to existing chained list */
+ *tail_gn = gn;
+ /* find new tail of the chained list */
+ while (gn != NULL)
+ {
+ tail_gn = &gn->next; gn = gn->next;
+ }
+ }
}
- objectID++;
- }
- return top_gn;
-}
+ parser->destroy(parser);
+ return top_gn;
+}
-/*
+/**
* Parses an X.509v3 certificate
*/
-bool
-parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
+bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
{
- u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
-
- while (objectID < X509_OBJ_ROOF)
- {
- if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID) {
- case X509_OBJ_CERTIFICATE:
- cert->certificate = object;
- break;
- case X509_OBJ_TBS_CERTIFICATE:
- cert->tbsCertificate = object;
- break;
- case X509_OBJ_VERSION:
- cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG(DBG_PARSING,
- DBG_log(" v%d", cert->version);
- )
- break;
- case X509_OBJ_SERIAL_NUMBER:
- cert->serialNumber = object;
- break;
- case X509_OBJ_SIG_ALG:
- cert->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_ISSUER:
- cert->issuer = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case X509_OBJ_NOT_BEFORE:
- cert->notBefore = parse_time(object, level);
- break;
- case X509_OBJ_NOT_AFTER:
- cert->notAfter = parse_time(object, level);
- break;
- case X509_OBJ_SUBJECT:
- cert->subject = object;
- DBG(DBG_PARSING,
- dntoa(buf, BUF_LEN, object);
- DBG_log(" '%s'",buf)
- )
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
- if (parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
- cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
- else
- {
- plog(" unsupported public key algorithm");
- return FALSE;
- }
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY:
- if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
- {
- /* skip initial bit string octet defining 0 unused bits */
- ctx.blobs[4].ptr++; ctx.blobs[4].len--;
- }
- else
- {
- plog(" invalid RSA public key format");
- return FALSE;
- }
- break;
- case X509_OBJ_RSA_PUBLIC_KEY:
- cert->subjectPublicKey = object;
- break;
- case X509_OBJ_MODULUS:
- if (object.len < RSA_MIN_OCTETS + 1)
- {
- plog(" " RSA_MIN_OCTETS_UGH);
- return FALSE;
- }
- if (object.len > RSA_MAX_OCTETS + (size_t)(*object.ptr == 0x00))
- {
- plog(" " RSA_MAX_OCTETS_UGH);
- return FALSE;
- }
- cert->modulus = object;
- break;
- case X509_OBJ_PUBLIC_EXPONENT:
- cert->publicExponent = object;
- break;
- case X509_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case X509_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG(DBG_PARSING,
- DBG_log(" %s",(critical)?"TRUE":"FALSE");
- )
- break;
- case X509_OBJ_EXTN_VALUE:
- {
- switch (extn_oid) {
- case OID_SUBJECT_KEY_ID:
- cert->subjectKeyID =
- parse_keyIdentifier(object, level, FALSE);
- break;
- case OID_SUBJECT_ALT_NAME:
- cert->subjectAltName =
- parse_generalNames(object, level, FALSE);
- break;
- case OID_BASIC_CONSTRAINTS:
- cert->isCA =
- parse_basicConstraints(object, level);
- break;
- case OID_CRL_DISTRIBUTION_POINTS:
- cert->crlDistributionPoints =
- parse_crlDistributionPoints(object, level);
- break;
- case OID_AUTHORITY_KEY_ID:
- parse_authorityKeyIdentifier(object, level
- , &cert->authKeyID, &cert->authKeySerialNumber);
- break;
- case OID_AUTHORITY_INFO_ACCESS:
- parse_authorityInfoAccess(object, level, &cert->accessLocation);
- break;
- case OID_EXTENDED_KEY_USAGE:
- cert->isOcspSigner = parse_extendedKeyUsage(object, level);
- break;
- case OID_NS_REVOCATION_URL:
- case OID_NS_CA_REVOCATION_URL:
- case OID_NS_CA_POLICY_URL:
- case OID_NS_COMMENT:
- if (!parse_asn1_simple_object(&object, ASN1_IA5STRING
- , level, oid_names[extn_oid].name))
- {
- return FALSE;
- }
- break;
+ u_char buf[BUF_LEN];
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ int extn_oid = OID_UNKNOWN;
+ bool critical;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(certObjects, blob);
+ parser->set_top_level(parser, level0);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ u_int level = parser->get_level(parser) + 1;
+
+ switch (objectID) {
+ case X509_OBJ_CERTIFICATE:
+ cert->certificate = object;
+ break;
+ case X509_OBJ_TBS_CERTIFICATE:
+ cert->tbsCertificate = object;
+ break;
+ case X509_OBJ_VERSION:
+ cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+ DBG(DBG_PARSING,
+ DBG_log(" v%d", cert->version);
+ )
+ break;
+ case X509_OBJ_SERIAL_NUMBER:
+ cert->serialNumber = object;
+ break;
+ case X509_OBJ_SIG_ALG:
+ cert->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case X509_OBJ_ISSUER:
+ cert->issuer = object;
+ DBG(DBG_PARSING,
+ dntoa(buf, BUF_LEN, object);
+ DBG_log(" '%s'",buf)
+ )
+ break;
+ case X509_OBJ_NOT_BEFORE:
+ cert->notBefore = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_NOT_AFTER:
+ cert->notAfter = asn1_parse_time(object, level);
+ break;
+ case X509_OBJ_SUBJECT:
+ cert->subject = object;
+ DBG(DBG_PARSING,
+ dntoa(buf, BUF_LEN, object);
+ DBG_log(" '%s'",buf)
+ )
+ break;
+ case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
+ cert->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
+ KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
+ if (cert->public_key == NULL)
+ {
+ goto end;
+ }
+ break;
+ case X509_OBJ_EXTN_ID:
+ extn_oid = asn1_known_oid(object);
+ break;
+ case X509_OBJ_CRITICAL:
+ critical = object.len && *object.ptr;
+ DBG(DBG_PARSING,
+ DBG_log(" %s",(critical)?"TRUE":"FALSE");
+ )
+ break;
+ case X509_OBJ_EXTN_VALUE:
+ {
+ switch (extn_oid) {
+ case OID_SUBJECT_KEY_ID:
+ if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
+ level, "keyIdentifier"))
+ {
+ goto end;
+ }
+ cert->subjectKeyID = object;
+ break;
+ case OID_SUBJECT_ALT_NAME:
+ cert->subjectAltName =
+ parse_generalNames(object, level, FALSE);
+ break;
+ case OID_BASIC_CONSTRAINTS:
+ cert->isCA =
+ parse_basicConstraints(object, level);
+ break;
+ case OID_CRL_DISTRIBUTION_POINTS:
+ cert->crlDistributionPoints =
+ parse_crlDistributionPoints(object, level);
+ break;
+ case OID_AUTHORITY_KEY_ID:
+ parse_authorityKeyIdentifier(object, level
+ , &cert->authKeyID, &cert->authKeySerialNumber);
+ break;
+ case OID_AUTHORITY_INFO_ACCESS:
+ parse_authorityInfoAccess(object, level, &cert->accessLocation);
+ break;
+ case OID_EXTENDED_KEY_USAGE:
+ cert->isOcspSigner = parse_extendedKeyUsage(object, level);
+ break;
+ case OID_NS_REVOCATION_URL:
+ case OID_NS_CA_REVOCATION_URL:
+ case OID_NS_CA_POLICY_URL:
+ case OID_NS_COMMENT:
+ if (!asn1_parse_simple_object(&object, ASN1_IA5STRING
+ , level, oid_names[extn_oid].name))
+ {
+ goto end;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case X509_OBJ_ALGORITHM:
+ cert->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ break;
+ case X509_OBJ_SIGNATURE:
+ cert->signature = object;
+ break;
default:
- break;
+ break;
}
- }
- break;
- case X509_OBJ_ALGORITHM:
- cert->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_SIGNATURE:
- cert->signature = object;
- break;
- default:
- break;
}
- objectID++;
- }
- time(&cert->installed);
- return TRUE;
+ success = parser->success(parser);
+ time(&cert->installed);
+
+end:
+ parser->destroy(parser);
+ return success;
}
-/* verify the validity of a certificate by
+/**
+ * Verify the validity of a certificate by
* checking the notBefore and notAfter dates
*/
-err_t
-check_validity(const x509cert_t *cert, time_t *until)
+err_t check_validity(const x509cert_t *cert, time_t *until)
{
- time_t current_time;
+ time_t current_time;
- time(&current_time);
- DBG(DBG_CONTROL | DBG_PARSING ,
- DBG_log(" not before : %s", timetoa(&cert->notBefore, TRUE));
- DBG_log(" current time: %s", timetoa(&current_time, TRUE));
- DBG_log(" not after : %s", timetoa(&cert->notAfter, TRUE));
- )
-
- if (cert->notAfter < *until) *until = cert->notAfter;
+ time(&current_time);
+ DBG(DBG_CONTROL | DBG_PARSING ,
+ DBG_log(" not before : %T", &cert->notBefore, TRUE);
+ DBG_log(" current time: %T", &current_time, TRUE);
+ DBG_log(" not after : %T", &cert->notAfter, TRUE);
+ )
- if (current_time < cert->notBefore)
- return "certificate is not valid yet";
- if (current_time > cert->notAfter)
- return "certificate has expired";
- else
- return NULL;
+ if (cert->notAfter < *until)
+ {
+ *until = cert->notAfter;
+ }
+ if (current_time < cert->notBefore)
+ {
+ return "certificate is not valid yet";
+ }
+ if (current_time > cert->notAfter)
+ {
+ return "certificate has expired";
+ }
+ else
+ {
+ return NULL;
+ }
}
-/*
- * verifies a X.509 certificate
+/**
+ * Verifies a X.509 certificate
*/
-bool
-verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
+bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
{
- int pathlen;
+ int pathlen;
- *until = cert->notAfter;
+ *until = cert->notAfter;
- for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
- {
- x509cert_t *issuer_cert;
- u_char buf[BUF_LEN];
- err_t ugh = NULL;
-
- DBG(DBG_CONTROL,
- dntoa(buf, BUF_LEN, cert->subject);
- DBG_log("subject: '%s'",buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- DBG_log("issuer: '%s'",buf);
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- DBG_log("authkey: %s", buf);
- }
- )
+ for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
+ {
+ x509cert_t *issuer_cert;
+ u_char buf[BUF_LEN];
+ err_t ugh = NULL;
- ugh = check_validity(cert, until);
+ DBG(DBG_CONTROL,
+ dntoa(buf, BUF_LEN, cert->subject);
+ DBG_log("subject: '%s'",buf);
+ dntoa(buf, BUF_LEN, cert->issuer);
+ DBG_log("issuer: '%s'",buf);
+ if (cert->authKeyID.ptr != NULL)
+ {
+ datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
+ , buf, BUF_LEN);
+ DBG_log("authkey: %s", buf);
+ }
+ )
- if (ugh != NULL)
- {
- plog("%s", ugh);
- return FALSE;
- }
+ ugh = check_validity(cert, until);
- DBG(DBG_CONTROL,
- DBG_log("certificate is valid")
- )
+ if (ugh != NULL)
+ {
+ plog("%s", ugh);
+ return FALSE;
+ }
- lock_authcert_list("verify_x509cert");
- issuer_cert = get_authcert(cert->issuer, cert->authKeySerialNumber
- , cert->authKeyID, AUTH_CA);
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is valid")
+ )
- if (issuer_cert == NULL)
- {
- plog("issuer cacert not found");
- unlock_authcert_list("verify_x509cert");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("issuer cacert found")
- )
+ lock_authcert_list("verify_x509cert");
+ issuer_cert = get_authcert(cert->issuer, cert->authKeySerialNumber
+ , cert->authKeyID, AUTH_CA);
- if (!check_signature(cert->tbsCertificate, cert->signature
- , cert->algorithm, cert->algorithm, issuer_cert))
- {
- plog("certificate signature is invalid");
- unlock_authcert_list("verify_x509cert");
- return FALSE;
- }
- DBG(DBG_CONTROL,
- DBG_log("certificate signature is valid")
- )
- unlock_authcert_list("verify_x509cert");
+ if (issuer_cert == NULL)
+ {
+ plog("issuer cacert not found");
+ unlock_authcert_list("verify_x509cert");
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("issuer cacert found")
+ )
- /* check if cert is a self-signed root ca */
- if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
- {
- DBG(DBG_CONTROL,
- DBG_log("reached self-signed root ca")
- )
- return TRUE;
- }
- else
- {
- time_t nextUpdate = *until;
- time_t revocationDate = UNDEFINED_TIME;
- crl_reason_t revocationReason = REASON_UNSPECIFIED;
-
- /* first check certificate revocation using ocsp */
- cert_status_t status = verify_by_ocsp(cert, &nextUpdate
- , &revocationDate, &revocationReason);
-
- /* if ocsp service is not available then fall back to crl */
- if ((status == CERT_UNDEFINED)
- || (status == CERT_UNKNOWN && strict))
- {
- status = verify_by_crl(cert, &nextUpdate, &revocationDate
- , &revocationReason);
- }
-
- switch (status)
- {
- case CERT_GOOD:
- /* if status information is stale */
- if (strict && nextUpdate < time(NULL))
+ if (!x509_check_signature(cert->tbsCertificate, cert->signature,
+ cert->algorithm, issuer_cert))
{
- DBG(DBG_CONTROL,
- DBG_log("certificate is good but status is stale")
- )
- remove_x509_public_key(cert);
- return FALSE;
+ plog("certificate signature is invalid");
+ unlock_authcert_list("verify_x509cert");
+ return FALSE;
}
DBG(DBG_CONTROL,
- DBG_log("certificate is good")
+ DBG_log("certificate signature is valid")
)
-
- /* with strict crl policy the public key must have the same
- * lifetime as the validity of the ocsp status or crl lifetime
- */
- if (strict && nextUpdate < *until)
- *until = nextUpdate;
- break;
- case CERT_REVOKED:
- plog("certificate was revoked on %s, reason: %s"
- , timetoa(&revocationDate, TRUE)
- , enum_name(&crl_reason_names, revocationReason));
- remove_x509_public_key(cert);
- return FALSE;
- case CERT_UNKNOWN:
- case CERT_UNDEFINED:
- default:
- plog("certificate status unknown");
- if (strict)
+ unlock_authcert_list("verify_x509cert");
+
+ /* check if cert is a self-signed root ca */
+ if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
{
- remove_x509_public_key(cert);
- return FALSE;
+ DBG(DBG_CONTROL,
+ DBG_log("reached self-signed root ca")
+ )
+ return TRUE;
}
- break;
- }
- }
+ else
+ {
+ time_t nextUpdate = *until;
+ time_t revocationDate = UNDEFINED_TIME;
+ crl_reason_t revocationReason = REASON_UNSPECIFIED;
- /* go up one step in the trust chain */
- cert = issuer_cert;
- }
- plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
- return FALSE;
+ /* first check certificate revocation using ocsp */
+ cert_status_t status = verify_by_ocsp(cert, &nextUpdate
+ , &revocationDate, &revocationReason);
+
+ /* if ocsp service is not available then fall back to crl */
+ if ((status == CERT_UNDEFINED)
+ || (status == CERT_UNKNOWN && strict))
+ {
+ status = verify_by_crl(cert, &nextUpdate, &revocationDate
+ , &revocationReason);
+ }
+
+ switch (status)
+ {
+ case CERT_GOOD:
+ /* if status information is stale */
+ if (strict && nextUpdate < time(NULL))
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is good but status is stale")
+ )
+ remove_x509_public_key(cert);
+ return FALSE;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("certificate is good")
+ )
+
+ /* with strict crl policy the public key must have the same
+ * lifetime as the validity of the ocsp status or crl lifetime
+ */
+ if (strict && nextUpdate < *until)
+ {
+ *until = nextUpdate;
+ }
+ break;
+ case CERT_REVOKED:
+ plog("certificate was revoked on %T, reason: %N"
+ , &revocationDate, TRUE
+ , crl_reason_names, revocationReason);
+ remove_x509_public_key(cert);
+ return FALSE;
+ case CERT_UNKNOWN:
+ case CERT_UNDEFINED:
+ default:
+ plog("certificate status unknown");
+ if (strict)
+ {
+ remove_x509_public_key(cert);
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ /* go up one step in the trust chain */
+ cert = issuer_cert;
+ }
+ plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
+ return FALSE;
}
-/*
- * list all X.509 certs in a chained list
+/**
+ * List all X.509 certs in a chained list
*/
-void
-list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
- , bool utc)
+void list_x509cert_chain(const char *caption, x509cert_t* cert,
+ u_char auth_flags, bool utc)
{
- bool first = TRUE;
- time_t now;
+ bool first = TRUE;
+ time_t now;
- /* determine the current time */
- time(&now);
+ /* determine the current time */
+ time(&now);
- while (cert != NULL)
- {
- if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
+ while (cert != NULL)
{
- unsigned keysize;
- char keyid[KEYID_BUF];
- u_char buf[BUF_LEN];
- cert_t c;
-
- c.type = CERT_X509_SIGNATURE;
- c.u.x509 = cert;
-
- if (first)
- {
- whack_log(RC_COMMENT, " ");
- whack_log(RC_COMMENT, "List of X.509 %s Certificates:", caption);
- whack_log(RC_COMMENT, " ");
- first = FALSE;
- }
-
- whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc),
- cert->count);
- dntoa(buf, BUF_LEN, cert->subject);
- whack_log(RC_COMMENT, " subject: '%s'", buf);
- dntoa(buf, BUF_LEN, cert->issuer);
- whack_log(RC_COMMENT, " issuer: '%s'", buf);
- datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " serial: %s", buf);
- form_keyid(cert->publicExponent, cert->modulus, keyid, &keysize);
- whack_log(RC_COMMENT, " pubkey: %4d RSA Key %s%s"
- , 8*keysize, keyid
- , cert->smartcard ? ", on smartcard" :
- (has_private_key(c)? ", has private key" : ""));
- whack_log(RC_COMMENT, " validity: not before %s %s",
- timetoa(&cert->notBefore, utc),
- (cert->notBefore < now)?"ok":"fatal (not valid yet)");
- whack_log(RC_COMMENT, " not after %s %s",
- timetoa(&cert->notAfter, utc),
- check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
- if (cert->subjectKeyID.ptr != NULL)
- {
- datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " subjkey: %s", buf);
- }
- if (cert->authKeyID.ptr != NULL)
- {
- datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
- , buf, BUF_LEN);
- whack_log(RC_COMMENT, " authkey: %s", buf);
- }
- if (cert->authKeySerialNumber.ptr != NULL)
- {
- datatot(cert->authKeySerialNumber.ptr, cert->authKeySerialNumber.len
- , ':', buf, BUF_LEN);
- whack_log(RC_COMMENT, " aserial: %s", buf);
- }
+ if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
+ {
+ u_char buf[BUF_LEN];
+ public_key_t *key = cert->public_key;
+ cert_t c;
+
+ c.type = CERT_X509_SIGNATURE;
+ c.u.x509 = cert;
+
+ if (first)
+ {
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of X.509 %s Certificates:", caption);
+ whack_log(RC_COMMENT, " ");
+ first = FALSE;
+ }
+
+ whack_log(RC_COMMENT, "%T, count: %d", &cert->installed, utc,
+ cert->count);
+ dntoa(buf, BUF_LEN, cert->subject);
+ whack_log(RC_COMMENT, " subject: '%s'", buf);
+ dntoa(buf, BUF_LEN, cert->issuer);
+ whack_log(RC_COMMENT, " issuer: '%s'", buf);
+ datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':',
+ buf, BUF_LEN);
+ whack_log(RC_COMMENT, " serial: %s", buf);
+ whack_log(RC_COMMENT, " validity: not before %T %s",
+ &cert->notBefore, utc,
+ (cert->notBefore < now)?"ok":"fatal (not valid yet)");
+ whack_log(RC_COMMENT, " not after %T %s",
+ &cert->notAfter, utc,
+ check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
+ whack_log(RC_COMMENT, " pubkey: %N %4d bits%s",
+ key_type_names, key->get_type(key),
+ key->get_keysize(key) * BITS_PER_BYTE,
+ cert->smartcard ? ", on smartcard" :
+ (has_private_key(c)? ", has private key" : ""));
+ whack_log(RC_COMMENT, " keyid: %Y",
+ key->get_id(key, ID_PUBKEY_INFO_SHA1));
+ if (cert->subjectKeyID.ptr != NULL)
+ {
+ datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':',
+ buf, BUF_LEN);
+ whack_log(RC_COMMENT, " subjkey: %s", buf);
+ }
+ if (cert->authKeyID.ptr != NULL)
+ {
+ datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':',
+ buf, BUF_LEN);
+ whack_log(RC_COMMENT, " authkey: %s", buf);
+ }
+ if (cert->authKeySerialNumber.ptr != NULL)
+ {
+ datatot(cert->authKeySerialNumber.ptr,
+ cert->authKeySerialNumber.len, ':', buf, BUF_LEN);
+ whack_log(RC_COMMENT, " aserial: %s", buf);
+ }
+ }
+ cert = cert->next;
}
- cert = cert->next;
- }
}
-/*
- * list all X.509 end certificates in a chained list
+/**
+ * List all X.509 end certificates in a chained list
*/
-void
-list_x509_end_certs(bool utc)
+void list_x509_end_certs(bool utc)
{
- list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
+ list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
}
diff --git a/src/pluto/x509.h b/src/pluto/x509.h
index 67730bbd0..ab0fbac9e 100644
--- a/src/pluto/x509.h
+++ b/src/pluto/x509.h
@@ -2,7 +2,7 @@
* Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
* Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
* Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2000-2009 Andreas Steffen, Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -13,28 +13,29 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: x509.h 3252 2007-10-06 21:24:50Z andreas $
*/
#ifndef _X509_H
#define _X509_H
-#include "pkcs1.h"
+#include <credentials/keys/public_key.h>
+#include <credentials/keys/private_key.h>
+
+#include "constants.h"
#include "id.h"
/* Definition of generalNames kinds */
typedef enum {
- GN_OTHER_NAME = 0,
- GN_RFC822_NAME = 1,
- GN_DNS_NAME = 2,
- GN_X400_ADDRESS = 3,
- GN_DIRECTORY_NAME = 4,
- GN_EDI_PARTY_NAME = 5,
- GN_URI = 6,
- GN_IP_ADDRESS = 7,
- GN_REGISTERED_ID = 8
+ GN_OTHER_NAME = 0,
+ GN_RFC822_NAME = 1,
+ GN_DNS_NAME = 2,
+ GN_X400_ADDRESS = 3,
+ GN_DIRECTORY_NAME = 4,
+ GN_EDI_PARTY_NAME = 5,
+ GN_URI = 6,
+ GN_IP_ADDRESS = 7,
+ GN_REGISTERED_ID = 8
} generalNames_t;
/* access structure for a GeneralName */
@@ -42,9 +43,9 @@ typedef enum {
typedef struct generalName generalName_t;
struct generalName {
- generalName_t *next;
- generalNames_t kind;
- chunk_t name;
+ generalName_t *next;
+ generalNames_t kind;
+ chunk_t name;
};
/* access structure for an X.509v3 certificate */
@@ -52,46 +53,42 @@ struct generalName {
typedef struct x509cert x509cert_t;
struct x509cert {
- x509cert_t *next;
- time_t installed;
- int count;
- bool smartcard;
- u_char authority_flags;
- chunk_t certificate;
- chunk_t tbsCertificate;
- u_int version;
- chunk_t serialNumber;
- /* signature */
- int sigAlg;
- chunk_t issuer;
- /* validity */
- time_t notBefore;
- time_t notAfter;
- chunk_t subject;
- /* subjectPublicKeyInfo */
- enum pubkey_alg subjectPublicKeyAlgorithm;
- chunk_t subjectPublicKey;
- chunk_t modulus;
- chunk_t publicExponent;
- /* issuerUniqueID */
- /* subjectUniqueID */
- /* v3 extensions */
- /* extension */
- /* extension */
- /* extnID */
- /* critical */
- /* extnValue */
- bool isCA;
- bool isOcspSigner; /* ocsp */
- chunk_t subjectKeyID;
- chunk_t authKeyID;
- chunk_t authKeySerialNumber;
- chunk_t accessLocation; /* ocsp */
- generalName_t *subjectAltName;
- generalName_t *crlDistributionPoints;
- /* signatureAlgorithm */
- int algorithm;
- chunk_t signature;
+ x509cert_t *next;
+ time_t installed;
+ int count;
+ bool smartcard;
+ u_char authority_flags;
+ chunk_t certificate;
+ chunk_t tbsCertificate;
+ u_int version;
+ chunk_t serialNumber;
+ /* signature */
+ int sigAlg;
+ chunk_t issuer;
+ /* validity */
+ time_t notBefore;
+ time_t notAfter;
+ chunk_t subject;
+ public_key_t *public_key;
+ /* issuerUniqueID */
+ /* subjectUniqueID */
+ /* v3 extensions */
+ /* extension */
+ /* extension */
+ /* extnID */
+ /* critical */
+ /* extnValue */
+ bool isCA;
+ bool isOcspSigner; /* ocsp */
+ chunk_t subjectKeyID;
+ chunk_t authKeyID;
+ chunk_t authKeySerialNumber;
+ chunk_t accessLocation; /* ocsp */
+ generalName_t *subjectAltName;
+ generalName_t *crlDistributionPoints;
+ /* signatureAlgorithm */
+ int algorithm;
+ chunk_t signature;
};
/* used for initialization */
@@ -105,33 +102,37 @@ extern bool same_x509cert(const x509cert_t *a, const x509cert_t *b);
extern void hex_str(chunk_t bin, chunk_t *str);
extern int dn_count_wildcards(chunk_t dn);
extern int dntoa(char *dst, size_t dstlen, chunk_t dn);
-extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn
- , const char* null_dn);
+extern int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn,
+ const char* null_dn);
extern err_t atodn(char *src, chunk_t *dn);
extern void gntoid(struct id *id, const generalName_t *gn);
-extern void compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
+extern bool compute_subjectKeyID(x509cert_t *cert, chunk_t subjectKeyID);
extern void select_x509cert_id(x509cert_t *cert, struct id *end_id);
extern bool parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert);
extern time_t parse_time(chunk_t blob, int level0);
extern void parse_authorityKeyIdentifier(chunk_t blob, int level0
- , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
+ , chunk_t *authKeyID, chunk_t *authKeySerialNumber);
extern chunk_t get_directoryName(chunk_t blob, int level, bool implicit);
extern err_t check_validity(const x509cert_t *cert, time_t *until);
-extern bool check_signature(chunk_t tbs, chunk_t sig, int digest_alg
- , int enc_alg, const x509cert_t *issuer_cert);
+
+extern bool x509_check_signature(chunk_t tbs, chunk_t sig, int algorithm,
+ const x509cert_t *issuer_cert);
+extern chunk_t x509_build_signature(chunk_t tbs, int algorithm,
+ private_key_t *key, bool bit_string);
+
extern bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until);
extern x509cert_t* add_x509cert(x509cert_t *cert);
-extern x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid
- , x509cert_t* chain);
-extern void build_x509cert(x509cert_t *cert, const RSA_public_key_t *cert_key
- , const RSA_private_key_t *signer_key);
+extern x509cert_t* get_x509cert(chunk_t issuer, chunk_t serial, chunk_t keyid,
+ x509cert_t* chain);
+extern void build_x509cert(x509cert_t *cert, public_key_t *cert_key,
+ private_key_t *signer_key);
extern chunk_t build_subjectAltNames(generalName_t *subjectAltNames);
extern void share_x509cert(x509cert_t *cert);
extern void release_x509cert(x509cert_t *cert);
extern void free_x509cert(x509cert_t *cert);
extern void store_x509certs(x509cert_t **firstcert, bool strict);
-extern void list_x509cert_chain(const char *caption, x509cert_t* cert
- , u_char auth_flags, bool utc);
+extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
+ u_char auth_flags, bool utc);
extern void list_x509_end_certs(bool utc);
extern void free_generalNames(generalName_t* gn, bool free_name);
diff --git a/src/pluto/xauth.c b/src/pluto/xauth.c
index 8f4dc2460..af2d72d71 100644
--- a/src/pluto/xauth.c
+++ b/src/pluto/xauth.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: xauth.c 3738 2008-04-02 19:04:45Z andreas $
*/
#include <dlfcn.h>
@@ -29,51 +27,51 @@ void
xauth_init(void)
{
#ifdef XAUTH_DEFAULT_LIB
- xauth_module.handle = dlopen(XAUTH_DEFAULT_LIB, RTLD_NOW);
+ xauth_module.handle = dlopen(XAUTH_DEFAULT_LIB, RTLD_NOW);
- if (xauth_module.handle != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module '%s' loading'", XAUTH_DEFAULT_LIB)
- )
- xauth_module.get_secret = (bool (*) (const xauth_t*))
- dlsym(xauth_module.handle, "get_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.get_secret != NULL)
- {
- DBG_log("xauth module: found get_secret() function");
- }
- )
- xauth_module.verify_secret = (bool (*) (const xauth_peer_t*, const xauth_t*))
- dlsym(xauth_module.handle, "verify_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.verify_secret != NULL)
- {
- DBG_log("xauth module: found verify_secret() function");
- }
- )
- }
+ if (xauth_module.handle != NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module '%s' loading'", XAUTH_DEFAULT_LIB)
+ )
+ xauth_module.get_secret = (bool (*) (const xauth_t*))
+ dlsym(xauth_module.handle, "get_secret");
+ DBG(DBG_CONTROL,
+ if (xauth_module.get_secret != NULL)
+ {
+ DBG_log("xauth module: found get_secret() function");
+ }
+ )
+ xauth_module.verify_secret = (bool (*) (const xauth_peer_t*, const xauth_t*))
+ dlsym(xauth_module.handle, "verify_secret");
+ DBG(DBG_CONTROL,
+ if (xauth_module.verify_secret != NULL)
+ {
+ DBG_log("xauth module: found verify_secret() function");
+ }
+ )
+ }
#endif
- /* any null function pointers will be filled in by default functions */
- xauth_defaults();
+ /* any null function pointers will be filled in by default functions */
+ xauth_defaults();
}
void
xauth_finalize(void)
{
#ifdef XAUTH_DEFAULT_LIB
- if (xauth_module.handle != NULL)
- {
- if (dlclose(xauth_module.handle))
- {
- plog("failed to unload xauth module");
- }
- else
+ if (xauth_module.handle != NULL)
{
- DBG(DBG_CONTROL,
- DBG_log("xauth module unloaded")
- )
+ if (dlclose(xauth_module.handle))
+ {
+ plog("failed to unload xauth module");
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth module unloaded")
+ )
+ }
}
- }
#endif
}
diff --git a/src/pluto/xauth.h b/src/pluto/xauth.h
index fd7e5399f..8ab125ac4 100644
--- a/src/pluto/xauth.h
+++ b/src/pluto/xauth.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: xauth.h 3738 2008-04-02 19:04:45Z andreas $
*/
#ifndef _XAUTH_H
@@ -26,20 +24,20 @@
struct chunk_t;
typedef struct {
- char *conn_name;
- char id[BUF_LEN];
- char ip_address[ADDRTOT_BUF];
+ char *conn_name;
+ char id[BUF_LEN];
+ char ip_address[ADDRTOT_BUF];
} xauth_peer_t;
typedef struct {
- chunk_t user_name;
- chunk_t user_password;
+ chunk_t user_name;
+ chunk_t user_password;
} xauth_t;
typedef struct {
- void *handle;
- bool (*get_secret) (xauth_t *xauth_secret);
- bool (*verify_secret) (const xauth_peer_t *peer, const xauth_t *xauth_secret);
+ void *handle;
+ bool (*get_secret) (xauth_t *xauth_secret);
+ bool (*verify_secret) (const xauth_peer_t *peer, const xauth_t *xauth_secret);
} xauth_module_t;
extern xauth_module_t xauth_module;
diff --git a/src/scepclient/Makefile.am b/src/scepclient/Makefile.am
index 86220d71b..20bf76065 100644
--- a/src/scepclient/Makefile.am
+++ b/src/scepclient/Makefile.am
@@ -1,5 +1,5 @@
ipsec_PROGRAMS = scepclient
-scepclient_SOURCES = scepclient.c rsakey.c rsakey.h pkcs10.c pkcs10.h scep.c scep.h loglite.c
+scepclient_SOURCES = scepclient.c pkcs10.c pkcs10.h scep.c scep.h loglite.c
PLUTODIR=$(top_srcdir)/src/pluto
OPENACDIR=$(top_srcdir)/src/openac
@@ -15,34 +15,30 @@ INCLUDES = \
-I$(LIBCRYPTODIR) \
-I$(WHACKDIR)
-AM_CFLAGS = -DDEBUG -DNO_PLUTO -DIPSEC_CONFDIR=\"${confdir}\"
+AM_CFLAGS = \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PLUGINDIR=\"${plugindir}\" \
+-DPLUGINS=\""${pluto_plugins}\"" \
+-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
+-DDEBUG -DNO_PLUTO
+LIBSTRONGSWANBUILDDIR=$(top_builddir)/src/libstrongswan
LIBFREESWANBUILDDIR=$(top_builddir)/src/libfreeswan
-LIBCRYPTOBUILDDIR=$(top_builddir)/src/libcrypto
-scepclient_LDADD = asn1.o ca.o crl.o certs.o constants.o defs.o fetch.o id.o \
- keys.o lex.o md2.o md5.o mp_defs.o ocsp.o oid.o pem.o pgp.o \
- pkcs1.o pkcs7.o rnd.o sha1.o smartcard.o x509.o \
- $(LIBFREESWANBUILDDIR)/libfreeswan.a $(LIBCRYPTOBUILDDIR)/libcrypto.a \
- -lgmp
+scepclient_LDADD = \
+ca.o crl.o certs.o constants.o defs.o fetch.o id.o keys.o lex.o \
+ocsp.o pem.o pgpcert.o pkcs7.o smartcard.o x509.o \
+$(LIBSTRONGSWANBUILDDIR)/libstrongswan.la \
+$(LIBFREESWANBUILDDIR)/libfreeswan.a
# This compile option activates smartcard support
if USE_SMARTCARD
AM_CFLAGS += -DSMARTCARD
- scepclient_LDADD += -ldl
-endif
-
-# This compile option activates dynamic URL fetching using libcurl
-if USE_CURL
- AM_CFLAGS += -DLIBCURL
- scepclient_LDADD += -lcurl
+ scepclient_LDADD += $(DLLIB)
endif
dist_man_MANS = scepclient.8
-asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
@@ -58,9 +54,6 @@ crl.o : $(PLUTODIR)/crl.c $(PLUTODIR)/crl.h
defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-mp_defs.o : $(PLUTODIR)/mp_defs.c $(PLUTODIR)/mp_defs.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
fetch.o : $(PLUTODIR)/fetch.c $(PLUTODIR)/fetch.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
@@ -73,36 +66,18 @@ keys.o : $(PLUTODIR)/keys.c $(PLUTODIR)/keys.h
lex.o : $(PLUTODIR)/lex.c $(PLUTODIR)/lex.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-md2.o : $(PLUTODIR)/md2.c $(PLUTODIR)/md2.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-md5.o : $(PLUTODIR)/md5.c $(PLUTODIR)/md5.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
ocsp.o : $(PLUTODIR)/ocsp.c $(PLUTODIR)/ocsp.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
- $(COMPILE) -c -o $@ $<
-
pem.o : $(PLUTODIR)/pem.c $(PLUTODIR)/pem.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-pgp.o : $(PLUTODIR)/pgp.c $(PLUTODIR)/pgp.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
+pgpcert.o : $(PLUTODIR)/pgpcert.c $(PLUTODIR)/pgpcert.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
pkcs7.o : $(PLUTODIR)/pkcs7.c $(PLUTODIR)/pkcs7.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
smartcard.o : $(PLUTODIR)/smartcard.c $(PLUTODIR)/smartcard.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index a15b65697..3919583ef 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -36,11 +36,7 @@ ipsec_PROGRAMS = scepclient$(EXEEXT)
# This compile option activates smartcard support
@USE_SMARTCARD_TRUE@am__append_1 = -DSMARTCARD
-@USE_SMARTCARD_TRUE@am__append_2 = -ldl
-
-# This compile option activates dynamic URL fetching using libcurl
-@USE_CURL_TRUE@am__append_3 = -DLIBCURL
-@USE_CURL_TRUE@am__append_4 = -lcurl
+@USE_SMARTCARD_TRUE@am__append_2 = $(DLLIB)
subdir = src/scepclient
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -53,16 +49,15 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
-am_scepclient_OBJECTS = scepclient.$(OBJEXT) rsakey.$(OBJEXT) \
- pkcs10.$(OBJEXT) scep.$(OBJEXT) loglite.$(OBJEXT)
+am_scepclient_OBJECTS = scepclient.$(OBJEXT) pkcs10.$(OBJEXT) \
+ scep.$(OBJEXT) loglite.$(OBJEXT)
scepclient_OBJECTS = $(am_scepclient_OBJECTS)
am__DEPENDENCIES_1 =
-scepclient_DEPENDENCIES = asn1.o ca.o crl.o certs.o constants.o defs.o \
- fetch.o id.o keys.o lex.o md2.o md5.o mp_defs.o ocsp.o oid.o \
- pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o smartcard.o x509.o \
- $(LIBFREESWANBUILDDIR)/libfreeswan.a \
- $(LIBCRYPTOBUILDDIR)/libcrypto.a $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+@USE_SMARTCARD_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+scepclient_DEPENDENCIES = ca.o crl.o certs.o constants.o defs.o \
+ fetch.o id.o keys.o lex.o ocsp.o pem.o pgpcert.o pkcs7.o \
+ smartcard.o x509.o $(LIBSTRONGSWANBUILDDIR)/libstrongswan.la \
+ $(LIBFREESWANBUILDDIR)/libfreeswan.a $(am__DEPENDENCIES_2)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -98,6 +93,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -120,6 +116,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -131,6 +130,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -144,6 +144,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -204,6 +206,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -215,11 +218,12 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-scepclient_SOURCES = scepclient.c rsakey.c rsakey.h pkcs10.c pkcs10.h scep.c scep.h loglite.c
+scepclient_SOURCES = scepclient.c pkcs10.c pkcs10.h scep.c scep.h loglite.c
PLUTODIR = $(top_srcdir)/src/pluto
OPENACDIR = $(top_srcdir)/src/openac
WHACKDIR = $(top_srcdir)/src/whack
@@ -233,16 +237,17 @@ INCLUDES = \
-I$(LIBCRYPTODIR) \
-I$(WHACKDIR)
-AM_CFLAGS = -DDEBUG -DNO_PLUTO -DIPSEC_CONFDIR=\"${confdir}\" \
- $(am__append_1) $(am__append_3)
+AM_CFLAGS = -DIPSEC_CONFDIR=\"${confdir}\" \
+ -DIPSEC_PLUGINDIR=\"${plugindir}\" \
+ -DPLUGINS=\""${pluto_plugins}\"" \
+ -DSTRONGSWAN_CONF=\"${strongswan_conf}\" -DDEBUG -DNO_PLUTO \
+ $(am__append_1)
+LIBSTRONGSWANBUILDDIR = $(top_builddir)/src/libstrongswan
LIBFREESWANBUILDDIR = $(top_builddir)/src/libfreeswan
-LIBCRYPTOBUILDDIR = $(top_builddir)/src/libcrypto
-scepclient_LDADD = asn1.o ca.o crl.o certs.o constants.o defs.o \
- fetch.o id.o keys.o lex.o md2.o md5.o mp_defs.o ocsp.o oid.o \
- pem.o pgp.o pkcs1.o pkcs7.o rnd.o sha1.o smartcard.o x509.o \
- $(LIBFREESWANBUILDDIR)/libfreeswan.a \
- $(LIBCRYPTOBUILDDIR)/libcrypto.a -lgmp $(am__append_2) \
- $(am__append_4)
+scepclient_LDADD = ca.o crl.o certs.o constants.o defs.o fetch.o id.o \
+ keys.o lex.o ocsp.o pem.o pgpcert.o pkcs7.o smartcard.o x509.o \
+ $(LIBSTRONGSWANBUILDDIR)/libstrongswan.la \
+ $(LIBFREESWANBUILDDIR)/libfreeswan.a $(am__append_2)
dist_man_MANS = scepclient.8
all: all-am
@@ -252,8 +257,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -317,7 +322,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loglite.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs10.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsakey.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scep.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scepclient.Po@am__quote@
@@ -358,8 +362,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -398,7 +402,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -576,9 +580,6 @@ uninstall-man: uninstall-man8
uninstall-man uninstall-man8
-asn1.o : $(PLUTODIR)/asn1.c $(PLUTODIR)/asn1.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
ca.o : $(PLUTODIR)/ca.c $(PLUTODIR)/ca.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
@@ -594,9 +595,6 @@ crl.o : $(PLUTODIR)/crl.c $(PLUTODIR)/crl.h
defs.o : $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-mp_defs.o : $(PLUTODIR)/mp_defs.c $(PLUTODIR)/mp_defs.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
fetch.o : $(PLUTODIR)/fetch.c $(PLUTODIR)/fetch.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
@@ -609,36 +607,18 @@ keys.o : $(PLUTODIR)/keys.c $(PLUTODIR)/keys.h
lex.o : $(PLUTODIR)/lex.c $(PLUTODIR)/lex.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-md2.o : $(PLUTODIR)/md2.c $(PLUTODIR)/md2.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-md5.o : $(PLUTODIR)/md5.c $(PLUTODIR)/md5.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
ocsp.o : $(PLUTODIR)/ocsp.c $(PLUTODIR)/ocsp.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
- $(COMPILE) -c -o $@ $<
-
pem.o : $(PLUTODIR)/pem.c $(PLUTODIR)/pem.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-pgp.o : $(PLUTODIR)/pgp.c $(PLUTODIR)/pgp.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-pkcs1.o : $(PLUTODIR)/pkcs1.c $(PLUTODIR)/pkcs1.h
+pgpcert.o : $(PLUTODIR)/pgpcert.c $(PLUTODIR)/pgpcert.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
pkcs7.o : $(PLUTODIR)/pkcs7.c $(PLUTODIR)/pkcs7.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
-rnd.o : $(PLUTODIR)/rnd.c $(PLUTODIR)/rnd.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
-sha1.o : $(PLUTODIR)/sha1.c $(PLUTODIR)/sha1.h
- $(COMPILE) $(INCLUDES) -c -o $@ $<
-
smartcard.o : $(PLUTODIR)/smartcard.c $(PLUTODIR)/smartcard.h
$(COMPILE) $(INCLUDES) -c -o $@ $<
diff --git a/src/scepclient/loglite.c b/src/scepclient/loglite.c
index 4219eb707..b14e72ecb 100644
--- a/src/scepclient/loglite.c
+++ b/src/scepclient/loglite.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: loglite.c,v 1.2 2005/07/11 18:38:16 as Exp $
*/
#include <stdio.h>
@@ -23,12 +21,13 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
+#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <freeswan.h>
+#include <debug.h>
#include <constants.h>
#include <defs.h>
@@ -36,118 +35,179 @@
#include <whack.h>
bool
- log_to_stderr = FALSE, /* should log go to stderr? */
- log_to_syslog = TRUE; /* should log go to syslog? */
+ log_to_stderr = FALSE, /* should log go to stderr? */
+ log_to_syslog = TRUE; /* should log go to syslog? */
-void
-init_log(const char *program)
+/**
+ * @brief scepclient dbg function
+ */
+static void scepclient_dbg(int level, char *fmt, ...)
{
- if (log_to_stderr)
- setbuf(stderr, NULL);
- if (log_to_syslog)
- openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
+ int priority = LOG_INFO;
+ int debug_level;
+ char buffer[8192];
+ char *current = buffer, *next;
+ va_list args;
+
+ if (cur_debugging & DBG_PRIVATE)
+ {
+ debug_level = 4;
+ }
+ else if (cur_debugging & DBG_RAW)
+ {
+ debug_level = 3;
+ }
+ else if (cur_debugging & DBG_PARSING)
+ {
+ debug_level = 2;
+ }
+ else
+ {
+ debug_level = 1;
+ }
+
+ if (level <= debug_level)
+ {
+ va_start(args, fmt);
+
+ if (log_to_stderr)
+ {
+ if (level > 1)
+ {
+ fprintf(stderr, "| ");
+ }
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ }
+ if (log_to_syslog)
+ {
+ /* write in memory buffer first */
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+
+ /* do a syslog with every line */
+ while (current)
+ {
+ next = strchr(current, '\n');
+ if (next)
+ {
+ *(next++) = '\0';
+ }
+ syslog(priority, "%s%s\n", (level > 1)? "| ":"", current);
+ current = next;
+ }
+ }
+ va_end(args);
+ }
}
-void
-close_log(void)
+void init_log(const char *program)
{
- if (log_to_syslog)
- closelog();
+ /* enable scepclient bugging hook */
+ dbg = scepclient_dbg;
+
+ if (log_to_stderr)
+ {
+ setbuf(stderr, NULL);
+ }
+ if (log_to_syslog)
+ {
+ openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
+ }
}
-void
-plog(const char *message, ...)
+void close_log(void)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ if (log_to_syslog)
+ closelog();
+}
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+void plog(const char *message, ...)
+{
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
}
-void
-loglog(int mess_no, const char *message, ...)
+void loglog(int mess_no, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
}
-void
-log_errno_routine(int e, const char *message, ...)
+void log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ if (log_to_stderr)
+ fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
}
-void
-exit_log(const char *message, ...)
+void exit_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s\n", m);
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s", m);
- exit(1);
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s", m);
+ exit(1);
}
-void
-exit_log_errno_routine(int e, const char *message, ...)
+void exit_log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- exit(1);
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ exit(1);
}
-void
-whack_log(int mess_no, const char *message, ...)
+void whack_log(int mess_no, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- fprintf(stderr, "%s\n", m);
+ fprintf(stderr, "%s\n", m);
}
/* Build up a diagnostic in a static buffer.
@@ -162,132 +222,126 @@ whack_log(int mess_no, const char *message, ...)
*/
char diag_space[sizeof(diag_space)];
-err_t
-builddiag(const char *fmt, ...)
+err_t builddiag(const char *fmt, ...)
{
- static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
- char t[sizeof(diag_space)]; /* build result here first */
- va_list args;
-
- va_start(args, fmt);
- t[0] = '\0'; /* in case nothing terminates string */
- vsnprintf(t, sizeof(t), fmt, args);
- va_end(args);
- strcpy(diag_space, t);
- return diag_space;
+ static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
+ char t[sizeof(diag_space)]; /* build result here first */
+ va_list args;
+
+ va_start(args, fmt);
+ t[0] = '\0'; /* in case nothing terminates string */
+ vsnprintf(t, sizeof(t), fmt, args);
+ va_end(args);
+ strcpy(diag_space, t);
+ return diag_space;
}
/* Debugging message support */
#ifdef DEBUG
-void
-switch_fail(int n, const char *file_str, unsigned long line_no)
+void switch_fail(int n, const char *file_str, unsigned long line_no)
{
- char buf[30];
+ char buf[30];
- snprintf(buf, sizeof(buf), "case %d unexpected", n);
- passert_fail(buf, file_str, line_no);
+ snprintf(buf, sizeof(buf), "case %d unexpected", n);
+ passert_fail(buf, file_str, line_no);
}
-void
-passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
+void passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- abort(); /* exiting correctly doesn't always work */
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ abort(); /* exiting correctly doesn't always work */
}
lset_t
- base_debugging = DBG_NONE, /* default to reporting nothing */
- cur_debugging = DBG_NONE;
+ base_debugging = DBG_NONE, /* default to reporting nothing */
+ cur_debugging = DBG_NONE;
-void
-pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
+void pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
}
/* log a debugging message (prefixed by "| ") */
-void
-DBG_log(const char *message, ...)
+void DBG_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "| %s\n", m);
- if (log_to_syslog)
- syslog(LOG_DEBUG, "| %s", m);
+ if (log_to_stderr)
+ fprintf(stderr, "| %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_DEBUG, "| %s", m);
}
/* dump raw bytes in hex to stderr (for lack of any better destination) */
-void
-DBG_dump(const char *label, const void *p, size_t len)
+void DBG_dump(const char *label, const void *p, size_t len)
{
-# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
-# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
- char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
- char *bp;
- const unsigned char *cp = p;
-
- bp = buf;
+# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
+# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
+ char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
+ char *bp;
+ const unsigned char *cp = p;
- if (label != NULL && label[0] != '\0')
- {
- /* Handle the label. Care must be taken to avoid buffer overrun. */
- size_t llen = strlen(label);
+ bp = buf;
- if (llen + 1 > sizeof(buf))
+ if (label != NULL && label[0] != '\0')
{
- DBG_log("%s", label);
+ /* Handle the label. Care must be taken to avoid buffer overrun. */
+ size_t llen = strlen(label);
+
+ if (llen + 1 > sizeof(buf))
+ {
+ DBG_log("%s", label);
+ }
+ else
+ {
+ strcpy(buf, label);
+ if (buf[llen-1] == '\n')
+ {
+ buf[llen-1] = '\0'; /* get rid of newline */
+ DBG_log("%s", buf);
+ }
+ else if (llen < DUMP_LABEL_WIDTH)
+ {
+ bp = buf + llen;
+ }
+ else
+ {
+ DBG_log("%s", buf);
+ }
+ }
}
- else
- {
- strcpy(buf, label);
- if (buf[llen-1] == '\n')
- {
- buf[llen-1] = '\0'; /* get rid of newline */
- DBG_log("%s", buf);
- }
- else if (llen < DUMP_LABEL_WIDTH)
- {
- bp = buf + llen;
- }
- else
- {
- DBG_log("%s", buf);
- }
- }
- }
-
- do {
- int i, j;
- for (i = 0; len!=0 && i!=4; i++)
- {
- *bp++ = ' ';
- for (j = 0; len!=0 && j!=4; len--, j++)
- {
- static const char hexdig[] = "0123456789abcdef";
-
- *bp++ = ' ';
- *bp++ = hexdig[(*cp >> 4) & 0xF];
- *bp++ = hexdig[*cp & 0xF];
- cp++;
- }
- }
- *bp = '\0';
- DBG_log("%s", buf);
- bp = buf;
- } while (len != 0);
+ do {
+ int i, j;
+
+ for (i = 0; len!=0 && i!=4; i++)
+ {
+ *bp++ = ' ';
+ for (j = 0; len!=0 && j!=4; len--, j++)
+ {
+ static const char hexdig[] = "0123456789abcdef";
+
+ *bp++ = ' ';
+ *bp++ = hexdig[(*cp >> 4) & 0xF];
+ *bp++ = hexdig[*cp & 0xF];
+ cp++;
+ }
+ }
+ *bp = '\0';
+ DBG_log("%s", buf);
+ bp = buf;
+ } while (len != 0);
# undef DUMP_LABEL_WIDTH
# undef DUMP_WIDTH
}
diff --git a/src/scepclient/pkcs10.c b/src/scepclient/pkcs10.c
index 86267f508..cdd68431e 100644
--- a/src/scepclient/pkcs10.c
+++ b/src/scepclient/pkcs10.c
@@ -26,12 +26,11 @@
#include <arpa/inet.h>
#include <freeswan.h>
+#include <asn1/asn1.h>
#include <asn1/oid.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
#include "../pluto/log.h"
#include "../pluto/x509.h"
@@ -40,66 +39,66 @@
/* some pre-coded OIDs */
static u_char ASN1_challengePassword_oid_str[] = {
- 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x07
+ 0x06,0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x07
};
-static const chunk_t ASN1_challengePassword_oid = strchunk(ASN1_challengePassword_oid_str);
+static const chunk_t ASN1_challengePassword_oid = chunk_from_buf(ASN1_challengePassword_oid_str);
static u_char ASN1_extensionRequest_oid_str[] = {
- 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x0E
+ 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x0E
};
-static const chunk_t ASN1_extensionRequest_oid = strchunk(ASN1_extensionRequest_oid_str);
+static const chunk_t ASN1_extensionRequest_oid = chunk_from_buf(ASN1_extensionRequest_oid_str);
/**
* @brief Adds a subjectAltName in DER-coded form to a linked list
*
- * @param[in,out] subjectAltNames head of the linked list of subjectAltNames
- * @param[in] kind type of the subjectAltName (which is a generalName)
- * @param[in] value value of the subjectAltName as an ASCII string
+ * @param[in,out] subjectAltNames head of the linked list of subjectAltNames
+ * @param[in] kind type of the subjectAltName (which is a generalName)
+ * @param[in] value value of the subjectAltName as an ASCII string
*/
void
pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
, char *value)
{
- generalName_t *gn;
- asn1_t asn1_type = ASN1_EOC;
- chunk_t name = { value, strlen(value) };
-
- switch (kind)
- {
- case GN_RFC822_NAME:
- asn1_type = ASN1_CONTEXT_S_1;
- break;
- case GN_DNS_NAME:
- asn1_type = ASN1_CONTEXT_S_2;
- break;
- case GN_IP_ADDRESS:
+ generalName_t *gn;
+ asn1_t asn1_type = ASN1_EOC;
+ chunk_t name = { value, strlen(value) };
+
+ switch (kind)
{
- struct in_addr addr;
-
- /* convert an ASCII dotted IPv4 address (e.g. 123.456.78.90)
- * to a byte representation in network order
- */
- if (!inet_aton(value, &addr))
- {
- fprintf(stderr, "error in IPv4 subjectAltName\n");
- return;
- }
- asn1_type = ASN1_CONTEXT_S_7;
- name.ptr = (u_char *) &addr.s_addr;
- name.len = sizeof(addr.s_addr);
- break;
- }
- default:
- break;
- }
-
- gn = alloc_thing(generalName_t, "subjectAltName");
- gn->kind = kind;
- gn->name = asn1_simple_object(asn1_type, name);
- gn->next = *subjectAltNames;
- *subjectAltNames = gn;
+ case GN_RFC822_NAME:
+ asn1_type = ASN1_CONTEXT_S_1;
+ break;
+ case GN_DNS_NAME:
+ asn1_type = ASN1_CONTEXT_S_2;
+ break;
+ case GN_IP_ADDRESS:
+ {
+ struct in_addr addr;
+
+ /* convert an ASCII dotted IPv4 address (e.g. 123.456.78.90)
+ * to a byte representation in network order
+ */
+ if (!inet_aton(value, &addr))
+ {
+ fprintf(stderr, "error in IPv4 subjectAltName\n");
+ return;
+ }
+ asn1_type = ASN1_CONTEXT_S_7;
+ name.ptr = (u_char *) &addr.s_addr;
+ name.len = sizeof(addr.s_addr);
+ break;
+ }
+ default:
+ break;
+ }
+
+ gn = malloc_thing(generalName_t);
+ gn->kind = kind;
+ gn->name = asn1_simple_object(asn1_type, name);
+ gn->next = *subjectAltNames;
+ *subjectAltNames = gn;
}
/**
@@ -108,71 +107,75 @@ pkcs10_add_subjectAltName(generalName_t **subjectAltNames, generalNames_t kind
* challenge password ans subjectAltNames are only included,
* when avaiable in given #pkcs10_t structure
*
- * @param[in] pkcs10 Pointer to a #pkcs10_t structure
- * @return 1 if succeeded, 0 otherwise
+ * @param[in] pkcs10 Pointer to a #pkcs10_t structure
+ * @return 1 if succeeded, 0 otherwise
*/
static chunk_t
build_req_info_attributes(pkcs10_t* pkcs10)
{
- chunk_t subjectAltNames = empty_chunk;
- chunk_t challengePassword = empty_chunk;
-
- if (pkcs10->subjectAltNames != NULL)
- {
-
- subjectAltNames = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_extensionRequest_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_wrap(ASN1_SEQUENCE, "m"
- , build_subjectAltNames(pkcs10->subjectAltNames)
- )
- )
- );
- }
-
- if (pkcs10->challengePassword.len > 0)
- {
- asn1_t type = is_printablestring(pkcs10->challengePassword)
- ? ASN1_PRINTABLESTRING : ASN1_T61STRING;
-
- challengePassword = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_challengePassword_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(type, pkcs10->challengePassword)
- )
- );
- }
-
- return asn1_wrap(ASN1_CONTEXT_C_0, "mm"
- , subjectAltNames
- , challengePassword);
+ chunk_t subjectAltNames = chunk_empty;
+ chunk_t challengePassword = chunk_empty;
+
+ if (pkcs10->subjectAltNames != NULL)
+ {
+
+ subjectAltNames = asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_extensionRequest_oid
+ , asn1_wrap(ASN1_SET, "m"
+ , asn1_wrap(ASN1_SEQUENCE, "m"
+ , build_subjectAltNames(pkcs10->subjectAltNames)
+ )
+ )
+ );
+ }
+
+ if (pkcs10->challengePassword.len > 0)
+ {
+ asn1_t type = asn1_is_printablestring(pkcs10->challengePassword)
+ ? ASN1_PRINTABLESTRING : ASN1_T61STRING;
+
+ challengePassword = asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_challengePassword_oid
+ , asn1_wrap(ASN1_SET, "m"
+ , asn1_simple_object(type, pkcs10->challengePassword)
+ )
+ );
+ }
+
+ return asn1_wrap(ASN1_CONTEXT_C_0, "mm"
+ , subjectAltNames
+ , challengePassword);
}
/**
* @brief Builds a DER-code pkcs#10 certificate request
*
- * @param[in] pkcs10 pointer to a pkcs10_t struct
- * @return DER-code pkcs10 request
+ * @param[in] pkcs10 pointer to a pkcs10_t struct
+ * @return DER-code pkcs10 request
*/
static chunk_t
pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
{
- RSA_public_key_t *rsak = (RSA_public_key_t *) pkcs10->private_key;
+ chunk_t key = pkcs10->public_key->get_encoding(pkcs10->public_key);
+
+ chunk_t keyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", key));
- chunk_t cert_req_info = asn1_wrap(ASN1_SEQUENCE, "ccmm"
- , ASN1_INTEGER_0
- , pkcs10->subject
- , pkcs1_build_publicKeyInfo(rsak)
- , build_req_info_attributes(pkcs10));
+ chunk_t cert_req_info = asn1_wrap(ASN1_SEQUENCE, "ccmm",
+ ASN1_INTEGER_0,
+ pkcs10->subject,
+ keyInfo,
+ build_req_info_attributes(pkcs10));
- chunk_t signature = pkcs1_build_signature(cert_req_info
- , signature_alg, pkcs10->private_key, TRUE);
+ chunk_t signature = x509_build_signature(cert_req_info, signature_alg,
+ pkcs10->private_key, TRUE);
- return asn1_wrap(ASN1_SEQUENCE, "mcm"
- , cert_req_info
- , asn1_algorithmIdentifier(signature_alg)
- , signature);
+ return asn1_wrap(ASN1_SEQUENCE, "mcm",
+ cert_req_info,
+ asn1_algorithmIdentifier(signature_alg),
+ signature);
}
/**
@@ -183,38 +186,39 @@ pkcs10_build_request(pkcs10_t *pkcs10, int signature_alg)
* (e.g. commonName, organization) are needed. An optional challenge
* password or some subjectAltNames may be included.
*
- * @param[in] key rsakey of type #rsakey_t
- * @param[in] subject DER-coded subject distinguished name
- * @param[in] challengePassword challenge password or empty_chunk
- * @param[in] subjectAltNames linked list of subjectAltNames or NULL
- * @return pointer to a #pkcs10_t object
+ * @param[in] key rsakey of type #rsakey_t
+ * @param[in] subject DER-coded subject distinguished name
+ * @param[in] challengePassword challenge password or chunk_empty
+ * @param[in] subjectAltNames linked list of subjectAltNames or NULL
+ * @return pointer to a #pkcs10_t object
*/
-pkcs10_t*
-pkcs10_build(RSA_private_key_t *key, chunk_t subject, chunk_t challengePassword
-, generalName_t *subjectAltNames, int signature_alg)
+pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
+ chunk_t subject, chunk_t challengePassword,
+ generalName_t *subjectAltNames, int signature_alg)
{
- pkcs10_t *pkcs10 = alloc_thing(pkcs10_t, "pkcs10_t");
+ pkcs10_t *pkcs10 = malloc_thing(pkcs10_t);
- pkcs10->subject = subject;
- pkcs10->private_key = key;
- pkcs10->challengePassword = challengePassword;
- pkcs10->subjectAltNames = subjectAltNames;
+ pkcs10->subject = subject;
+ pkcs10->private_key = private;
+ pkcs10->public_key = public;
+ pkcs10->challengePassword = challengePassword;
+ pkcs10->subjectAltNames = subjectAltNames;
- pkcs10->request = pkcs10_build_request(pkcs10, signature_alg);
- return pkcs10;
+ pkcs10->request = pkcs10_build_request(pkcs10, signature_alg);
+ return pkcs10;
}
/**
* @brief Frees the resources used by an #pkcs10_t object
*
- * @param[in] pkcs10 #pkcs10_t to free
+ * @param[in] pkcs10 #pkcs10_t to free
*/
void
pkcs10_free(pkcs10_t *pkcs10)
{
- if (pkcs10 != NULL)
- {
- freeanychunk(pkcs10->request);
- pfree(pkcs10);
- }
+ if (pkcs10 != NULL)
+ {
+ free(pkcs10->request.ptr);
+ free(pkcs10);
+ }
}
diff --git a/src/scepclient/pkcs10.h b/src/scepclient/pkcs10.h
index c2a4c1b92..3f29f019a 100644
--- a/src/scepclient/pkcs10.h
+++ b/src/scepclient/pkcs10.h
@@ -4,7 +4,7 @@
*
* Contains functions to build DER encoded pkcs#10 certificate requests
*/
-
+
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -23,8 +23,10 @@
#ifndef _PKCS10_H
#define _PKCS10_H
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
+
#include "../pluto/defs.h"
-#include "../pluto/pkcs1.h"
#include "../pluto/x509.h"
typedef struct pkcs10_struct pkcs10_t;
@@ -38,20 +40,21 @@ typedef struct pkcs10_struct pkcs10_t;
* The RSA private key is needed to compute the signature of the given request
*/
struct pkcs10_struct {
- RSA_private_key_t *private_key;
- chunk_t request;
- chunk_t subject;
- chunk_t challengePassword;
- generalName_t *subjectAltNames;
+ private_key_t *private_key;
+ public_key_t *public_key;
+ chunk_t request;
+ chunk_t subject;
+ chunk_t challengePassword;
+ generalName_t *subjectAltNames;
};
extern const pkcs10_t empty_pkcs10;
-extern void pkcs10_add_subjectAltName(generalName_t **subjectAltNames
- , generalNames_t kind, char *value);
-extern pkcs10_t* pkcs10_build(RSA_private_key_t *key, chunk_t subject
- , chunk_t challengePassword, generalName_t *subjectAltNames
- , int signature_alg);
+extern void pkcs10_add_subjectAltName(generalName_t **subjectAltNames,
+ generalNames_t kind, char *value);
+extern pkcs10_t* pkcs10_build(private_key_t *private, public_key_t *public,
+ chunk_t subject, chunk_t challengePassword,
+ generalName_t *subjectAltNames, int signature_alg);
extern void pkcs10_free(pkcs10_t *pkcs10);
#endif /* _PKCS10_H */
diff --git a/src/scepclient/rsakey.c b/src/scepclient/rsakey.c
deleted file mode 100644
index a7c6321f5..000000000
--- a/src/scepclient/rsakey.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * @file rsakey.c
- * @brief Functions for RSA key generation
- */
-
-/*
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * $Id: rsakey.c,v 1.5 2006/01/04 21:16:30 as Exp $
- */
-
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <gmp.h>
-
-#include <freeswan.h>
-
-#include "../pluto/constants.h"
-#include "../pluto/defs.h"
-#include "../pluto/mp_defs.h"
-#include "../pluto/log.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
-
-#include "rsakey.h"
-
-/* Number of times the probabilistic primality test is applied */
-#define PRIMECHECK_ROUNDS 30
-
-/* Public exponent used for signature key generation */
-#define PUBLIC_EXPONENT 0x10001
-
-#ifndef DEV_RANDOM
-#define DEV_RANDOM "/dev/random"
-#endif
-
-
-/**
- * @brief Reads a specific number of bytes from a given device/file
- *
- * @param[in] nbytes number of bytes to read from random device
- * @param[out] buf pointer to buffer where to write the data in.
- * size of buffer has to be at least nbytes.
- * @return TRUE, if succeeded, FALSE otherwise
- */
-
-static bool
-get_true_random_bytes(size_t nbytes, char *buf)
-{
- size_t ndone;
- size_t got;
- char *device = DEV_RANDOM;
-
- int dev = open(DEV_RANDOM, 0);
-
- if (dev < 0)
- {
- fprintf(stderr, "could not open random device %s", device);
- return FALSE;
- }
-
- DBG(DBG_CONTROL,
- DBG_log("getting %d bytes from %s...", (int) nbytes, device)
- )
-
- ndone = 0;
- while (ndone < nbytes)
- {
- got = read(dev, buf + ndone, nbytes - ndone);
- if (got < 0)
- {
- fprintf(stderr, "read error on %s", device);
- return FALSE;
- }
- if (got == 0)
- {
- fprintf(stderr, "eof on %s", device);
- return FALSE;
- }
- ndone += got;
- }
- close(dev);
- return TRUE;
-}
-
-/**
- * @brief initialize an mpz_t to a random number, specified bit count
- *
- * Converting the random value in a value of type mpz_t is done
- * by creating a hexbuffer.
- * Converting via hex is a bit weird, but it's the best route GMP gives us.
- * Note that highmost and lowmost bits are forced on -- highmost to give a
- * number of exactly the specified length, lowmost so it is an odd number.
- *
- * @param[out] var uninitialized mpz_t to store th random number in
- * @param[in] nbits length of var in bits (known to be a multiple of BITS_PER_BYTE)
- * @return TRUE on success, FALSE otherwise
- */
-static bool
-init_random(mpz_t var, int nbits)
-{
- size_t nbytes = (size_t)(nbits/BITS_PER_BYTE);
- char random_buf[RSA_MAX_OCTETS/2];
-
- assert(nbytes <= sizeof(random_buf));
-
- if (!get_true_random_bytes(nbytes, random_buf))
- return FALSE;
-
- random_buf[0] |= 01 << (BITS_PER_BYTE-1); /* force high bit on */
- random_buf[nbytes-1] |= 01; /* force low bit on */
- n_to_mpz(var, random_buf, nbytes);
- return TRUE;
-}
-
-/**
- * @brief initialize an mpz_t to a random prime of specified size
- *
- * Efficiency tweak: we reject candidates that are 1 higher than a multiple
- * of e, since they will make the internal modulus not relatively prime to e.
- *
- * @param[out] var mpz_t variable to initialize
- * @param[in] nbits length of given prime in bits (known to be a multiple of BITS_PER_BYTE)
- * @param[in] eval E-Value, 0 means don't bother w. tweak
- * @return 1 on success, 0 otherwise
- */
-static bool
-init_prime(mpz_t var, int nbits, int eval)
-{
- unsigned long tries;
- size_t len;
-
- /* get a random value of nbits length */
- if (!init_random(var, nbits))
- return FALSE;
-
- /* check if odd number */
- assert(mpz_fdiv_ui(var, 2) == 1);
- DBG(DBG_CONTROLMORE,
- DBG_log("looking for a prime starting there (can take a while)...")
- )
-
- tries = 1;
- while (mpz_fdiv_ui(var, eval) == 1
- || !mpz_probab_prime_p(var, PRIMECHECK_ROUNDS))
- {
- /* not a prime, increase by 2 */
- mpz_add_ui(var, var, 2);
- tries++;
- }
-
- len = mpz_sizeinbase(var, 2);
-
- /* check bit length of primee */
- assert(len == (size_t)nbits || len == (size_t)(nbits+1));
-
- if (len == (size_t)(nbits+1))
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("carry out occurred (!), retrying...")
- )
- mpz_clear(var);
- /* recursive call */
- return init_prime(var, nbits, eval);
- }
- DBG(DBG_CONTROLMORE,
- DBG_log("found it after %lu tries.",tries)
- )
- return TRUE;
-}
-
-/**
- * @brief Generate a RSA key usable for encryption
- *
- * Generate an RSA key usable for encryption. All the
- * values of the RSA key are filled into mpz_t parameters.
- * These mpz_t parameters must not be initialized and have
- * to be cleared with mpz_clear after using.
- *
- * @param[in] nbits size of rsa key in bits
- * @return RSA_public_key_t containing the generated RSA key
- */
-err_t
-generate_rsa_private_key(int nbits, RSA_private_key_t *key)
-{
- mpz_t p, q, n, e, d, exp1, exp2, coeff;
- mpz_t m, q1, t; /* temporary variables*/
-
- DBG(DBG_CONTROL,
- DBG_log("generating %d bit RSA key:", nbits)
- )
-
- if (nbits <= 0)
- return "negative rsa key length!";
-
- /* Get values of primes p and q */
- DBG(DBG_CONTROLMORE,
- DBG_log("initialize prime p")
- )
- if (!init_prime(p, nbits/2, PUBLIC_EXPONENT))
- return "could not generate prime p";
-
- DBG(DBG_CONTROLMORE,
- DBG_log("initialize prime q")
- )
- if (!init_prime(q, nbits/2, PUBLIC_EXPONENT))
- return "could not generate prime q";
-
- mpz_init(t);
-
- /* Swapping primes so p is larger then q */
- if (mpz_cmp(p, q) < 0)
- {
- DBG(DBG_CONTROLMORE,
- DBG_log("swapping primes so p is the larger...")
- );
- mpz_set(t, p);
- mpz_set(p, q);
- mpz_set(q, t);
- }
-
- DBG(DBG_CONTROLMORE,
- DBG_log("computing modulus...")
- )
- mpz_init(n);
- /* n = p*q */
- mpz_mul(n, p, q);
-
- /* Assign e the value of defined PUBLIC_EXPONENT */
- mpz_init_set_ui(e, PUBLIC_EXPONENT);
-
- DBG(DBG_CONTROLMORE,
- DBG_log("computing lcm(p-1, q-1)...")
- )
- /* m = p */
- mpz_init_set(m, p);
- /* m = m-1 */
- mpz_sub_ui(m, m, 1);
- /* q1 = q */
- mpz_init_set(q1, q);
- /* q1 = q1-1 */
- mpz_sub_ui(q1, q1, 1);
- /* t = gcd(p-1, q-1) */
- mpz_gcd(t, m, q1);
- /* m = (p-1)*(q-1) */
- mpz_mul(m, m, q1);
- /* m = m / t */
- mpz_divexact(m, m, t);
- /* t = gcd(m, e) (greatest common divisor) */
- mpz_gcd(t, m, e);
- /* m and e relatively prime */
- assert(mpz_cmp_ui(t, 1) == 0);
-
- /* decryption key */
- DBG(DBG_CONTROLMORE,
- DBG_log("computing d...")
- )
- mpz_init(d);
- /* e has an inverse mod m */
- assert(mpz_invert(d, e, m));
-
- /* make sure d is positive */
- if (mpz_cmp_ui(d, 0) < 0)
- mpz_add(d, d, m);
-
- /* d has to be positive */
- assert(mpz_cmp(d, m) < 0);
-
- /* the speedup hacks */
- DBG(DBG_CONTROLMORE,
- DBG_log("computing exp1, exp1, coeff...")
- )
- mpz_init(exp1);
- /* t = p-1 */
- mpz_sub_ui(t, p, 1);
- /* exp1 = d mod p-1 */
- mpz_mod(exp1, d, t);
-
- mpz_init(exp2);
- /* t = q-1 */
- mpz_sub_ui(t, q, 1);
- /* exp2 = d mod q-1 */
- mpz_mod(exp2, d, t);
-
- mpz_init(coeff);
- /* coeff = q^-1 mod p */
- mpz_invert(coeff, q, p);
-
- /* make sure coeff is positive */
- if (mpz_cmp_ui(coeff, 0) < 0)
- mpz_add(coeff, coeff, p);
-
- /* coeff has to be positive */
- assert(mpz_cmp(coeff, p) < 0);
-
- /* Clear temporary variables */
- mpz_clear(q1);
- mpz_clear(m);
- mpz_clear(t);
-
- /* form FreeS/WAN keyid */
- {
- size_t e_len = (mpz_sizeinbase(e,2)+BITS_PER_BYTE-1)/BITS_PER_BYTE;
- size_t n_len = (mpz_sizeinbase(n,2)+BITS_PER_BYTE-1)/BITS_PER_BYTE;
- chunk_t e_ch = mpz_to_n(e, e_len);
- chunk_t n_ch = mpz_to_n(n, n_len);
- form_keyid(e_ch, n_ch, key->pub.keyid, &key->pub.k);
- freeanychunk(e_ch);
- freeanychunk(n_ch);
- }
- /* fill in the elements of the RSA private key */
- key->p = *p;
- key->q = *q;
- key->pub.n = *n;
- key->pub.e = *e;
- key->d = *d;
- key->dP = *exp1;
- key->dQ = *exp2;
- key->qInv = *coeff;
-
- DBG(DBG_CONTROL,
- DBG_log("RSA key *%s generated with %d bits", key->pub.keyid
- , (int)mpz_sizeinbase(n,2))
- )
-
-#ifdef DEBUG
- DBG(DBG_PRIVATE,
- RSA_show_private_key(key)
- )
-#endif
- return NULL;
-}
diff --git a/src/scepclient/scep.c b/src/scepclient/scep.c
index 1b01044df..a788c6f41 100644
--- a/src/scepclient/scep.c
+++ b/src/scepclient/scep.c
@@ -24,575 +24,533 @@
#include <stdlib.h>
#include <freeswan.h>
-#include <asn1/oid.h>
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif
+#include <library.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+#include <crypto/rngs/rng.h>
+#include <crypto/hashers/hasher.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
-#include "../pluto/rnd.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
#include "../pluto/fetch.h"
#include "../pluto/log.h"
#include "scep.h"
static char ASN1_messageType_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02
+ 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x02
};
static char ASN1_senderNonce_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05
+ 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x05
};
static char ASN1_transId_oid_str[] = {
- 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07
+ 0x06, 0x0A, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x09, 0x07
};
static const chunk_t ASN1_messageType_oid =
- strchunk(ASN1_messageType_oid_str);
+ chunk_from_buf(ASN1_messageType_oid_str);
static const chunk_t ASN1_senderNonce_oid =
- strchunk(ASN1_senderNonce_oid_str);
+ chunk_from_buf(ASN1_senderNonce_oid_str);
static const chunk_t ASN1_transId_oid =
- strchunk(ASN1_transId_oid_str);
+ chunk_from_buf(ASN1_transId_oid_str);
static const char *pkiStatus_values[] = { "0", "2", "3" };
static const char *pkiStatus_names[] = {
- "SUCCESS",
- "FAILURE",
- "PENDING",
- "UNKNOWN"
+ "SUCCESS",
+ "FAILURE",
+ "PENDING",
+ "UNKNOWN"
};
static const char *msgType_values[] = { "3", "19", "20", "21", "22" };
static const char *msgType_names[] = {
- "CertRep",
- "PKCSReq",
- "GetCertInitial",
- "GetCert",
- "GetCRL",
- "Unknown"
+ "CertRep",
+ "PKCSReq",
+ "GetCertInitial",
+ "GetCert",
+ "GetCRL",
+ "Unknown"
};
static const char *failInfo_reasons[] = {
- "badAlg - unrecognized or unsupported algorithm identifier",
- "badMessageCheck - integrity check failed",
- "badRequest - transaction not permitted or supported",
- "badTime - Message time field was not sufficiently close to the system time",
- "badCertId - No certificate could be identified matching the provided criteria"
+ "badAlg - unrecognized or unsupported algorithm identifier",
+ "badMessageCheck - integrity check failed",
+ "badRequest - transaction not permitted or supported",
+ "badTime - Message time field was not sufficiently close to the system time",
+ "badCertId - No certificate could be identified matching the provided criteria"
};
const scep_attributes_t empty_scep_attributes = {
- SCEP_Unknown_MSG , /* msgType */
- SCEP_UNKNOWN , /* pkiStatus */
- SCEP_unknown_REASON, /* failInfo */
- { NULL, 0 } , /* transID */
- { NULL, 0 } , /* senderNonce */
- { NULL, 0 } , /* recipientNonce */
+ SCEP_Unknown_MSG , /* msgType */
+ SCEP_UNKNOWN , /* pkiStatus */
+ SCEP_unknown_REASON, /* failInfo */
+ { NULL, 0 } , /* transID */
+ { NULL, 0 } , /* senderNonce */
+ { NULL, 0 } , /* recipientNonce */
};
/* ASN.1 definition of the X.501 atttribute type */
static const asn1Object_t attributesObjects[] = {
- { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
- { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
- { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
+ { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
+ { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define ATTRIBUTE_OBJ_TYPE 2
+#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_TYPE 2
-#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_ROOF 7
-
-/*
- * extract and store an attribute
+/**
+ * Extract and store an attribute
*/
-static bool
-extract_attribute(int oid, chunk_t object, u_int level
-, scep_attributes_t *attrs)
+static bool extract_attribute(int oid, chunk_t object, u_int level,
+ scep_attributes_t *attrs)
{
- asn1_t type = ASN1_EOC;
- const char *name = "none";
-
- switch (oid)
- {
- case OID_PKCS9_CONTENT_TYPE:
- type = ASN1_OID;
- name = "contentType";
- break;
- case OID_PKCS9_SIGNING_TIME:
- type = ASN1_UTCTIME;
- name = "signingTime";
- break;
- case OID_PKCS9_MESSAGE_DIGEST:
- type = ASN1_OCTET_STRING;
- name = "messageDigest";
- break;
- case OID_PKI_MESSAGE_TYPE:
- type = ASN1_PRINTABLESTRING;
- name = "messageType";
- break;
- case OID_PKI_STATUS:
- type = ASN1_PRINTABLESTRING;
- name = "pkiStatus";
- break;
- case OID_PKI_FAIL_INFO:
- type = ASN1_PRINTABLESTRING;
- name = "failInfo";
- break;
- case OID_PKI_SENDER_NONCE:
- type = ASN1_OCTET_STRING;
- name = "senderNonce";
- break;
- case OID_PKI_RECIPIENT_NONCE:
- type = ASN1_OCTET_STRING;
- name = "recipientNonce";
- break;
- case OID_PKI_TRANS_ID:
- type = ASN1_PRINTABLESTRING;
- name = "transID";
- break;
- default:
- break;
- }
-
- if (type == ASN1_EOC)
- return TRUE;
+ asn1_t type = ASN1_EOC;
+ const char *name = "none";
- if (!parse_asn1_simple_object(&object, type, level+1, name))
- return FALSE;
-
- switch (oid)
- {
- case OID_PKCS9_CONTENT_TYPE:
- break;
- case OID_PKCS9_SIGNING_TIME:
- break;
- case OID_PKCS9_MESSAGE_DIGEST:
- break;
- case OID_PKI_MESSAGE_TYPE:
- {
- scep_msg_t m;
-
- for (m = SCEP_CertRep_MSG; m < SCEP_Unknown_MSG; m++)
- {
- if (strncmp(msgType_values[m], object.ptr, object.len) == 0)
- attrs->msgType = m;
- }
- DBG(DBG_CONTROL,
- DBG_log("messageType: %s", msgType_names[attrs->msgType])
- )
- }
- break;
- case OID_PKI_STATUS:
+ switch (oid)
{
- pkiStatus_t s;
-
- for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
- {
- if (strncmp(pkiStatus_values[s], object.ptr, object.len) == 0)
- attrs->pkiStatus = s;
- }
- DBG(DBG_CONTROL,
- DBG_log("pkiStatus: %s", pkiStatus_names[attrs->pkiStatus])
- )
+ case OID_PKCS9_CONTENT_TYPE:
+ type = ASN1_OID;
+ name = "contentType";
+ break;
+ case OID_PKCS9_SIGNING_TIME:
+ type = ASN1_UTCTIME;
+ name = "signingTime";
+ break;
+ case OID_PKCS9_MESSAGE_DIGEST:
+ type = ASN1_OCTET_STRING;
+ name = "messageDigest";
+ break;
+ case OID_PKI_MESSAGE_TYPE:
+ type = ASN1_PRINTABLESTRING;
+ name = "messageType";
+ break;
+ case OID_PKI_STATUS:
+ type = ASN1_PRINTABLESTRING;
+ name = "pkiStatus";
+ break;
+ case OID_PKI_FAIL_INFO:
+ type = ASN1_PRINTABLESTRING;
+ name = "failInfo";
+ break;
+ case OID_PKI_SENDER_NONCE:
+ type = ASN1_OCTET_STRING;
+ name = "senderNonce";
+ break;
+ case OID_PKI_RECIPIENT_NONCE:
+ type = ASN1_OCTET_STRING;
+ name = "recipientNonce";
+ break;
+ case OID_PKI_TRANS_ID:
+ type = ASN1_PRINTABLESTRING;
+ name = "transID";
+ break;
+ default:
+ break;
}
- break;
- case OID_PKI_FAIL_INFO:
- if (object.len == 1
- && *object.ptr >= '0' && *object.ptr <= '4')
+
+ if (type == ASN1_EOC)
+ return TRUE;
+
+ if (!asn1_parse_simple_object(&object, type, level+1, name))
+ return FALSE;
+
+ switch (oid)
{
- attrs->failInfo = (failInfo_t)(*object.ptr - '0');
+ case OID_PKCS9_CONTENT_TYPE:
+ break;
+ case OID_PKCS9_SIGNING_TIME:
+ break;
+ case OID_PKCS9_MESSAGE_DIGEST:
+ break;
+ case OID_PKI_MESSAGE_TYPE:
+ {
+ scep_msg_t m;
+
+ for (m = SCEP_CertRep_MSG; m < SCEP_Unknown_MSG; m++)
+ {
+ if (strncmp(msgType_values[m], object.ptr, object.len) == 0)
+ attrs->msgType = m;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("messageType: %s", msgType_names[attrs->msgType])
+ )
+ }
+ break;
+ case OID_PKI_STATUS:
+ {
+ pkiStatus_t s;
+
+ for (s = SCEP_SUCCESS; s < SCEP_UNKNOWN; s++)
+ {
+ if (strncmp(pkiStatus_values[s], object.ptr, object.len) == 0)
+ attrs->pkiStatus = s;
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("pkiStatus: %s", pkiStatus_names[attrs->pkiStatus])
+ )
+ }
+ break;
+ case OID_PKI_FAIL_INFO:
+ if (object.len == 1
+ && *object.ptr >= '0' && *object.ptr <= '4')
+ {
+ attrs->failInfo = (failInfo_t)(*object.ptr - '0');
+ }
+ if (attrs->failInfo != SCEP_unknown_REASON)
+ plog("failInfo: %s", failInfo_reasons[attrs->failInfo]);
+ break;
+ case OID_PKI_SENDER_NONCE:
+ attrs->senderNonce = object;
+ break;
+ case OID_PKI_RECIPIENT_NONCE:
+ attrs->recipientNonce = object;
+ break;
+ case OID_PKI_TRANS_ID:
+ attrs->transID = object;
}
- if (attrs->failInfo != SCEP_unknown_REASON)
- plog("failInfo: %s", failInfo_reasons[attrs->failInfo]);
- break;
- case OID_PKI_SENDER_NONCE:
- attrs->senderNonce = object;
- break;
- case OID_PKI_RECIPIENT_NONCE:
- attrs->recipientNonce = object;
- break;
- case OID_PKI_TRANS_ID:
- attrs->transID = object;
- }
- return TRUE;
+ return TRUE;
}
-/*
- * parse X.501 attributes
+/**
+ * Parse X.501 attributes
*/
-bool
-parse_attributes(chunk_t blob, scep_attributes_t *attrs)
+bool parse_attributes(chunk_t blob, scep_attributes_t *attrs)
{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int oid = OID_UNKNOWN;
- int objectID = 0;
-
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
-
- DBG(DBG_CONTROL | DBG_PARSING,
- DBG_log("parsing attributes")
- )
- while (objectID < ATTRIBUTE_OBJ_ROOF)
- {
- if (!extract_object(attributesObjects, &objectID
- , &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
+ asn1_parser_t *parser;
+ chunk_t object;
+ int oid = OID_UNKNOWN;
+ int objectID;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(attributesObjects, blob);
+ DBG(DBG_CONTROL | DBG_PARSING,
+ DBG_log("parsing attributes")
+ )
+
+ while (parser->iterate(parser, &objectID, &object))
{
- case ATTRIBUTE_OBJ_TYPE:
- oid = known_oid(object);
- break;
- case ATTRIBUTE_OBJ_VALUE:
- if (!extract_attribute(oid, object, level, attrs))
- return FALSE;
+ switch (objectID)
+ {
+ case ATTRIBUTE_OBJ_TYPE:
+ oid = asn1_known_oid(object);
+ break;
+ case ATTRIBUTE_OBJ_VALUE:
+ if (!extract_attribute(oid, object, parser->get_level(parser), attrs))
+ {
+ goto end;
+ }
+ }
}
- objectID++;
- }
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
-/* generates a unique fingerprint of the pkcs10 request
+/**
+ * Generates a unique fingerprint of the pkcs10 request
* by computing an MD5 hash over it
*/
-void
-scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
+chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10)
{
- char buf[MD5_DIGEST_SIZE];
- chunk_t digest = { buf, sizeof(buf) };
-
- /* the fingerprint is the MD5 hash in hexadecimal format */
- compute_digest(pkcs10, OID_MD5, &digest);
- fingerprint->len = 2*digest.len;
- fingerprint->ptr = alloc_bytes(fingerprint->len + 1, "fingerprint");
- datatot(digest.ptr, digest.len, 16, fingerprint->ptr, fingerprint->len + 1);
+ char digest_buf[HASH_SIZE_MD5];
+ chunk_t digest = chunk_from_buf(digest_buf);
+ hasher_t *hasher;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ hasher->get_hash(hasher, pkcs10, digest_buf);
+ hasher->destroy(hasher);
+
+ return chunk_to_hex(digest, NULL, FALSE);
}
-/* generate a transaction id as the MD5 hash of an public key
+/**
+ * Generate a transaction id as the MD5 hash of an public key
* the transaction id is also used as a unique serial number
*/
-void
-scep_generate_transaction_id(const RSA_public_key_t *rsak
-, chunk_t *transID, chunk_t *serialNumber)
+void scep_generate_transaction_id(public_key_t *key, chunk_t *transID,
+ chunk_t *serialNumber)
{
- char buf[MD5_DIGEST_SIZE];
-
- chunk_t digest = { buf, sizeof(buf) };
- chunk_t public_key = pkcs1_build_publicKeyInfo(rsak);
+ char digest_buf[HASH_SIZE_MD5];
+ chunk_t digest = chunk_from_buf(digest_buf);
+ chunk_t keyEncoding, keyInfo;
+ hasher_t *hasher;
+ bool msb_set;
+ u_char *pos;
+
+ keyEncoding = key->get_encoding(key);
- bool msb_set;
- u_char *pos;
+ keyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
+ asn1_bitstring("m", keyEncoding));
- compute_digest(public_key, OID_MD5, &digest);
- pfree(public_key.ptr);
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+ hasher->get_hash(hasher, keyInfo, digest_buf);
+ hasher->destroy(hasher);
+ free(keyInfo.ptr);
- /* is the most significant bit of the digest set? */
- msb_set = (*digest.ptr & 0x80) == 0x80;
+ /* is the most significant bit of the digest set? */
+ msb_set = (*digest.ptr & 0x80) == 0x80;
- /* allocate space for the serialNumber */
- serialNumber->len = msb_set + digest.len;
- serialNumber->ptr = alloc_bytes(serialNumber->len, "serialNumber");
+ /* allocate space for the serialNumber */
+ serialNumber->len = msb_set + digest.len;
+ serialNumber->ptr = malloc(serialNumber->len);
- /* the serial number as the two's complement of the digest */
- pos = serialNumber->ptr;
- if (msb_set)
- {
- *pos++ = 0x00;
- }
- memcpy(pos, digest.ptr, digest.len);
+ /* the serial number as the two's complement of the digest */
+ pos = serialNumber->ptr;
+ if (msb_set)
+ {
+ *pos++ = 0x00;
+ }
+ memcpy(pos, digest.ptr, digest.len);
- /* the transaction id is the serial number in hex format */
- transID->len = 2*digest.len;
- transID->ptr = alloc_bytes(transID->len + 1, "transID");
- datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
+ /* the transaction id is the serial number in hex format */
+ transID->len = 2*digest.len;
+ transID->ptr = malloc(transID->len + 1);
+ datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
}
-/*
- * builds a transId attribute
+/**
+ * Builds a transId attribute
*/
-chunk_t
-scep_transId_attribute(chunk_t transID)
+chunk_t scep_transId_attribute(chunk_t transID)
{
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_transId_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_PRINTABLESTRING, transID)
- )
- );
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_transId_oid
+ , asn1_wrap(ASN1_SET, "m"
+ , asn1_simple_object(ASN1_PRINTABLESTRING, transID)
+ )
+ );
}
-/*
- * builds a messageType attribute
+/**
+ * Builds a messageType attribute
*/
-chunk_t
-scep_messageType_attribute(scep_msg_t m)
+chunk_t scep_messageType_attribute(scep_msg_t m)
{
- chunk_t msgType = {
- (u_char*)msgType_values[m],
- strlen(msgType_values[m])
- };
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_messageType_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_PRINTABLESTRING, msgType)
- )
- );
+ chunk_t msgType = {
+ (u_char*)msgType_values[m],
+ strlen(msgType_values[m])
+ };
+
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_messageType_oid
+ , asn1_wrap(ASN1_SET, "m"
+ , asn1_simple_object(ASN1_PRINTABLESTRING, msgType)
+ )
+ );
}
-/*
- * builds a senderNonce attribute
+/**
+ * Builds a senderNonce attribute
*/
-chunk_t
-scep_senderNonce_attribute(void)
+chunk_t scep_senderNonce_attribute(void)
{
- const size_t nonce_len = 16;
- u_char nonce_buf[nonce_len];
- chunk_t senderNonce = { nonce_buf, nonce_len };
-
- get_rnd_bytes(nonce_buf, nonce_len);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_senderNonce_oid
- , asn1_wrap(ASN1_SET, "m"
- , asn1_simple_object(ASN1_OCTET_STRING, senderNonce)
- )
- );
+ const size_t nonce_len = 16;
+ u_char nonce_buf[nonce_len];
+ chunk_t senderNonce = { nonce_buf, nonce_len };
+ rng_t *rng;
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ rng->get_bytes(rng, nonce_len, nonce_buf);
+ rng->destroy(rng);
+
+ return asn1_wrap(ASN1_SEQUENCE, "cm"
+ , ASN1_senderNonce_oid
+ , asn1_wrap(ASN1_SET, "m"
+ , asn1_simple_object(ASN1_OCTET_STRING, senderNonce)
+ )
+ );
}
-/*
- * builds a pkcs7 enveloped and signed scep request
+/**
+ * Builds a pkcs7 enveloped and signed scep request
*/
-chunk_t
-scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
-, const x509cert_t *enc_cert, int enc_alg
-, const x509cert_t *signer_cert, int digest_alg
-, const RSA_private_key_t *private_key)
+chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
+ const x509cert_t *enc_cert, int enc_alg,
+ const x509cert_t *signer_cert, int digest_alg,
+ private_key_t *private_key)
{
- chunk_t envelopedData, attributes, request;
-
- envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);
-
- attributes = asn1_wrap(ASN1_SET, "mmmmm"
- , pkcs7_contentType_attribute()
- , pkcs7_messageDigest_attribute(envelopedData
- , digest_alg)
- , scep_transId_attribute(transID)
- , scep_messageType_attribute(msg)
- , scep_senderNonce_attribute());
-
- request = pkcs7_build_signedData(envelopedData, attributes
- , signer_cert, digest_alg, private_key);
- freeanychunk(envelopedData);
- freeanychunk(attributes);
- return request;
+ chunk_t envelopedData, attributes, request;
+
+ envelopedData = pkcs7_build_envelopedData(data, enc_cert, enc_alg);
+
+ attributes = asn1_wrap(ASN1_SET, "mmmmm"
+ , pkcs7_contentType_attribute()
+ , pkcs7_messageDigest_attribute(envelopedData
+ , digest_alg)
+ , scep_transId_attribute(transID)
+ , scep_messageType_attribute(msg)
+ , scep_senderNonce_attribute());
+
+ request = pkcs7_build_signedData(envelopedData, attributes
+ , signer_cert, digest_alg, private_key);
+ free(envelopedData.ptr);
+ free(attributes.ptr);
+ return request;
}
-#ifdef LIBCURL
-/* converts a binary request to base64 with 64 characters per line
+/**
+ * Converts a binary request to base64 with 64 characters per line
* newline and '+' characters are escaped by %0A and %2B, respectively
*/
-static char*
-escape_http_request(chunk_t req)
+static char* escape_http_request(chunk_t req)
{
- char *escaped_req = NULL;
- char *p1, *p2;
- int lines = 0;
- int plus = 0;
- int n = 0;
-
- /* compute and allocate the size of the base64-encoded request */
- int len = 1 + 4*((req.len + 2)/3);
- char *encoded_req = alloc_bytes(len, "encoded request");
-
- /* do the base64 conversion */
- len = datatot(req.ptr, req.len, 64, encoded_req, len);
-
- /* compute newline characters to be inserted every 64 characters */
- lines = (len - 2) / 64;
-
- /* count number of + characters to be escaped */
- p1 = encoded_req;
- while (*p1 != '\0')
- {
- if (*p1++ == '+')
- plus++;
- }
-
- escaped_req = alloc_bytes(len + 3*(lines + plus), "escaped request");
-
- /* escape special characters in the request */
- p1 = encoded_req;
- p2 = escaped_req;
- while (*p1 != '\0')
- {
- if (n == 64)
- {
- memcpy(p2, "%0A", 3);
- p2 += 3;
- n = 0;
- }
- if (*p1 == '+')
+ char *escaped_req = NULL;
+ char *p1, *p2;
+ int lines = 0;
+ int plus = 0;
+ int n = 0;
+
+ /* compute and allocate the size of the base64-encoded request */
+ int len = 1 + 4*((req.len + 2)/3);
+ char *encoded_req = malloc(len);
+
+ /* do the base64 conversion */
+ len = datatot(req.ptr, req.len, 64, encoded_req, len);
+
+ /* compute newline characters to be inserted every 64 characters */
+ lines = (len - 2) / 64;
+
+ /* count number of + characters to be escaped */
+ p1 = encoded_req;
+ while (*p1 != '\0')
{
- memcpy(p2, "%2B", 3);
- p2 += 3;
+ if (*p1++ == '+')
+ plus++;
}
- else
+
+ escaped_req = malloc(len + 3*(lines + plus));
+
+ /* escape special characters in the request */
+ p1 = encoded_req;
+ p2 = escaped_req;
+ while (*p1 != '\0')
{
- *p2++ = *p1;
+ if (n == 64)
+ {
+ memcpy(p2, "%0A", 3);
+ p2 += 3;
+ n = 0;
+ }
+ if (*p1 == '+')
+ {
+ memcpy(p2, "%2B", 3);
+ p2 += 3;
+ }
+ else
+ {
+ *p2++ = *p1;
+ }
+ p1++;
+ n++;
}
- p1++;
- n++;
- }
- *p2 = '\0';
- pfreeany(encoded_req);
- return escaped_req;
+ *p2 = '\0';
+ free(encoded_req);
+ return escaped_req;
}
-#endif
-/*
- * send a SCEP request via HTTP and wait for a response
+/**
+ * Send a SCEP request via HTTP and wait for a response
*/
-bool
-scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
-, fetch_request_t req_type, chunk_t *response)
+bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
+ bool http_get_request, chunk_t *response)
{
-#ifdef LIBCURL
- char errorbuffer[CURL_ERROR_SIZE] = "";
- char *complete_url = NULL;
- struct curl_slist *headers = NULL;
- CURL *curl;
- CURLcode res;
-
- /* initialize response */
- *response = empty_chunk;
-
- /* initialize curl context */
- curl = curl_easy_init();
- if (curl == NULL)
- {
- plog("could not initialize curl context");
- return FALSE;
- }
-
- if (op == SCEP_PKI_OPERATION)
- {
- const char operation[] = "PKIOperation";
-
- if (req_type == FETCH_GET)
+ int len;
+ status_t status;
+ char *complete_url = NULL;
+
+ /* initialize response */
+ *response = chunk_empty;
+
+ DBG(DBG_CONTROL,
+ DBG_log("sending scep request to '%s'", url)
+ )
+
+ if (op == SCEP_PKI_OPERATION)
{
- char *escaped_req = escape_http_request(pkcs7);
-
- /* form complete url */
- int len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s&message=%s"
- , url, operation, escaped_req);
- pfreeany(escaped_req);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
- headers = curl_slist_append(headers, "Pragma:");
- headers = curl_slist_append(headers, "Host:");
- headers = curl_slist_append(headers, "Accept:");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ const char operation[] = "PKIOperation";
+
+ if (http_get_request)
+ {
+ char *escaped_req = escape_http_request(pkcs7);
+
+ /* form complete url */
+ len = strlen(url) + 20 + strlen(operation) + strlen(escaped_req) + 1;
+ complete_url = malloc(len);
+ snprintf(complete_url, len, "%s?operation=%s&message=%s"
+ , url, operation, escaped_req);
+ free(escaped_req);
+
+ status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
+ FETCH_HTTP_VERSION_1_0,
+ FETCH_REQUEST_HEADER, "Pragma:",
+ FETCH_REQUEST_HEADER, "Host:",
+ FETCH_REQUEST_HEADER, "Accept:",
+ FETCH_END);
+ }
+ else /* HTTP_POST */
+ {
+ /* form complete url */
+ len = strlen(url) + 11 + strlen(operation) + 1;
+ complete_url = malloc(len);
+ snprintf(complete_url, len, "%s?operation=%s", url, operation);
+
+ status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
+ FETCH_REQUEST_DATA, pkcs7,
+ FETCH_REQUEST_TYPE, "",
+ FETCH_REQUEST_HEADER, "Expect:",
+ FETCH_END);
+ }
}
- else /* HTTP_POST */
+ else /* SCEP_GET_CA_CERT */
{
- /* form complete url */
- int len = strlen(url) + 11 + strlen(operation) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s", url, operation);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, FALSE);
- headers = curl_slist_append(headers, "Content-Type:");
- headers = curl_slist_append(headers, "Expect:");
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char*)pkcs7.ptr);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, pkcs7.len);
+ const char operation[] = "GetCACert";
+
+ /* form complete url */
+ len = strlen(url) + 32 + strlen(operation) + 1;
+ complete_url = malloc(len);
+ snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
+ , url, operation);
+
+ status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
+ FETCH_END);
}
- }
- else /* SCEP_GET_CA_CERT */
- {
- const char operation[] = "GetCACert";
-
- /* form complete url */
- int len = strlen(url) + 32 + strlen(operation) + 1;
-
- complete_url = alloc_bytes(len, "complete url");
- snprintf(complete_url, len, "%s?operation=%s&message=CAIdentifier"
- , url, operation);
-
- curl_easy_setopt(curl, CURLOPT_HTTPGET, TRUE);
- }
-
- curl_easy_setopt(curl, CURLOPT_URL, complete_url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_buffer);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response);
- curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
- curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE);
- curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, FETCH_CMD_TIMEOUT);
-
- DBG(DBG_CONTROL,
- DBG_log("sending scep request to '%s'", url)
- )
- res = curl_easy_perform(curl);
-
- if (res == CURLE_OK)
- {
- DBG(DBG_CONTROL,
- DBG_log("received scep response")
- )
- DBG(DBG_RAW,
- DBG_dump_chunk("SCEP response:\n", *response)
- )
- }
- else
- {
- plog("failed to fetch scep response from '%s': %s", url, errorbuffer);
- }
- curl_slist_free_all(headers);
- curl_easy_cleanup(curl);
- pfreeany(complete_url);
-
- return (res == CURLE_OK);
-#else /* !LIBCURL */
- plog("scep error: pluto wasn't compiled with libcurl support");
- return FALSE;
-#endif /* !LIBCURL */
+
+ free(complete_url);
+ return (status == SUCCESS);
}
-err_t
-scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data
-, scep_attributes_t *attrs, x509cert_t *signer_cert)
+err_t scep_parse_response(chunk_t response, chunk_t transID, contentInfo_t *data,
+ scep_attributes_t *attrs, x509cert_t *signer_cert)
{
- chunk_t attributes;
-
- if (!pkcs7_parse_signedData(response, data, NULL, &attributes, signer_cert))
- {
- return "error parsing the scep response";
- }
- if (!parse_attributes(attributes, attrs))
- {
- return "error parsing the scep response attributes";
- }
- if (!same_chunk(transID, attrs->transID))
- {
- return "transaction ID of scep response does not match";
- }
- return NULL;
+ chunk_t attributes;
+
+ if (!pkcs7_parse_signedData(response, data, NULL, &attributes, signer_cert))
+ {
+ return "error parsing the scep response";
+ }
+ if (!parse_attributes(attributes, attrs))
+ {
+ return "error parsing the scep response attributes";
+ }
+ if (!chunk_equals(transID, attrs->transID))
+ {
+ return "transaction ID of scep response does not match";
+ }
+ return NULL;
}
diff --git a/src/scepclient/scep.h b/src/scepclient/scep.h
index 81e5d1a4b..e8dc87591 100644
--- a/src/scepclient/scep.h
+++ b/src/scepclient/scep.h
@@ -4,7 +4,7 @@
*
* Contains functions to build and parse SCEP requests and replies
*/
-
+
/*
* Copyright (C) 2005 Jan Hutter, Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -19,18 +19,17 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
-
+
#ifndef _SCEP_H
#define _SCEP_H
#include "../pluto/defs.h"
-#include "../pluto/pkcs1.h"
#include "../pluto/pkcs7.h"
/* supported SCEP operation types */
typedef enum {
- SCEP_PKI_OPERATION,
- SCEP_GET_CA_CERT
+ SCEP_PKI_OPERATION,
+ SCEP_GET_CA_CERT
} scep_op_t;
/* SCEP pkiStatus values */
@@ -63,31 +62,32 @@ typedef enum {
/* SCEP attributes */
typedef struct {
- scep_msg_t msgType;
- pkiStatus_t pkiStatus;
- failInfo_t failInfo;
- chunk_t transID;
- chunk_t senderNonce;
- chunk_t recipientNonce;
+ scep_msg_t msgType;
+ pkiStatus_t pkiStatus;
+ failInfo_t failInfo;
+ chunk_t transID;
+ chunk_t senderNonce;
+ chunk_t recipientNonce;
} scep_attributes_t;
extern const scep_attributes_t empty_scep_attributes;
extern bool parse_attributes(chunk_t blob, scep_attributes_t *attrs);
-extern void scep_generate_pkcs10_fingerprint(chunk_t pkcs10
- , chunk_t *fingerprint);
-extern void scep_generate_transaction_id(const RSA_public_key_t *rsak
- , chunk_t *transID, chunk_t *serialNumber);
+extern void scep_generate_transaction_id(public_key_t *key,
+ chunk_t *transID,
+ chunk_t *serialNumber);
+extern chunk_t scep_generate_pkcs10_fingerprint(chunk_t pkcs10);
extern chunk_t scep_transId_attribute(chunk_t transaction_id);
extern chunk_t scep_messageType_attribute(scep_msg_t m);
extern chunk_t scep_senderNonce_attribute(void);
-extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg
- , const x509cert_t *enc_cert, int enc_alg
- , const x509cert_t *signer_cert, int digest_alg
- , const RSA_private_key_t *private_key);
-extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op
- , fetch_request_t request_type, chunk_t *response);
-extern err_t scep_parse_response(chunk_t response, chunk_t transID
- , contentInfo_t *data, scep_attributes_t *attrs, x509cert_t *signer_cert);
+extern chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
+ const x509cert_t *enc_cert, int enc_alg,
+ const x509cert_t *signer_cert, int digest_alg,
+ private_key_t *private_key);
+extern bool scep_http_request(const char *url, chunk_t pkcs7, scep_op_t op,
+ bool http_get_request, chunk_t *response);
+extern err_t scep_parse_response(chunk_t response, chunk_t transID,
+ contentInfo_t *data, scep_attributes_t *attrs,
+ x509cert_t *signer_cert);
#endif /* _SCEP_H */
diff --git a/src/scepclient/scepclient.8 b/src/scepclient/scepclient.8
index 0d6364ef2..d9bf8e4cc 100644
--- a/src/scepclient/scepclient.8
+++ b/src/scepclient/scepclient.8
@@ -152,7 +152,13 @@ Supported values for \fIalgo\fP:
.IP "\fBdes\-cbc\fP" 12
DES CBC encryption (key size = 56 bit).
.IP "\fB3des\-cbc\fP" 12
-Triple DES CBC encryption (key size = 168 bit).
+Triple DES-EDE-CBC encryption (key size = 168 bit).
+.IP "\fBaes128\-cbc\fP" 12
+AES-CBC encryption (key size = 128 bit).
+.IP "\fBaes192\-cbc\fP" 12
+AES-CBC encryption (key size = 192 bit).
+.IP "\fBaes256\-cbc\fP" 12
+AES-CBC encryption (key size = 256 bit).
.RE
.PP
.B \-o, \-\-out \fItype\fP[=\fIfilename\fP]
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index f4afe0b8f..0e7ae3e40 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -32,22 +32,24 @@
#include <ctype.h>
#include <unistd.h>
#include <time.h>
-#include <gmp.h>
#include <freeswan.h>
+
+#include <library.h>
+#include <debug.h>
+#include <asn1/asn1.h>
#include <asn1/oid.h>
+#include <utils/optionsfrom.h>
+#include <utils/enumerator.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/public_key.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/log.h"
-#include "../pluto/asn1.h"
-#include "../pluto/pkcs1.h"
#include "../pluto/pkcs7.h"
#include "../pluto/certs.h"
-#include "../pluto/fetch.h"
-#include "../pluto/rnd.h"
-#include "rsakey.h"
#include "pkcs10.h"
#include "scep.h"
@@ -56,37 +58,37 @@
*/
/* default name of DER-encoded PKCS#1 private key file */
-#define DEFAULT_FILENAME_PKCS1 "myKey.der"
+#define DEFAULT_FILENAME_PKCS1 "myKey.der"
/* default name of DER-encoded PKCS#10 certificate request file */
-#define DEFAULT_FILENAME_PKCS10 "myReq.der"
+#define DEFAULT_FILENAME_PKCS10 "myReq.der"
/* default name of DER-encoded PKCS#7 file */
-#define DEFAULT_FILENAME_PKCS7 "pkcs7.der"
+#define DEFAULT_FILENAME_PKCS7 "pkcs7.der"
/* default name of DER-encoded self-signed X.509 certificate file */
-#define DEFAULT_FILENAME_CERT_SELF "selfCert.der"
+#define DEFAULT_FILENAME_CERT_SELF "selfCert.der"
/* default name of DER-encoded X.509 certificate file */
-#define DEFAULT_FILENAME_CERT "myCert.der"
+#define DEFAULT_FILENAME_CERT "myCert.der"
/* default name of DER-encoded CA cert file used for key encipherment */
-#define DEFAULT_FILENAME_CACERT_ENC "caCert.der"
+#define DEFAULT_FILENAME_CACERT_ENC "caCert.der"
/* default name of the der encoded CA cert file used for signature verification */
-#define DEFAULT_FILENAME_CACERT_SIG "caCert.der"
+#define DEFAULT_FILENAME_CACERT_SIG "caCert.der"
/* default prefix of the der encoded CA certificates received from the SCEP server */
-#define DEFAULT_FILENAME_PREFIX_CACERT "caCert.der"
+#define DEFAULT_FILENAME_PREFIX_CACERT "caCert.der"
/* default certificate validity */
-#define DEFAULT_CERT_VALIDITY 5 * 3600 * 24 * 365 /* seconds */
+#define DEFAULT_CERT_VALIDITY 5 * 3600 * 24 * 365 /* seconds */
/* default polling time interval in SCEP manual mode */
-#define DEFAULT_POLL_INTERVAL 20 /* seconds */
+#define DEFAULT_POLL_INTERVAL 20 /* seconds */
/* default key length for self-generated RSA keys */
-#define DEFAULT_RSA_KEY_LENGTH 2048 /* bits */
+#define DEFAULT_RSA_KEY_LENGTH 2048 /* bits */
/* default distinguished name */
#define DEFAULT_DN "C=CH, O=Linux strongSwan, CN="
@@ -110,12 +112,15 @@ long crl_check_interval = 0;
/* by default pluto logs out after every smartcard use */
bool pkcs11_keep_state = FALSE;
+/* options read by optionsfrom */
+options_t *options;
/*
* Global variables
*/
-RSA_private_key_t *private_key = NULL;
+private_key_t *private_key = NULL;
+public_key_t *public_key = NULL;
chunk_t pkcs1;
chunk_t pkcs7;
@@ -138,58 +143,52 @@ pkcs10_t *pkcs10 = NULL;
/**
* @brief exit scepclient
*
- * The log is closed and leaks are reported
- * if LEAK_DETECTIVE is activated
- *
* @param status 0 = OK, 1 = general discomfort
*/
static void
exit_scepclient(err_t message, ...)
{
- if (private_key != NULL)
- {
- free_RSA_private_content(private_key);
- pfree(private_key);
- }
- freeanychunk(pkcs1);
- freeanychunk(pkcs7);
- freeanychunk(subject);
- freeanychunk(serialNumber);
- freeanychunk(transID);
- freeanychunk(fingerprint);
- freeanychunk(issuerAndSubject);
- freeanychunk(getCertInitial);
- if (scep_response.ptr != NULL)
+ int status = 0;
+
+ DESTROY_IF(private_key);
+ DESTROY_IF(public_key);
+ free(pkcs1.ptr);
+ free(pkcs7.ptr);
+ free(subject.ptr);
+ free(serialNumber.ptr);
+ free(transID.ptr);
+ free(fingerprint.ptr);
+ free(issuerAndSubject.ptr);
+ free(getCertInitial.ptr);
free(scep_response.ptr);
- free_generalNames(subjectAltNames, TRUE);
- if (x509_signer != NULL)
- x509_signer->subjectAltName = NULL;
-
- free_x509cert(x509_signer);
- free_x509cert(x509_ca_enc);
- free_x509cert(x509_ca_sig);
- pkcs10_free(pkcs10);
-
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
-
- /* print any error message to stderr */
- if (message != NULL && *message != '\0')
- {
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- fprintf(stderr, "error: %s\n", m);
- exit(-1);
- }
- exit(0);
+ free_generalNames(subjectAltNames, TRUE);
+ if (x509_signer != NULL)
+ {
+ x509_signer->subjectAltName = NULL;
+ }
+ free_x509cert(x509_signer);
+ free_x509cert(x509_ca_enc);
+ free_x509cert(x509_ca_sig);
+ pkcs10_free(pkcs10);
+ options->destroy(options);
+
+ /* print any error message to stderr */
+ if (message != NULL && *message != '\0')
+ {
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ fprintf(stderr, "error: %s\n", m);
+ status = -1;
+ }
+ library_deinit();
+ close_log();
+ exit(status);
}
/**
@@ -199,8 +198,8 @@ exit_scepclient(err_t message, ...)
static void
version(void)
{
- printf("scepclient %s\n", scepclient_version);
- exit_scepclient(NULL);
+ printf("scepclient %s\n", scepclient_version);
+ exit_scepclient(NULL);
}
/**
@@ -212,61 +211,81 @@ version(void)
static void
usage(const char *message)
{
- fprintf(stderr,
- "Usage: scepclient\n"
- " --help (-h) show usage and exit\n"
- " --version (-v) show version and exit\n"
- " --quiet (-q) do not write log output to stderr\n"
- " --in (-i) <type>[=<filename>] use <filename> of <type> for input \n"
- " <type> = pkcs1 | cacert-enc | cacert-sig\n"
- " - if no pkcs1 input is defined, a \n"
- " RSA key will be generated\n"
- " - if no filename is given, default is used\n"
- " --out (-o) <type>[=<filename>] write output of <type> to <filename>\n"
- " multiple outputs are allowed\n"
- " <type> = pkcs1 | pkcs10 | pkcs7 | cert-self | cert | cacert\n"
- " - type cacert defines filename prefix of\n"
- " received CA certificate(s)\n"
- " - if no filename is given, default is used\n"
- " --optionsfrom (-+) <filename> reads additional options from given file\n"
- " --force (-f) force existing file(s)\n"
- "\n"
- "Options for key generation (pkcs1):\n"
- " --keylength (-k) <bits> key length for RSA key generation\n"
- "(default: 2048 bits)\n"
- "\n"
- "Options for validity:\n"
- " --days (-D) <days> validity in days\n"
- " --startdate (-S) <YYMMDDHHMMSS>Z not valid before date\n"
- " --enddate (-E) <YYMMDDHHMMSS>Z not valid after date\n"
- "\n"
- "Options for request generation (pkcs10):\n"
- " --dn (-d) <dn> comma separated list of distinguished names\n"
- " --subjectAltName (-s) <t>=<v> include subjectAltName in certificate request\n"
- " <t> = email | dns | ip \n"
- " --password (-p) <pw> challenge password\n"
- " - if pw is '%%prompt', password gets prompted for\n"
- " --algorithm (-a) <algo> use specified algorithm for PKCS#7 encryption\n"
- " <algo> = des-cbc | 3des-cbc (default: 3des-cbc)\n"
- "\n"
- "Options for enrollment (cert):\n"
- " --url (-u) <url> url of the SCEP server\n"
- " --method (-m) post | get http request type\n"
- " --interval (-t) <seconds> manual mode poll interval in seconds (default 20s)\n"
- " --maxpolltime (-x) <seconds> max poll time in seconds when in manual mode\n"
- " (default: unlimited)\n"
+ fprintf(stderr,
+ "Usage: scepclient\n"
+ " --help (-h) show usage and exit\n"
+ " --version (-v) show version and exit\n"
+ " --quiet (-q) do not write log output to stderr\n"
+ " --in (-i) <type>[=<filename>] use <filename> of <type> for input \n"
+ " <type> = pkcs1 | cacert-enc | cacert-sig\n"
+ " - if no pkcs1 input is defined, a \n"
+ " RSA key will be generated\n"
+ " - if no filename is given, default is used\n"
+ " --out (-o) <type>[=<filename>] write output of <type> to <filename>\n"
+ " multiple outputs are allowed\n"
+ " <type> = pkcs1 | pkcs10 | pkcs7 | cert-self | cert | cacert\n"
+ " - type cacert defines filename prefix of\n"
+ " received CA certificate(s)\n"
+ " - if no filename is given, default is used\n"
+ " --optionsfrom (-+) <filename> reads additional options from given file\n"
+ " --force (-f) force existing file(s)\n"
+ "\n"
+ "Options for key generation (pkcs1):\n"
+ " --keylength (-k) <bits> key length for RSA key generation\n"
+ "(default: 2048 bits)\n"
+ "\n"
+ "Options for validity:\n"
+ " --days (-D) <days> validity in days\n"
+ " --startdate (-S) <YYMMDDHHMMSS>Z not valid before date\n"
+ " --enddate (-E) <YYMMDDHHMMSS>Z not valid after date\n"
+ "\n"
+ "Options for request generation (pkcs10):\n"
+ " --dn (-d) <dn> comma separated list of distinguished names\n"
+ " --subjectAltName (-s) <t>=<v> include subjectAltName in certificate request\n"
+ " <t> = email | dns | ip \n"
+ " --password (-p) <pw> challenge password\n"
+ " - if pw is '%%prompt', password gets prompted for\n"
+ " --algorithm (-a) <algo> use specified algorithm for PKCS#7 encryption\n"
+ " <algo> = des-cbc | 3des-cbc (default) | \n"
+ " aes128-cbc | aes192-cbc | aes256-cbc | \n"
+ " camellia128-cbc | camellia192-cbc | camellia256-cbc\n"
+ "\n"
+ "Options for enrollment (cert):\n"
+ " --url (-u) <url> url of the SCEP server\n"
+ " --method (-m) post | get http request type\n"
+ " --interval (-t) <seconds> manual mode poll interval in seconds (default 20s)\n"
+ " --maxpolltime (-x) <seconds> max poll time in seconds when in manual mode\n"
+ " (default: unlimited)\n"
#ifdef DEBUG
- "\n"
- "Debugging output:\n"
- " --debug-all (-A) show everything except private\n"
- " --debug-parsing (-P) show parsing relevant stuff\n"
- " --debug-raw (-R) show raw hex dumps\n"
- " --debug-control (-C) show control flow output\n"
- " --debug-controlmore (-M) show more control flow\n"
- " --debug-private (-X) show sensitive data (private keys, etc.)\n"
+ "\n"
+ "Debugging output:\n"
+ " --debug-all (-A) show everything except private\n"
+ " --debug-parsing (-P) show parsing relevant stuff\n"
+ " --debug-raw (-R) show raw hex dumps\n"
+ " --debug-control (-C) show control flow output\n"
+ " --debug-controlmore (-M) show more control flow\n"
+ " --debug-private (-X) show sensitive data (private keys, etc.)\n"
#endif
- );
- exit_scepclient(message);
+ );
+ exit_scepclient(message);
+}
+
+/**
+ * Log loaded plugins
+ */
+static void print_plugins()
+{
+ char buf[BUF_LEN], *plugin;
+ int len = 0;
+ enumerator_t *enumerator;
+
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
+ {
+ len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin);
+ }
+ enumerator->destroy(enumerator);
+ DBG1(" loaded plugins: %s", buf);
}
/**
@@ -277,760 +296,842 @@ usage(const char *message)
*/
int main(int argc, char **argv)
{
- /* external values */
- extern char * optarg;
- extern int optind;
-
- /* type of input and output files */
- typedef enum {
- PKCS1 = 0x01,
- PKCS10 = 0x02,
- PKCS7 = 0x04,
- CERT_SELF = 0x08,
- CERT = 0x10,
- CACERT_ENC = 0x20,
- CACERT_SIG = 0x40
- } scep_filetype_t;
-
- /* filetype to read from, defaults to "generate a key" */
- scep_filetype_t filetype_in = 0;
-
- /* filetype to write to, no default here */
- scep_filetype_t filetype_out = 0;
-
- /* input files */
- char *file_in_pkcs1 = DEFAULT_FILENAME_PKCS1;
- char *file_in_cacert_enc = DEFAULT_FILENAME_CACERT_ENC;
- char *file_in_cacert_sig = DEFAULT_FILENAME_CACERT_SIG;
-
- /* output files */
- char *file_out_pkcs1 = DEFAULT_FILENAME_PKCS1;
- char *file_out_pkcs10 = DEFAULT_FILENAME_PKCS10;
- char *file_out_pkcs7 = DEFAULT_FILENAME_PKCS7;
- char *file_out_cert_self = DEFAULT_FILENAME_CERT_SELF;
- char *file_out_cert = DEFAULT_FILENAME_CERT;
- char *file_out_prefix_cacert = DEFAULT_FILENAME_PREFIX_CACERT;
-
- /* by default user certificate is requested */
- bool request_ca_certificate = FALSE;
-
- /* by default existing files are not overwritten */
- bool force = FALSE;
-
- /* length of RSA key in bits */
- u_int rsa_keylength = DEFAULT_RSA_KEY_LENGTH;
-
- /* validity of self-signed certificate */
- time_t validity = DEFAULT_CERT_VALIDITY;
- time_t notBefore = 0;
- time_t notAfter = 0;
-
- /* distinguished name for requested certificate, ASCII format */
- char *distinguishedName = NULL;
-
- /* challenge password */
- char challenge_password_buffer[MAX_PASSWORD_LENGTH];
-
- /* symmetric encryption algorithm used by pkcs7, default is 3DES */
- int pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
-
- /* digest algorithm used by pkcs7, default is MD5 */
- int pkcs7_digest_alg = OID_MD5;
-
- /* signature algorithm used by pkcs10, default is MD5 with RSA encryption */
- int pkcs10_signature_alg = OID_MD5;
-
- /* URL of the SCEP-Server */
- char *scep_url = NULL;
-
- /* http request method, default is GET */
- fetch_request_t request_type = FETCH_GET;
-
- /* poll interval time in manual mode in seconds */
- u_int poll_interval = DEFAULT_POLL_INTERVAL;
-
- /* maximum poll time */
- u_int max_poll_time = 0;
-
- err_t ugh = NULL;
-
- /* initialize global variables */
- pkcs1 = empty_chunk;
- pkcs7 = empty_chunk;
- serialNumber = empty_chunk;
- transID = empty_chunk;
- fingerprint = empty_chunk;
- issuerAndSubject = empty_chunk;
- challengePassword = empty_chunk;
- getCertInitial = empty_chunk;
- scep_response = empty_chunk;
- log_to_stderr = TRUE;
-
- for (;;)
- {
- static const struct option long_opts[] = {
- /* name, has_arg, flag, val */
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "quiet", no_argument, NULL, 'q' },
- { "in", required_argument, NULL, 'i' },
- { "out", required_argument, NULL, 'o' },
- { "force", no_argument, NULL, 'f' },
- { "keylength", required_argument, NULL, 'k' },
- { "dn", required_argument, NULL, 'd' },
- { "days", required_argument, NULL, 'D' },
- { "startdate", required_argument, NULL, 'S' },
- { "enddate", required_argument, NULL, 'E' },
- { "subjectAltName", required_argument, NULL, 's' },
- { "password", required_argument, NULL, 'p' },
- { "algorithm", required_argument, NULL, 'a' },
- { "url", required_argument, NULL, 'u' },
- { "method", required_argument, NULL, 'm' },
- { "interval", required_argument, NULL, 't' },
- { "maxpolltime", required_argument, NULL, 'x' },
+ /* external values */
+ extern char * optarg;
+ extern int optind;
+
+ /* type of input and output files */
+ typedef enum {
+ PKCS1 = 0x01,
+ PKCS10 = 0x02,
+ PKCS7 = 0x04,
+ CERT_SELF = 0x08,
+ CERT = 0x10,
+ CACERT_ENC = 0x20,
+ CACERT_SIG = 0x40
+ } scep_filetype_t;
+
+ /* filetype to read from, defaults to "generate a key" */
+ scep_filetype_t filetype_in = 0;
+
+ /* filetype to write to, no default here */
+ scep_filetype_t filetype_out = 0;
+
+ /* input files */
+ char *file_in_pkcs1 = DEFAULT_FILENAME_PKCS1;
+ char *file_in_cacert_enc = DEFAULT_FILENAME_CACERT_ENC;
+ char *file_in_cacert_sig = DEFAULT_FILENAME_CACERT_SIG;
+
+ /* output files */
+ char *file_out_pkcs1 = DEFAULT_FILENAME_PKCS1;
+ char *file_out_pkcs10 = DEFAULT_FILENAME_PKCS10;
+ char *file_out_pkcs7 = DEFAULT_FILENAME_PKCS7;
+ char *file_out_cert_self = DEFAULT_FILENAME_CERT_SELF;
+ char *file_out_cert = DEFAULT_FILENAME_CERT;
+ char *file_out_prefix_cacert = DEFAULT_FILENAME_PREFIX_CACERT;
+
+ /* by default user certificate is requested */
+ bool request_ca_certificate = FALSE;
+
+ /* by default existing files are not overwritten */
+ bool force = FALSE;
+
+ /* length of RSA key in bits */
+ u_int rsa_keylength = DEFAULT_RSA_KEY_LENGTH;
+
+ /* validity of self-signed certificate */
+ time_t validity = DEFAULT_CERT_VALIDITY;
+ time_t notBefore = 0;
+ time_t notAfter = 0;
+
+ /* distinguished name for requested certificate, ASCII format */
+ char *distinguishedName = NULL;
+
+ /* challenge password */
+ char challenge_password_buffer[MAX_PASSWORD_LENGTH];
+
+ /* symmetric encryption algorithm used by pkcs7, default is 3DES */
+ int pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
+
+ /* digest algorithm used by pkcs7, default is SHA-1 */
+ int pkcs7_digest_alg = OID_SHA1;
+
+ /* signature algorithm used by pkcs10, default is SHA-1 with RSA encryption */
+ int pkcs10_signature_alg = OID_SHA1;
+
+ /* URL of the SCEP-Server */
+ char *scep_url = NULL;
+
+ /* http request method, default is GET */
+ bool http_get_request = TRUE;
+
+ /* poll interval time in manual mode in seconds */
+ u_int poll_interval = DEFAULT_POLL_INTERVAL;
+
+ /* maximum poll time */
+ u_int max_poll_time = 0;
+
+ err_t ugh = NULL;
+
+ /* initialize global variables */
+ pkcs1 = chunk_empty;
+ pkcs7 = chunk_empty;
+ serialNumber = chunk_empty;
+ transID = chunk_empty;
+ fingerprint = chunk_empty;
+ issuerAndSubject = chunk_empty;
+ challengePassword = chunk_empty;
+ getCertInitial = chunk_empty;
+ scep_response = chunk_empty;
+ log_to_stderr = TRUE;
+
+ /* initialize library and optionsfrom */
+ library_init(STRONGSWAN_CONF);
+ options = options_create();
+
+ for (;;)
+ {
+ static const struct option long_opts[] = {
+ /* name, has_arg, flag, val */
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "optionsfrom", required_argument, NULL, '+' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "in", required_argument, NULL, 'i' },
+ { "out", required_argument, NULL, 'o' },
+ { "force", no_argument, NULL, 'f' },
+ { "keylength", required_argument, NULL, 'k' },
+ { "dn", required_argument, NULL, 'd' },
+ { "days", required_argument, NULL, 'D' },
+ { "startdate", required_argument, NULL, 'S' },
+ { "enddate", required_argument, NULL, 'E' },
+ { "subjectAltName", required_argument, NULL, 's' },
+ { "password", required_argument, NULL, 'p' },
+ { "algorithm", required_argument, NULL, 'a' },
+ { "url", required_argument, NULL, 'u' },
+ { "method", required_argument, NULL, 'm' },
+ { "interval", required_argument, NULL, 't' },
+ { "maxpolltime", required_argument, NULL, 'x' },
+#ifdef DEBUG
+ { "debug-all", no_argument, NULL, 'A' },
+ { "debug-parsing", no_argument, NULL, 'P'},
+ { "debug-raw", no_argument, NULL, 'R'},
+ { "debug-control", no_argument, NULL, 'C'},
+ { "debug-controlmore", no_argument, NULL, 'M'},
+ { "debug-private", no_argument, NULL, 'X'},
+#endif
+ { 0,0,0,0 }
+ };
+
+ /* parse next option */
+ int c = getopt_long(argc, argv, "hv+:qi:o:fk:d:s:p:a:u:m:t:x:APRCMS", long_opts, NULL);
+
+ switch (c)
+ {
+ case EOF: /* end of flags */
+ break;
+
+ case 'h': /* --help */
+ usage(NULL);
+
+ case 'v': /* --version */
+ version();
+
+ case 'q': /* --quiet */
+ log_to_stderr = FALSE;
+ continue;
+
+ case 'i': /* --in <type> [= <filename>] */
+ {
+ char *filename = strstr(optarg, "=");
+
+ if (filename)
+ {
+ /* replace '=' by '\0' */
+ *filename = '\0';
+ /* set pointer to start of filename */
+ filename++;
+ }
+ if (strcaseeq("pkcs1", optarg))
+ {
+ filetype_in |= PKCS1;
+ if (filename)
+ file_in_pkcs1 = filename;
+ }
+ else if (strcaseeq("cacert-enc", optarg))
+ {
+ filetype_in |= CACERT_ENC;
+ if (filename)
+ file_in_cacert_enc = filename;
+ }
+ else if (strcaseeq("cacert-sig", optarg))
+ {
+ filetype_in |= CACERT_SIG;
+ if (filename)
+ file_in_cacert_sig = filename;
+ }
+ else
+ {
+ usage("invalid --in file type");
+ }
+ continue;
+ }
+
+ case 'o': /* --out <type> [= <filename>] */
+ {
+ char *filename = strstr(optarg, "=");
+
+ if (filename)
+ {
+ /* replace '=' by '\0' */
+ *filename = '\0';
+ /* set pointer to start of filename */
+ filename++;
+ }
+ if (strcaseeq("pkcs1", optarg))
+ {
+ filetype_out |= PKCS1;
+ if (filename)
+ file_out_pkcs1 = filename;
+ }
+ else if (strcaseeq("pkcs10", optarg))
+ {
+ filetype_out |= PKCS10;
+ if (filename)
+ file_out_pkcs10 = filename;
+ }
+ else if (strcaseeq("pkcs7", optarg))
+ {
+ filetype_out |= PKCS7;
+ if (filename)
+ file_out_pkcs7 = filename;
+ }
+ else if (strcaseeq("cert-self", optarg))
+ {
+ filetype_out |= CERT_SELF;
+ if (filename)
+ file_out_cert_self = filename;
+ }
+ else if (strcaseeq("cert", optarg))
+ {
+ filetype_out |= CERT;
+ if (filename)
+ file_out_cert = filename;
+ }
+ else if (strcaseeq("cacert", optarg))
+ {
+ request_ca_certificate = TRUE;
+ if (filename)
+ file_out_prefix_cacert = filename;
+ }
+ else
+ {
+ usage("invalid --out file type");
+ }
+ continue;
+ }
+
+ case 'f': /* --force */
+ force = TRUE;
+ continue;
+
+ case '+': /* --optionsfrom <filename> */
+ if (!options->from(options, optarg, &argc, &argv, optind))
+ {
+ exit_scepclient("optionsfrom failed");
+ }
+ continue;
+
+ case 'k': /* --keylength <length> */
+ {
+ div_t q;
+
+ rsa_keylength = atoi(optarg);
+ if (rsa_keylength == 0)
+ usage("invalid keylength");
+
+ /* check if key length is a multiple of 8 bits */
+ q = div(rsa_keylength, 2*BITS_PER_BYTE);
+ if (q.rem != 0)
+ {
+ exit_scepclient("keylength is not a multiple of %d bits!"
+ , 2*BITS_PER_BYTE);
+ }
+ continue;
+ }
+
+ case 'D': /* --days */
+ if (optarg == NULL || !isdigit(optarg[0]))
+ usage("missing number of days");
+ {
+ char *endptr;
+ long days = strtol(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg
+ || days <= 0)
+ usage("<days> must be a positive number");
+ validity = 24*3600*days;
+ }
+ continue;
+
+ case 'S': /* --startdate */
+ if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
+ usage("date format must be YYMMDDHHMMSSZ");
+ {
+ chunk_t date = { optarg, 13 };
+ notBefore = asn1_to_time(&date, ASN1_UTCTIME);
+ }
+ continue;
+
+ case 'E': /* --enddate */
+ if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
+ usage("date format must be YYMMDDHHMMSSZ");
+ {
+ chunk_t date = { optarg, 13 };
+ notAfter = asn1_to_time(&date, ASN1_UTCTIME);
+ }
+ continue;
+
+ case 'd': /* --dn */
+ if (distinguishedName)
+ usage("only one distinguished name allowed");
+ distinguishedName = optarg;
+ continue;
+
+ case 's': /* --subjectAltName */
+ {
+ generalNames_t kind;
+ char *value = strstr(optarg, "=");
+
+ if (value)
+ {
+ /* replace '=' by '\0' */
+ *value = '\0';
+ /* set pointer to start of value */
+ value++;
+ }
+
+ if (strcaseeq("email", optarg))
+ {
+ kind = GN_RFC822_NAME;
+ }
+ else if (strcaseeq("dns", optarg))
+ {
+ kind = GN_DNS_NAME;
+ }
+ else if (strcaseeq("ip", optarg))
+ {
+ kind = GN_IP_ADDRESS;
+ }
+ else
+ {
+ usage("invalid --subjectAltName type");
+ continue;
+ }
+ pkcs10_add_subjectAltName(&subjectAltNames, kind, value);
+ continue;
+ }
+
+ case 'p': /* --password */
+ if (challengePassword.len > 0)
+ {
+ usage("only one challenge password allowed");
+ }
+ if (strcaseeq("%prompt", optarg))
+ {
+ printf("Challenge password: ");
+ if (fgets(challenge_password_buffer, sizeof(challenge_password_buffer)-1, stdin))
+ {
+ challengePassword.ptr = challenge_password_buffer;
+ /* discard the terminating '\n' from the input */
+ challengePassword.len = strlen(challenge_password_buffer) - 1;
+ }
+ else
+ {
+ usage("challenge password could not be read");
+ }
+ }
+ else
+ {
+ challengePassword.ptr = optarg;
+ challengePassword.len = strlen(optarg);
+ }
+ continue;
+
+ case 'u': /* -- url */
+ if (scep_url)
+ {
+ usage("only one URL argument allowed");
+ }
+ scep_url = optarg;
+ continue;
+
+ case 'm': /* --method */
+ if (strcaseeq("get", optarg))
+ {
+ http_get_request = TRUE;
+ }
+ else if (strcaseeq("post", optarg))
+ {
+ http_get_request = FALSE;
+ }
+ else
+ {
+ usage("invalid http request method specified");
+ }
+ continue;
+
+ case 't': /* --interval */
+ poll_interval = atoi(optarg);
+ if (poll_interval <= 0)
+ {
+ usage("invalid interval specified");
+ }
+ continue;
+
+ case 'x': /* --maxpolltime */
+ max_poll_time = atoi(optarg);
+ if (max_poll_time < 0)
+ {
+ usage("invalid maxpolltime specified");
+ }
+ continue;
+
+ case 'a': /*--algorithm */
+ if (strcaseeq("des-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_DES_CBC;
+ }
+ else if (strcaseeq("3des-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
+ }
+ else if (strcaseeq("aes128-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_AES128_CBC;
+ }
+ else if (strcaseeq("aes192-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_AES192_CBC;
+ }
+ else if (strcaseeq("aes256-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_AES256_CBC;
+ }
+ else if (strcaseeq("camellia128-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_CAMELLIA128_CBC;
+ }
+ else if (strcaseeq("camellia192-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_CAMELLIA192_CBC;
+ }
+ else if (strcaseeq("camellia256-cbc", optarg))
+ {
+ pkcs7_symmetric_cipher = OID_CAMELLIA256_CBC;
+ }
+ else
+ {
+ usage("invalid encryption algorithm specified");
+ }
+ continue;
#ifdef DEBUG
- { "debug-all", no_argument, NULL, 'A' },
- { "debug-parsing", no_argument, NULL, 'P'},
- { "debug-raw", no_argument, NULL, 'R'},
- { "debug-control", no_argument, NULL, 'C'},
- { "debug-controlmore", no_argument, NULL, 'M'},
- { "debug-private", no_argument, NULL, 'X'},
+ case 'A': /* --debug-all */
+ base_debugging |= DBG_ALL;
+ continue;
+ case 'P': /* debug parsing */
+ base_debugging |= DBG_PARSING;
+ continue;
+ case 'R': /* debug raw */
+ base_debugging |= DBG_RAW;
+ continue;
+ case 'C': /* debug control */
+ base_debugging |= DBG_CONTROL;
+ continue;
+ case 'M': /* debug control more */
+ base_debugging |= DBG_CONTROLMORE;
+ continue;
+ case 'X': /* debug private */
+ base_debugging |= DBG_PRIVATE;
+ continue;
#endif
- { 0,0,0,0 }
- };
+ default:
+ usage("unknown option");
+ }
+ /* break from loop */
+ break;
+ }
+ cur_debugging = base_debugging;
+
+ init_log("scepclient");
- /* parse next option */
- int c = getopt_long(argc, argv, "hv+:qi:o:fk:d:s:p:a:u:m:t:x:APRCMS", long_opts, NULL);
+ /* load plugins, further infrastructure may need it */
+ lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR,
+ lib->settings->get_str(lib->settings, "scepclient.load", PLUGINS));
+ print_plugins();
- switch (c)
+ if ((filetype_out == 0) && (!request_ca_certificate))
+ {
+ usage ("--out filetype required");
+ }
+ if (request_ca_certificate && (filetype_out > 0 || filetype_in > 0))
{
- case EOF: /* end of flags */
- break;
+ usage("in CA certificate request, no other --in or --out option allowed");
+ }
- case 'h': /* --help */
- usage(NULL);
+ /* check if url is given, if cert output defined */
+ if (((filetype_out & CERT) || request_ca_certificate) && !scep_url)
+ {
+ usage("URL of SCEP server required");
+ }
- case 'v': /* --version */
- version();
+ /* check for sanity of --in/--out */
+ if (!filetype_in && (filetype_in > filetype_out))
+ {
+ usage("cannot generate --out of given --in!");
+ }
- case 'q': /* --quiet */
- log_to_stderr = FALSE;
- continue;
+ /*
+ * input of PKCS#1 file
+ */
+ if (filetype_in & PKCS1) /* load an RSA key pair from file */
+ {
+ prompt_pass_t pass = { "", FALSE, STDIN_FILENO };
+ char *path = concatenate_paths(PRIVATE_KEY_PATH, file_in_pkcs1);
- case 'i': /* --in <type> [= <filename>] */
- {
- char *filename = strstr(optarg, "=");
+ private_key = load_private_key(path, &pass, KEY_RSA);
+ }
+ else /* generate an RSA key pair */
+ {
+ private_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_KEY_SIZE, rsa_keylength,
+ BUILD_END);
+ }
+ if (private_key == NULL)
+ {
+ exit_scepclient("no RSA private key available");
+ }
+ public_key = private_key->get_public_key(private_key);
- if (filename)
- {
- /* replace '=' by '\0' */
- *filename = '\0';
- /* set pointer to start of filename */
- filename++;
- }
- if (strcasecmp("pkcs1", optarg) == 0)
- {
- filetype_in |= PKCS1;
- if (filename)
- file_in_pkcs1 = filename;
- }
- else if (strcasecmp("cacert-enc", optarg) == 0)
- {
- filetype_in |= CACERT_ENC;
- if (filename)
- file_in_cacert_enc = filename;
- }
- else if (strcasecmp("cacert-sig", optarg) == 0)
- {
- filetype_in |= CACERT_SIG;
- if (filename)
- file_in_cacert_sig = filename;
- }
- else
- {
- usage("invalid --in file type");
- }
- continue;
- }
+ /* check for minimum key length */
+ if (private_key->get_keysize(private_key) < RSA_MIN_OCTETS)
+ {
+ exit_scepclient("length of RSA key has to be at least %d bits"
+ ,RSA_MIN_OCTETS * BITS_PER_BYTE);
+ }
- case 'o': /* --out <type> [= <filename>] */
- {
- char *filename = strstr(optarg, "=");
+ /*
+ * input of PKCS#10 file
+ */
+ if (filetype_in & PKCS10)
+ {
+ /* user wants to load a pkcs10 request
+ * operation is not yet supported
+ * would require a PKCS#10 parsing function
- if (filename)
- {
- /* replace '=' by '\0' */
- *filename = '\0';
- /* set pointer to start of filename */
- filename++;
- }
- if (strcasecmp("pkcs1", optarg) == 0)
- {
- filetype_out |= PKCS1;
- if (filename)
- file_out_pkcs1 = filename;
- }
- else if (strcasecmp("pkcs10", optarg) == 0)
- {
- filetype_out |= PKCS10;
- if (filename)
- file_out_pkcs10 = filename;
- }
- else if (strcasecmp("pkcs7", optarg) == 0)
- {
- filetype_out |= PKCS7;
- if (filename)
- file_out_pkcs7 = filename;
- }
- else if (strcasecmp("cert-self", optarg) == 0)
- {
- filetype_out |= CERT_SELF;
- if (filename)
- file_out_cert_self = filename;
- }
- else if (strcasecmp("cert", optarg) == 0)
- {
- filetype_out |= CERT;
- if (filename)
- file_out_cert = filename;
- }
- else if (strcasecmp("cacert", optarg) == 0)
- {
- request_ca_certificate = TRUE;
- if (filename)
- file_out_prefix_cacert = filename;
- }
- else
- {
- usage("invalid --out file type");
- }
- continue;
- }
-
- case 'f': /* --force */
- force = TRUE;
- continue;
-
- case '+': /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- case 'k': /* --keylength <length> */
- {
- div_t q;
-
- rsa_keylength = atoi(optarg);
- if (rsa_keylength == 0)
- usage("invalid keylength");
-
- /* check if key length is a multiple of 8 bits */
- q = div(rsa_keylength, 2*BITS_PER_BYTE);
- if (q.rem != 0)
- {
- exit_scepclient("keylength is not a multiple of %d bits!"
- , 2*BITS_PER_BYTE);
- }
- continue;
- }
-
- case 'D': /* --days */
- if (optarg == NULL || !isdigit(optarg[0]))
- usage("missing number of days");
- {
- char *endptr;
- long days = strtol(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg
- || days <= 0)
- usage("<days> must be a positive number");
- validity = 24*3600*days;
- }
- continue;
-
- case 'S': /* --startdate */
- if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
- usage("date format must be YYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 13 };
- notBefore = asn1totime(&date, ASN1_UTCTIME);
- }
- continue;
-
- case 'E': /* --enddate */
- if (optarg == NULL || strlen(optarg) != 13 || optarg[12] != 'Z')
- usage("date format must be YYMMDDHHMMSSZ");
- {
- chunk_t date = { optarg, 13 };
- notAfter = asn1totime(&date, ASN1_UTCTIME);
- }
- continue;
-
- case 'd': /* --dn */
- if (distinguishedName)
- usage("only one distinguished name allowed");
- distinguishedName = optarg;
- continue;
-
- case 's': /* --subjectAltName */
- {
- generalNames_t kind;
- char *value = strstr(optarg, "=");
-
- if (value)
- {
- /* replace '=' by '\0' */
- *value = '\0';
- /* set pointer to start of value */
- value++;
- }
+ pkcs10 = pkcs10_read_from_file(file_in_pkcs10);
- if (!strcasecmp("email", optarg))
- kind = GN_RFC822_NAME;
- else if (!strcasecmp("dns", optarg))
- kind = GN_DNS_NAME;
- else if (!strcasecmp("ip", optarg))
- kind = GN_IP_ADDRESS;
- else
- {
- usage("invalid --subjectAltName type");
- continue;
- }
- pkcs10_add_subjectAltName(&subjectAltNames, kind, value);
- continue;
- }
-
- case 'p': /* --password */
- if (challengePassword.len > 0)
- usage("only one challenge password allowed");
-
- if (strcasecmp("%prompt", optarg) == 0)
- {
- printf("Challenge password: ");
- if (fgets(challenge_password_buffer, sizeof(challenge_password_buffer)-1, stdin))
+ */
+ }
+ else
+ {
+ char buf[IDTOA_BUF];
+ chunk_t dn = chunk_empty;
+
+ dn.ptr = buf;
+
+ if (distinguishedName == NULL)
{
- challengePassword.ptr = challenge_password_buffer;
- /* discard the terminating '\n' from the input */
- challengePassword.len = strlen(challenge_password_buffer) - 1;
+ char buf[BUF_LEN];
+ int n = sprintf(buf, DEFAULT_DN);
+
+ /* set the common name to the hostname */
+ if (gethostname(buf + n, BUF_LEN - n) || strlen(buf) == n)
+ {
+ exit_scepclient("no hostname defined, use "
+ "--dn <distinguished name> option");
+ }
+ distinguishedName = buf;
}
- else
+
+ DBG(DBG_CONTROL,
+ DBG_log("dn: '%s'", distinguishedName);
+ )
+ ugh = atodn(distinguishedName, &dn);
+ if (ugh != NULL)
{
- usage("challenge password could not be read");
+ exit_scepclient(ugh);
}
- }
- else
- {
- challengePassword.ptr = optarg;
- challengePassword.len = strlen(optarg);
- }
- continue;
-
- case 'u': /* -- url */
- if (scep_url)
- usage("only one URL argument allowed");
- scep_url = optarg;
- continue;
-
- case 'm': /* --method */
- if (strcasecmp("post", optarg) == 0)
- request_type = FETCH_POST;
- else if (strcasecmp("get", optarg) == 0)
- request_type = FETCH_GET;
- else
- usage("invalid http request method specified");
- continue;
-
- case 't': /* --interval */
- poll_interval = atoi(optarg);
- if (poll_interval <= 0)
- usage("invalid interval specified");
- continue;
-
- case 'x': /* --maxpolltime */
- max_poll_time = atoi(optarg);
- if (max_poll_time < 0)
- usage("invalid maxpolltime specified");
- continue;
-
- case 'a': /*--algorithm */
- if (strcasecmp("des-cbc", optarg) == 0)
- pkcs7_symmetric_cipher = OID_DES_CBC;
- else if (strcasecmp("3des-cbc", optarg) == 0)
- pkcs7_symmetric_cipher = OID_3DES_EDE_CBC;
- else
- usage("invalid encryption algorithm specified");
- continue;
-#ifdef DEBUG
- case 'A': /* --debug-all */
- base_debugging |= DBG_ALL;
- continue;
- case 'P': /* debug parsing */
- base_debugging |= DBG_PARSING;
- continue;
- case 'R': /* debug raw */
- base_debugging |= DBG_RAW;
- continue;
- case 'C': /* debug control */
- base_debugging |= DBG_CONTROL;
- continue;
- case 'M': /* debug control more */
- base_debugging |= DBG_CONTROLMORE;
- continue;
- case 'X': /* debug private */
- base_debugging |= DBG_PRIVATE;
- continue;
-#endif
- default:
- usage("unknown option");
+
+ subject = chunk_clone(dn);
+
+ DBG(DBG_CONTROL,
+ DBG_log("building pkcs10 object:")
+ )
+ pkcs10 = pkcs10_build(private_key, public_key, subject,
+ challengePassword, subjectAltNames,
+ pkcs10_signature_alg);
+ fingerprint = scep_generate_pkcs10_fingerprint(pkcs10->request);
+ plog(" fingerprint: %s", fingerprint.ptr);
}
- /* break from loop */
- break;
- }
- init_log("scepclient");
- cur_debugging = base_debugging;
- init_rnd_pool();
- init_fetch();
+ /*
+ * output of PKCS#10 file
+ */
+ if (filetype_out & PKCS10)
+ {
+ char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
- if ((filetype_out == 0) && (!request_ca_certificate))
- usage ("--out filetype required");
+ if (!chunk_write(pkcs10->request, path, "pkcs10", 0022, force))
+ exit_scepclient("could not write pkcs10 file '%s'", path);
- if (request_ca_certificate && (filetype_out > 0 || filetype_in > 0))
- usage("in CA certificate request, no other --in or --out option allowed");
+ filetype_out &= ~PKCS10; /* delete PKCS10 flag */
+ }
- /* check if url is given, if cert output defined */
- if (((filetype_out & CERT) || request_ca_certificate) && !scep_url)
- usage("URL of SCEP server required");
+ if (!filetype_out)
+ {
+ exit_scepclient(NULL); /* no further output required */
+ }
- /* check for sanity of --in/--out */
- if (!filetype_in && (filetype_in > filetype_out))
- usage("cannot generate --out of given --in!");
-
- /*
- * input of PKCS#1 file
- */
- private_key = alloc_thing(RSA_private_key_t, "RSA_private_key_t");
-
- if (filetype_in & PKCS1) /* load an RSA key pair from file */
- {
- prompt_pass_t pass = { "", FALSE, STDIN_FILENO };
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_in_pkcs1);
-
- ugh = load_rsa_private_key(path, &pass, private_key);
- }
- else /* generate an RSA key pair */
- {
- ugh = generate_rsa_private_key(rsa_keylength, private_key);
- }
- if (ugh != NULL)
- exit_scepclient(ugh);
-
- /* check for minimum key length */
- if ((private_key->pub.k) < RSA_MIN_OCTETS)
- {
- exit_scepclient("length of RSA key has to be at least %d bits"
- ,RSA_MIN_OCTETS * BITS_PER_BYTE);
- }
-
- /*
- * input of PKCS#10 file
- */
- if (filetype_in & PKCS10)
- {
- /* user wants to load a pkcs10 request
- * operation is not yet supported
- * would require a PKCS#10 parsing function
-
- pkcs10 = pkcs10_read_from_file(file_in_pkcs10);
-
- */
- }
- else
- {
- char buf[IDTOA_BUF];
- chunk_t dn = empty_chunk;
-
- dn.ptr = buf;
-
- if (distinguishedName == NULL)
+ /*
+ * output of PKCS#1 file
+ */
+ if (filetype_out & PKCS1)
{
- char buf[BUF_LEN];
- int n = sprintf(buf, DEFAULT_DN);
-
- /* set the common name to the hostname */
- if (gethostname(buf + n, BUF_LEN - n) || strlen(buf) == n)
- {
- exit_scepclient("no hostname defined, use "
- "--dn <distinguished name> option");
- }
- distinguishedName = buf;
+ char *path = concatenate_paths(PRIVATE_KEY_PATH, file_out_pkcs1);
+
+ DBG(DBG_CONTROL,
+ DBG_log("building pkcs1 object:")
+ )
+ pkcs1 = private_key->get_encoding(private_key);
+
+ if (!chunk_write(pkcs1, path, "pkcs1", 0066, force))
+ exit_scepclient("could not write pkcs1 file '%s'", path);
+
+ filetype_out &= ~PKCS1; /* delete PKCS1 flag */
}
- DBG(DBG_CONTROL,
- DBG_log("dn: '%s'", distinguishedName);
- )
- ugh = atodn(distinguishedName, &dn);
- if (ugh != NULL)
- exit_scepclient(ugh);
-
- clonetochunk(subject, dn.ptr, dn.len, "subject dn");
-
- DBG(DBG_CONTROL,
- DBG_log("building pkcs10 object:")
- )
- pkcs10 = pkcs10_build(private_key, subject, challengePassword
- , subjectAltNames, pkcs10_signature_alg);
- scep_generate_pkcs10_fingerprint(pkcs10->request, &fingerprint);
- plog(" fingerprint: %.*s", (int)fingerprint.len, fingerprint.ptr);
- }
-
- /*
- * output of PKCS#10 file
- */
- if (filetype_out & PKCS10)
- {
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs10);
-
- if (!write_chunk(path, "pkcs10", pkcs10->request, 0022, force))
- exit_scepclient("could not write pkcs10 file '%s'", path);
-
- filetype_out &= ~PKCS10; /* delete PKCS10 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * output of PKCS#1 file
- */
- if (filetype_out & PKCS1)
- {
- const char *path = concatenate_paths(PRIVATE_KEY_PATH, file_out_pkcs1);
-
- DBG(DBG_CONTROL,
- DBG_log("building pkcs1 object:")
- )
- pkcs1 = pkcs1_build_private_key(private_key);
-
- if (!write_chunk(path, "pkcs1", pkcs1, 0066, force))
- exit_scepclient("could not write pkcs1 file '%s'", path);
-
- filetype_out &= ~PKCS1; /* delete PKCS1 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- scep_generate_transaction_id((const RSA_public_key_t *)private_key
- , &transID, &serialNumber);
- plog(" transaction ID: %.*s", (int)transID.len, transID.ptr);
-
- /* generate a self-signed X.509 certificate */
- x509_signer = alloc_thing(x509cert_t, "signer cert");
- *x509_signer = empty_x509cert;
- x509_signer->serialNumber = serialNumber;
- x509_signer->sigAlg = OID_SHA1_WITH_RSA;
- x509_signer->issuer = subject;
- x509_signer->notBefore = (notBefore)? notBefore
- : time(NULL);
- x509_signer->notAfter = (notAfter)? notAfter
- : x509_signer->notBefore + validity;
- x509_signer->subject = subject;
- x509_signer->subjectAltName = subjectAltNames;
-
- build_x509cert(x509_signer, (const RSA_public_key_t *)private_key
- , private_key);
-
- /*
- * output of self-signed X.509 certificate file
- */
- if (filetype_out & CERT_SELF)
- {
- const char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
-
- if (!write_chunk(path, "self-signed cert", x509_signer->certificate, 0022, force))
- exit_scepclient("could not write self-signed cert file '%s'", path);
-;
- filetype_out &= ~CERT_SELF; /* delete CERT_SELF flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * load ca encryption certificate
- */
- {
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
- cert_t cert;
-
- if (!load_cert(path, "encryption cacert", &cert))
- exit_scepclient("could not load encryption cacert file '%s'", path);
- x509_ca_enc = cert.u.x509;
- }
-
- /*
- * input of PKCS#7 file
- */
- if (filetype_in & PKCS7)
- {
- /* user wants to load a pkcs7 encrypted request
- * operation is not yet supported!
- * would require additional parsing of transaction-id
-
- pkcs7 = pkcs7_read_from_file(file_in_pkcs7);
+ if (!filetype_out)
+ {
+ exit_scepclient(NULL); /* no further output required */
+ }
+ scep_generate_transaction_id(public_key, &transID, &serialNumber);
+ plog(" transaction ID: %.*s", (int)transID.len, transID.ptr);
+
+ /* generate a self-signed X.509 certificate */
+ x509_signer = malloc_thing(x509cert_t);
+ *x509_signer = empty_x509cert;
+ x509_signer->serialNumber = serialNumber;
+ x509_signer->sigAlg = OID_SHA1_WITH_RSA;
+ x509_signer->issuer = subject;
+ x509_signer->notBefore = (notBefore)? notBefore
+ : time(NULL);
+ x509_signer->notAfter = (notAfter)? notAfter
+ : x509_signer->notBefore + validity;
+ x509_signer->subject = subject;
+ x509_signer->subjectAltName = subjectAltNames;
+ build_x509cert(x509_signer, public_key, private_key);
+
+ /*
+ * output of self-signed X.509 certificate file
*/
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("building pkcs7 request")
- )
- pkcs7 = scep_build_request(pkcs10->request
- , transID, SCEP_PKCSReq_MSG
- , x509_ca_enc, pkcs7_symmetric_cipher
- , x509_signer, pkcs7_digest_alg, private_key);
- }
-
- /*
- * output pkcs7 encrypted and signed certificate request
- */
- if (filetype_out & PKCS7)
- {
- const char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
-
- if (!write_chunk(path, "pkcs7 encrypted request", pkcs7, 0022, force))
- exit_scepclient("could not write pkcs7 file '%s'", path);
-;
- filetype_out &= ~PKCS7; /* delete PKCS7 flag */
- }
-
- if (!filetype_out)
- exit_scepclient(NULL); /* no further output required */
-
- /*
- * output certificate fetch from SCEP server
- */
- if (filetype_out & CERT)
- {
- const char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
- cert_t cert;
- time_t poll_start;
-
- x509cert_t *certs = NULL;
- chunk_t envelopedData = empty_chunk;
- chunk_t certData = empty_chunk;
- contentInfo_t data = empty_contentInfo;
- scep_attributes_t attrs = empty_scep_attributes;
-
- if (!load_cert(path, "signature cacert", &cert))
- exit_scepclient("could not load signature cacert file '%s'", path);
- x509_ca_sig = cert.u.x509;
-
- if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION
- , request_type, &scep_response))
+ if (filetype_out & CERT_SELF)
{
- exit_scepclient("did not receive a valid scep response");
+ char *path = concatenate_paths(HOST_CERT_PATH, file_out_cert_self);
+
+ if (!chunk_write(x509_signer->certificate, path, "self-signed cert", 0022, force))
+ exit_scepclient("could not write self-signed cert file '%s'", path);
+;
+ filetype_out &= ~CERT_SELF; /* delete CERT_SELF flag */
}
- ugh = scep_parse_response(scep_response, transID, &data, &attrs
- , x509_ca_sig);
- if (ugh != NULL)
- exit_scepclient(ugh);
- /* in case of manual mode, we are going into a polling loop */
- if (attrs.pkiStatus == SCEP_PENDING)
+ if (!filetype_out)
{
- plog(" scep request pending, polling every %d seconds"
- , poll_interval);
- time(&poll_start);
- issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
- , x509_ca_sig->subject
- , subject);
+ exit_scepclient(NULL); /* no further output required */
}
- while (attrs.pkiStatus == SCEP_PENDING)
+
+ /*
+ * load ca encryption certificate
+ */
{
- if (max_poll_time > 0
- && (time(NULL) - poll_start >= max_poll_time))
- {
- exit_scepclient("maximum poll time reached: %d seconds"
- , max_poll_time);
- }
- DBG(DBG_CONTROL,
- DBG_log("going to sleep for %d seconds", poll_interval)
- )
- sleep(poll_interval);
- free(scep_response.ptr);
-
- DBG(DBG_CONTROL,
- DBG_log("fingerprint: %.*s", (int)fingerprint.len, fingerprint.ptr);
- DBG_log("transaction ID: %.*s", (int)transID.len, transID.ptr)
- )
-
- freeanychunk(getCertInitial);
- getCertInitial = scep_build_request(issuerAndSubject
- , transID, SCEP_GetCertInitial_MSG
- , x509_ca_enc, pkcs7_symmetric_cipher
- , x509_signer, pkcs7_digest_alg, private_key);
-
- if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION
- , request_type, &scep_response))
- {
- exit_scepclient("did not receive a valid scep response");
- }
- ugh = scep_parse_response(scep_response, transID, &data, &attrs
- , x509_ca_sig);
- if (ugh != NULL)
- exit_scepclient(ugh);
+ char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_enc);
+ cert_t cert;
+
+ if (!load_cert(path, "encryption cacert", &cert))
+ {
+ exit_scepclient("could not load encryption cacert file '%s'", path);
+ }
+ x509_ca_enc = cert.u.x509;
}
- if (attrs.pkiStatus != SCEP_SUCCESS)
+ /*
+ * input of PKCS#7 file
+ */
+ if (filetype_in & PKCS7)
{
- exit_scepclient("reply status is not 'SUCCESS'");
- }
+ /* user wants to load a pkcs7 encrypted request
+ * operation is not yet supported!
+ * would require additional parsing of transaction-id
- envelopedData = data.content;
+ pkcs7 = pkcs7_read_from_file(file_in_pkcs7);
- if (data.type != OID_PKCS7_DATA
- || !parse_asn1_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
+ */
+ }
+ else
{
- exit_scepclient("contentInfo is not of type 'data'");
+ DBG(DBG_CONTROL,
+ DBG_log("building pkcs7 request")
+ )
+ pkcs7 = scep_build_request(pkcs10->request
+ , transID, SCEP_PKCSReq_MSG
+ , x509_ca_enc, pkcs7_symmetric_cipher
+ , x509_signer, pkcs7_digest_alg, private_key);
}
- if (!pkcs7_parse_envelopedData(envelopedData, &certData
- , serialNumber, private_key))
+
+ /*
+ * output pkcs7 encrypted and signed certificate request
+ */
+ if (filetype_out & PKCS7)
{
- exit_scepclient("could not decrypt envelopedData");
+ char *path = concatenate_paths(REQ_PATH, file_out_pkcs7);
+
+ if (!chunk_write(pkcs7, path, "pkcs7 encrypted request", 0022, force))
+ exit_scepclient("could not write pkcs7 file '%s'", path);
+;
+ filetype_out &= ~PKCS7; /* delete PKCS7 flag */
}
- if (!pkcs7_parse_signedData(certData, NULL, &certs, NULL, NULL))
- {
- exit_scepclient("error parsing the scep response");
+
+ if (!filetype_out)
+ {
+ exit_scepclient(NULL); /* no further output required */
}
- freeanychunk(certData);
-
- /* store the end entity certificate */
- path = concatenate_paths(HOST_CERT_PATH, file_out_cert);
- while (certs != NULL)
- {
- bool stored = FALSE;
- x509cert_t *cert = certs;
-
- if (!cert->isCA)
- {
- if (stored)
- exit_scepclient("multiple certs received, only first stored");
- if (!write_chunk(path, "requested cert", cert->certificate, 0022, force))
- exit_scepclient("could not write cert file '%s'", path);
- stored = TRUE;
- }
- certs = certs->next;
- free_x509cert(cert);
+
+ /*
+ * output certificate fetch from SCEP server
+ */
+ if (filetype_out & CERT)
+ {
+ char *path = concatenate_paths(CA_CERT_PATH, file_in_cacert_sig);
+ cert_t cert;
+ time_t poll_start;
+
+ x509cert_t *certs = NULL;
+ chunk_t envelopedData = chunk_empty;
+ chunk_t certData = chunk_empty;
+ contentInfo_t data = empty_contentInfo;
+ scep_attributes_t attrs = empty_scep_attributes;
+
+ if (!load_cert(path, "signature cacert", &cert))
+ exit_scepclient("could not load signature cacert file '%s'", path);
+ x509_ca_sig = cert.u.x509;
+
+ if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
+ http_get_request, &scep_response))
+ {
+ exit_scepclient("did not receive a valid scep response");
+ }
+ ugh = scep_parse_response(scep_response, transID, &data, &attrs
+ , x509_ca_sig);
+ if (ugh != NULL)
+ {
+ exit_scepclient(ugh);
+ }
+
+ /* in case of manual mode, we are going into a polling loop */
+ if (attrs.pkiStatus == SCEP_PENDING)
+ {
+ plog(" scep request pending, polling every %d seconds"
+ , poll_interval);
+ time(&poll_start);
+ issuerAndSubject = asn1_wrap(ASN1_SEQUENCE, "cc"
+ , x509_ca_sig->subject
+ , subject);
+ }
+ while (attrs.pkiStatus == SCEP_PENDING)
+ {
+ if (max_poll_time > 0
+ && (time(NULL) - poll_start >= max_poll_time))
+ {
+ exit_scepclient("maximum poll time reached: %d seconds"
+ , max_poll_time);
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("going to sleep for %d seconds", poll_interval)
+ )
+ sleep(poll_interval);
+ free(scep_response.ptr);
+
+ DBG(DBG_CONTROL,
+ DBG_log("fingerprint: %.*s", (int)fingerprint.len, fingerprint.ptr);
+ DBG_log("transaction ID: %.*s", (int)transID.len, transID.ptr)
+ )
+
+ chunk_free(&getCertInitial);
+ getCertInitial = scep_build_request(issuerAndSubject
+ , transID, SCEP_GetCertInitial_MSG
+ , x509_ca_enc, pkcs7_symmetric_cipher
+ , x509_signer, pkcs7_digest_alg, private_key);
+
+ if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION,
+ http_get_request, &scep_response))
+ {
+ exit_scepclient("did not receive a valid scep response");
+ }
+ ugh = scep_parse_response(scep_response, transID, &data, &attrs
+ , x509_ca_sig);
+ if (ugh != NULL)
+ {
+ exit_scepclient(ugh);
+ }
+ }
+
+ if (attrs.pkiStatus != SCEP_SUCCESS)
+ {
+ exit_scepclient("reply status is not 'SUCCESS'");
+ }
+
+ envelopedData = data.content;
+
+ if (data.type != OID_PKCS7_DATA
+ || !asn1_parse_simple_object(&envelopedData, ASN1_OCTET_STRING, 0, "data"))
+ {
+ exit_scepclient("contentInfo is not of type 'data'");
+ }
+ if (!pkcs7_parse_envelopedData(envelopedData, &certData
+ , serialNumber, private_key))
+ {
+ exit_scepclient("could not decrypt envelopedData");
+ }
+ if (!pkcs7_parse_signedData(certData, NULL, &certs, NULL, NULL))
+ {
+ exit_scepclient("error parsing the scep response");
+ }
+ chunk_free(&certData);
+
+ /* store the end entity certificate */
+ path = concatenate_paths(HOST_CERT_PATH, file_out_cert);
+ while (certs != NULL)
+ {
+ bool stored = FALSE;
+ x509cert_t *cert = certs;
+
+ if (!cert->isCA)
+ {
+ if (stored)
+ exit_scepclient("multiple certs received, only first stored");
+ if (!chunk_write(cert->certificate, path, "requested cert", 0022, force))
+ exit_scepclient("could not write cert file '%s'", path);
+ stored = TRUE;
+ }
+ certs = certs->next;
+ free_x509cert(cert);
+ }
+ filetype_out &= ~CERT; /* delete CERT flag */
}
- filetype_out &= ~CERT; /* delete CERT flag */
- }
- exit_scepclient(NULL);
- return -1; /* should never be reached */
+ exit_scepclient(NULL);
+ return -1; /* should never be reached */
}
diff --git a/src/starter/Makefile.am b/src/starter/Makefile.am
index 8a9ba54c9..439a7785a 100644
--- a/src/starter/Makefile.am
+++ b/src/starter/Makefile.am
@@ -5,9 +5,22 @@ starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
exec.h invokecharon.h lex.yy.c loglite.c klips.c klips.h
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto -I$(top_srcdir)/src/whack -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\" -DIPSEC_EAPDIR=\"${eapdir}\" -DDEBUG
-starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a
+INCLUDES = \
+-I${linuxdir} \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto \
+-I$(top_srcdir)/src/whack \
+-I$(top_srcdir)/src/stroke
+
+AM_CFLAGS = \
+-DIPSEC_DIR=\"${ipsecdir}\" \
+-DIPSEC_CONFDIR=\"${confdir}\" \
+-DIPSEC_PIDDIR=\"${piddir}\" \
+-DIPSEC_EAPDIR=\"${eapdir}\" \
+-DDEBUG
+
+starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la
EXTRA_DIST = parser.l parser.y keywords.txt ipsec.conf
dist_man_MANS = ipsec.conf.5 starter.8
MAINTAINERCLEANFILES = lex.yy.c y.tab.c y.tab.h keywords.c
@@ -23,20 +36,20 @@ if USE_CHARON
AM_CFLAGS += -DSTART_CHARON
endif
-lex.yy.c: parser.l parser.y parser.h y.tab.c
- $(LEX) --nounput $<
+lex.yy.c: $(srcdir)/parser.l $(srcdir)/parser.y $(srcdir)/parser.h
+ $(LEX) $(srcdir)/parser.l
-y.tab.c: parser.y parser.l parser.h
- $(YACC) -v -d $<
+y.tab.c: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
+ $(YACC) -v -d $(srcdir)/parser.y
-y.tab.h: parser.y parser.l parser.h
- $(YACC) -v -d $<
+y.tab.h: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
+ $(YACC) -v -d $(srcdir)/parser.y
-keywords.c: keywords.txt keywords.h
- $(GPERF) -C -G -t < $< > $@
+keywords.c: $(srcdir)/keywords.txt $(srcdir)/keywords.h
+ $(GPERF) -m 10 -C -G -D -t < $(srcdir)/keywords.txt > $@
defs.o: $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
- $(COMPILE) -c -o $@ $<
+ $(COMPILE) -c -o $@ $(PLUTODIR)/defs.c
install-exec-local :
test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d" || true
diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in
index 54fd28604..4e6bffdeb 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -56,7 +56,8 @@ am_starter_OBJECTS = y.tab.$(OBJEXT) netkey.$(OBJEXT) \
lex.yy.$(OBJEXT) loglite.$(OBJEXT) klips.$(OBJEXT)
starter_OBJECTS = $(am_starter_OBJECTS)
starter_DEPENDENCIES = defs.o \
- $(top_builddir)/src/libfreeswan/libfreeswan.a
+ $(top_builddir)/src/libfreeswan/libfreeswan.a \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -93,6 +94,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -115,6 +117,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -126,6 +131,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -139,6 +145,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -199,6 +207,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -210,6 +219,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -220,11 +230,18 @@ starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
exec.h invokecharon.h lex.yy.c loglite.c klips.c klips.h
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto -I$(top_srcdir)/src/whack -I$(top_srcdir)/src/stroke
+INCLUDES = \
+-I${linuxdir} \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto \
+-I$(top_srcdir)/src/whack \
+-I$(top_srcdir)/src/stroke
+
AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_CONFDIR=\"${confdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" -DIPSEC_EAPDIR=\"${eapdir}\" \
-DDEBUG $(am__append_1) $(am__append_2)
-starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a
+starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la
EXTRA_DIST = parser.l parser.y keywords.txt ipsec.conf
dist_man_MANS = ipsec.conf.5 starter.8
MAINTAINERCLEANFILES = lex.yy.c y.tab.c y.tab.h keywords.c
@@ -238,8 +255,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -355,8 +372,8 @@ install-man5: $(man5_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
5*) ;; \
@@ -400,8 +417,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -440,7 +457,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -620,20 +637,20 @@ uninstall-man: uninstall-man5 uninstall-man8
uninstall-man8
-lex.yy.c: parser.l parser.y parser.h y.tab.c
- $(LEX) --nounput $<
+lex.yy.c: $(srcdir)/parser.l $(srcdir)/parser.y $(srcdir)/parser.h
+ $(LEX) $(srcdir)/parser.l
-y.tab.c: parser.y parser.l parser.h
- $(YACC) -v -d $<
+y.tab.c: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
+ $(YACC) -v -d $(srcdir)/parser.y
-y.tab.h: parser.y parser.l parser.h
- $(YACC) -v -d $<
+y.tab.h: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
+ $(YACC) -v -d $(srcdir)/parser.y
-keywords.c: keywords.txt keywords.h
- $(GPERF) -C -G -t < $< > $@
+keywords.c: $(srcdir)/keywords.txt $(srcdir)/keywords.h
+ $(GPERF) -m 10 -C -G -D -t < $(srcdir)/keywords.txt > $@
defs.o: $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h
- $(COMPILE) -c -o $@ $<
+ $(COMPILE) -c -o $@ $(PLUTODIR)/defs.c
install-exec-local :
test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d" || true
diff --git a/src/starter/args.c b/src/starter/args.c
index c09bea986..f9d1824d8 100644
--- a/src/starter/args.c
+++ b/src/starter/args.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: args.c 4612 2008-11-11 06:37:37Z andreas $
*/
#include <stddef.h>
@@ -33,276 +31,283 @@
/* argument types */
typedef enum {
- ARG_NONE,
- ARG_ENUM,
- ARG_UINT,
- ARG_TIME,
- ARG_ULNG,
- ARG_PCNT,
- ARG_STR,
- ARG_LST,
- ARG_MISC
+ ARG_NONE,
+ ARG_ENUM,
+ ARG_UINT,
+ ARG_TIME,
+ ARG_ULNG,
+ ARG_PCNT,
+ ARG_STR,
+ ARG_LST,
+ ARG_MISC
} arg_t;
/* various keyword lists */
static const char *LST_bool[] = {
- "no",
- "yes",
- NULL
+ "no",
+ "yes",
+ NULL
};
static const char *LST_sendcert[] = {
- "always",
- "ifasked",
- "never",
- "yes",
- "no",
- NULL
+ "always",
+ "ifasked",
+ "never",
+ "yes",
+ "no",
+ NULL
};
static const char *LST_unique[] = {
- "no",
- "yes",
- "replace",
- "keep",
- NULL
+ "no",
+ "yes",
+ "replace",
+ "keep",
+ NULL
};
static const char *LST_strict[] = {
- "no",
- "yes",
- "ifuri",
- NULL
+ "no",
+ "yes",
+ "ifuri",
+ NULL
};
static const char *LST_dpd_action[] = {
- "none",
- "clear",
- "hold",
- "restart",
- NULL
+ "none",
+ "clear",
+ "hold",
+ "restart",
+ NULL
};
static const char *LST_startup[] = {
- "ignore",
- "add",
- "route",
- "start",
- NULL
+ "ignore",
+ "add",
+ "route",
+ "start",
+ NULL
};
static const char *LST_packetdefault[] = {
- "drop",
- "reject",
- "pass",
- NULL
+ "drop",
+ "reject",
+ "pass",
+ NULL
};
static const char *LST_keyexchange[] = {
- "ike",
- "ikev1",
- "ikev2",
- NULL
+ "ike",
+ "ikev1",
+ "ikev2",
+ NULL
};
static const char *LST_pfsgroup[] = {
- "modp1024",
- "modp1536",
- "modp2048",
- "modp3072",
- "modp4096",
- "modp6144",
- "modp8192",
- NULL
+ "modp1024",
+ "modp1536",
+ "modp2048",
+ "modp3072",
+ "modp4096",
+ "modp6144",
+ "modp8192",
+ NULL
};
static const char *LST_plutodebug[] = {
- "none",
- "all",
- "raw",
- "crypt",
- "parsing",
- "emitting",
- "control",
- "lifecycle",
- "klips",
- "dns",
- "natt",
- "oppo",
- "controlmore",
- "private",
- NULL
+ "none",
+ "all",
+ "raw",
+ "crypt",
+ "parsing",
+ "emitting",
+ "control",
+ "lifecycle",
+ "klips",
+ "dns",
+ "natt",
+ "oppo",
+ "controlmore",
+ "private",
+ NULL
};
static const char *LST_klipsdebug[] = {
- "tunnel",
- "tunnel-xmit",
- "pfkey",
- "xform",
- "eroute",
- "spi",
- "radij",
- "esp",
- "ah",
- "ipcomp",
- "verbose",
- "all",
- "none",
- NULL
+ "tunnel",
+ "tunnel-xmit",
+ "pfkey",
+ "xform",
+ "eroute",
+ "spi",
+ "radij",
+ "esp",
+ "ah",
+ "ipcomp",
+ "verbose",
+ "all",
+ "none",
+ NULL
};
typedef struct {
- arg_t type;
- size_t offset;
- const char **list;
+ arg_t type;
+ size_t offset;
+ const char **list;
} token_info_t;
static const token_info_t token_info[] =
{
- /* config setup keywords */
- { ARG_LST, offsetof(starter_config_t, setup.interfaces), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.dumpdir), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.charonstart), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.plutostart), LST_bool },
-
- /* pluto/charon keywords */
- { ARG_LST, offsetof(starter_config_t, setup.plutodebug), LST_plutodebug },
- { ARG_STR, offsetof(starter_config_t, setup.charondebug), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.prepluto), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.postpluto), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.plutostderrlog), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_unique },
- { ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
- { ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_strict },
- { ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
- { ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.force_keepalive), LST_bool },
- { ARG_STR, offsetof(starter_config_t, setup.virtual_private), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.pkcs11module), NULL },
- { ARG_STR, offsetof(starter_config_t, setup.pkcs11initargs), NULL },
- { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11keepstate), LST_bool },
- { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11proxy), LST_bool },
-
- /* KLIPS keywords */
- { ARG_LST, offsetof(starter_config_t, setup.klipsdebug), LST_klipsdebug },
- { ARG_ENUM, offsetof(starter_config_t, setup.fragicmp), LST_bool },
- { ARG_STR, offsetof(starter_config_t, setup.packetdefault), LST_packetdefault },
- { ARG_ENUM, offsetof(starter_config_t, setup.hidetos), LST_bool },
-
- /* conn section keywords */
- { ARG_STR, offsetof(starter_conn_t, name), NULL },
- { ARG_ENUM, offsetof(starter_conn_t, startup), LST_startup },
- { ARG_ENUM, offsetof(starter_conn_t, keyexchange), LST_keyexchange },
- { ARG_MISC, 0, NULL /* KW_TYPE */ },
- { ARG_MISC, 0, NULL /* KW_PFS */ },
- { ARG_MISC, 0, NULL /* KW_COMPRESS */ },
- { ARG_ENUM, offsetof(starter_conn_t, install_policy), LST_bool },
- { ARG_MISC, 0, NULL /* KW_AUTH */ },
- { ARG_MISC, 0, NULL /* KW_AUTHBY */ },
- { ARG_MISC, 0, NULL /* KW_EAP */ },
- { ARG_STR, offsetof(starter_conn_t, eap_identity), NULL },
- { ARG_MISC, 0, NULL /* KW_MOBIKE */ },
- { ARG_MISC, 0, NULL /* KW_FORCEENCAPS */ },
- { ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL },
- { ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL },
- { ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL },
- { ARG_MISC, 0, NULL /* KW_KEYINGTRIES */ },
- { ARG_PCNT, offsetof(starter_conn_t, sa_rekey_fuzz), NULL },
- { ARG_MISC, 0, NULL /* KW_REKEY */ },
- { ARG_MISC, 0, NULL /* KW_REAUTH */ },
- { ARG_STR, offsetof(starter_conn_t, ike), NULL },
- { ARG_STR, offsetof(starter_conn_t, esp), NULL },
- { ARG_STR, offsetof(starter_conn_t, pfsgroup), LST_pfsgroup },
- { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
- { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
- { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
- { ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
- { ARG_MISC, 0, NULL /* KW_XAUTH */ },
- { ARG_ENUM, offsetof(starter_conn_t, me_mediation), LST_bool },
- { ARG_STR, offsetof(starter_conn_t, me_mediated_by), NULL },
- { ARG_STR, offsetof(starter_conn_t, me_peerid), NULL },
-
- /* ca section keywords */
- { ARG_STR, offsetof(starter_ca_t, name), NULL },
- { ARG_ENUM, offsetof(starter_ca_t, startup), LST_startup },
- { ARG_STR, offsetof(starter_ca_t, cacert), NULL },
- { ARG_STR, offsetof(starter_ca_t, ldaphost), NULL },
- { ARG_STR, offsetof(starter_ca_t, ldapbase), NULL },
- { ARG_STR, offsetof(starter_ca_t, crluri), NULL },
- { ARG_STR, offsetof(starter_ca_t, crluri2), NULL },
- { ARG_STR, offsetof(starter_ca_t, ocspuri), NULL },
- { ARG_STR, offsetof(starter_ca_t, ocspuri2), NULL },
- { ARG_STR, offsetof(starter_ca_t, certuribase), NULL },
-
- /* end keywords */
- { ARG_MISC, 0, NULL /* KW_HOST */ },
- { ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
- { ARG_STR, offsetof(starter_end_t, subnet), NULL },
- { ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
- { ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
- { ARG_STR, offsetof(starter_end_t, srcip), NULL },
- { ARG_MISC, 0, NULL /* KW_NATIP */ },
- { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
- { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
- { ARG_ENUM, offsetof(starter_end_t, allow_any), LST_bool },
- { ARG_STR, offsetof(starter_end_t, updown), NULL },
- { ARG_STR, offsetof(starter_end_t, id), NULL },
- { ARG_STR, offsetof(starter_end_t, rsakey), NULL },
- { ARG_STR, offsetof(starter_end_t, cert), NULL },
- { ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert },
- { ARG_STR, offsetof(starter_end_t, ca), NULL },
- { ARG_STR, offsetof(starter_end_t, groups), NULL },
- { ARG_STR, offsetof(starter_end_t, iface), NULL }
+ /* config setup keywords */
+ { ARG_LST, offsetof(starter_config_t, setup.interfaces), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.dumpdir), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.charonstart), LST_bool },
+ { ARG_ENUM, offsetof(starter_config_t, setup.plutostart), LST_bool },
+
+ /* pluto/charon keywords */
+ { ARG_LST, offsetof(starter_config_t, setup.plutodebug), LST_plutodebug },
+ { ARG_STR, offsetof(starter_config_t, setup.charondebug), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.prepluto), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.postpluto), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.plutostderrlog), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.uniqueids), LST_unique },
+ { ARG_UINT, offsetof(starter_config_t, setup.overridemtu), NULL },
+ { ARG_TIME, offsetof(starter_config_t, setup.crlcheckinterval), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.cachecrls), LST_bool },
+ { ARG_ENUM, offsetof(starter_config_t, setup.strictcrlpolicy), LST_strict },
+ { ARG_ENUM, offsetof(starter_config_t, setup.nocrsend), LST_bool },
+ { ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool },
+ { ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.force_keepalive), LST_bool },
+ { ARG_STR, offsetof(starter_config_t, setup.virtual_private), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.pkcs11module), NULL },
+ { ARG_STR, offsetof(starter_config_t, setup.pkcs11initargs), NULL },
+ { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11keepstate), LST_bool },
+ { ARG_ENUM, offsetof(starter_config_t, setup.pkcs11proxy), LST_bool },
+
+ /* KLIPS keywords */
+ { ARG_LST, offsetof(starter_config_t, setup.klipsdebug), LST_klipsdebug },
+ { ARG_ENUM, offsetof(starter_config_t, setup.fragicmp), LST_bool },
+ { ARG_STR, offsetof(starter_config_t, setup.packetdefault), LST_packetdefault },
+ { ARG_ENUM, offsetof(starter_config_t, setup.hidetos), LST_bool },
+
+ /* conn section keywords */
+ { ARG_STR, offsetof(starter_conn_t, name), NULL },
+ { ARG_ENUM, offsetof(starter_conn_t, startup), LST_startup },
+ { ARG_ENUM, offsetof(starter_conn_t, keyexchange), LST_keyexchange },
+ { ARG_MISC, 0, NULL /* KW_TYPE */ },
+ { ARG_MISC, 0, NULL /* KW_PFS */ },
+ { ARG_MISC, 0, NULL /* KW_COMPRESS */ },
+ { ARG_ENUM, offsetof(starter_conn_t, install_policy), LST_bool },
+ { ARG_MISC, 0, NULL /* KW_AUTH */ },
+ { ARG_MISC, 0, NULL /* KW_AUTHBY */ },
+ { ARG_MISC, 0, NULL /* KW_EAP */ },
+ { ARG_STR, offsetof(starter_conn_t, eap_identity), NULL },
+ { ARG_MISC, 0, NULL /* KW_MOBIKE */ },
+ { ARG_MISC, 0, NULL /* KW_FORCEENCAPS */ },
+ { ARG_TIME, offsetof(starter_conn_t, sa_ike_life_seconds), NULL },
+ { ARG_TIME, offsetof(starter_conn_t, sa_ipsec_life_seconds), NULL },
+ { ARG_TIME, offsetof(starter_conn_t, sa_rekey_margin), NULL },
+ { ARG_MISC, 0, NULL /* KW_KEYINGTRIES */ },
+ { ARG_PCNT, offsetof(starter_conn_t, sa_rekey_fuzz), NULL },
+ { ARG_MISC, 0, NULL /* KW_REKEY */ },
+ { ARG_MISC, 0, NULL /* KW_REAUTH */ },
+ { ARG_STR, offsetof(starter_conn_t, ike), NULL },
+ { ARG_STR, offsetof(starter_conn_t, esp), NULL },
+ { ARG_STR, offsetof(starter_conn_t, pfsgroup), LST_pfsgroup },
+ { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
+ { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
+ { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
+ { ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
+ { ARG_MISC, 0, NULL /* KW_XAUTH */ },
+ { ARG_ENUM, offsetof(starter_conn_t, me_mediation), LST_bool },
+ { ARG_STR, offsetof(starter_conn_t, me_mediated_by), NULL },
+ { ARG_STR, offsetof(starter_conn_t, me_peerid), NULL },
+
+ /* ca section keywords */
+ { ARG_STR, offsetof(starter_ca_t, name), NULL },
+ { ARG_ENUM, offsetof(starter_ca_t, startup), LST_startup },
+ { ARG_STR, offsetof(starter_ca_t, cacert), NULL },
+ { ARG_STR, offsetof(starter_ca_t, ldaphost), NULL },
+ { ARG_STR, offsetof(starter_ca_t, ldapbase), NULL },
+ { ARG_STR, offsetof(starter_ca_t, crluri), NULL },
+ { ARG_STR, offsetof(starter_ca_t, crluri2), NULL },
+ { ARG_STR, offsetof(starter_ca_t, ocspuri), NULL },
+ { ARG_STR, offsetof(starter_ca_t, ocspuri2), NULL },
+ { ARG_STR, offsetof(starter_ca_t, certuribase), NULL },
+
+ /* end keywords */
+ { ARG_MISC, 0, NULL /* KW_HOST */ },
+ { ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
+ { ARG_STR, offsetof(starter_end_t, subnet), NULL },
+ { ARG_MISC, 0, NULL /* KW_SUBNETWITHIN */ },
+ { ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
+ { ARG_STR, offsetof(starter_end_t, srcip), NULL },
+ { ARG_MISC, 0, NULL /* KW_NATIP */ },
+ { ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
+ { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
+ { ARG_ENUM, offsetof(starter_end_t, allow_any), LST_bool },
+ { ARG_STR, offsetof(starter_end_t, updown), NULL },
+ { ARG_STR, offsetof(starter_end_t, auth), NULL },
+ { ARG_STR, offsetof(starter_end_t, auth2), NULL },
+ { ARG_STR, offsetof(starter_end_t, id), NULL },
+ { ARG_STR, offsetof(starter_end_t, id2), NULL },
+ { ARG_STR, offsetof(starter_end_t, rsakey), NULL },
+ { ARG_STR, offsetof(starter_end_t, cert), NULL },
+ { ARG_STR, offsetof(starter_end_t, cert2), NULL },
+ { ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert },
+ { ARG_STR, offsetof(starter_end_t, ca), NULL },
+ { ARG_STR, offsetof(starter_end_t, ca2), NULL },
+ { ARG_STR, offsetof(starter_end_t, groups), NULL },
+ { ARG_STR, offsetof(starter_end_t, iface), NULL }
};
static void
free_list(char **list)
{
- char **s;
+ char **s;
- for (s = list; *s; s++)
- pfree(*s);
- pfree(list);
+ for (s = list; *s; s++)
+ {
+ free(*s);
+ }
+ free(list);
}
char **
new_list(char *value)
{
- char *val, *b, *e, *end, **ret;
- int count;
-
- val = value ? clone_str(value, "list value") : NULL;
- if (!val)
- return NULL;
- end = val + strlen(val);
- for (b = val, count = 0; b < end;)
- {
- for (e = b; ((*e != ' ') && (*e != '\0')); e++);
- *e = '\0';
- if (e != b)
- count++;
- b = e + 1;
- }
- if (count == 0)
- {
- pfree(val);
- return NULL;
- }
- ret = (char **)alloc_bytes((count+1) * sizeof(char *), "list");
-
- for (b = val, count = 0; b < end; )
- {
- for (e = b; (*e != '\0'); e++);
- if (e != b)
- ret[count++] = clone_str(b, "list value");
- b = e + 1;
- }
- ret[count] = NULL;
- pfree(val);
- return ret;
+ char *val, *b, *e, *end, **ret;
+ int count;
+
+ val = value ? clone_str(value) : NULL;
+ if (!val)
+ return NULL;
+ end = val + strlen(val);
+ for (b = val, count = 0; b < end;)
+ {
+ for (e = b; ((*e != ' ') && (*e != '\0')); e++);
+ *e = '\0';
+ if (e != b)
+ count++;
+ b = e + 1;
+ }
+ if (count == 0)
+ {
+ free(val);
+ return NULL;
+ }
+ ret = (char **)malloc((count+1) * sizeof(char *));
+
+ for (b = val, count = 0; b < end; )
+ {
+ for (e = b; (*e != '\0'); e++);
+ if (e != b)
+ ret[count++] = clone_str(b);
+ b = e + 1;
+ }
+ ret[count] = NULL;
+ free(val);
+ return ret;
}
@@ -311,191 +316,199 @@ new_list(char *value)
*/
bool
assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw, char *base
- , bool *assigned)
+ , bool *assigned)
{
- char *p = base + token_info[token].offset;
- const char **list = token_info[token].list;
-
- int index = -1; /* used for enumeration arguments */
-
- lset_t *seen = (lset_t *)base; /* seen flags are at the top of the struct */
- lset_t f = LELEM(token - first); /* compute flag position of argument */
-
- *assigned = FALSE;
+ char *p = base + token_info[token].offset;
+ const char **list = token_info[token].list;
- DBG(DBG_CONTROLMORE,
- DBG_log(" %s=%s", kw->entry->name, kw->value)
- )
+ int index = -1; /* used for enumeration arguments */
- if (*seen & f)
- {
- plog("# duplicate '%s' option", kw->entry->name);
- return FALSE;
- }
+ lset_t *seen = (lset_t *)base; /* seen flags are at the top of the struct */
+ lset_t f = LELEM(token - first); /* compute flag position of argument */
- /* set flag that this argument has been seen */
- *seen |= f;
+ *assigned = FALSE;
- /* is there a keyword list? */
- if (list != NULL && token_info[token].type != ARG_LST)
- {
- bool match = FALSE;
+ DBG(DBG_CONTROLMORE,
+ DBG_log(" %s=%s", kw->entry->name, kw->value)
+ )
- while (*list != NULL && !match)
- {
- index++;
- match = streq(kw->value, *list++);
- }
- if (!match)
- {
- plog("# bad value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
-
- switch (token_info[token].type)
- {
- case ARG_NONE:
- plog("# option '%s' not supported yet", kw->entry->name);
- return FALSE;
- case ARG_ENUM:
+ if (*seen & f)
{
- int *i = (int *)p;
-
- if (index < 0)
- {
- plog("# bad enumeration value: %s=%s (%d)"
- , kw->entry->name, kw->value, index);
+ plog("# duplicate '%s' option", kw->entry->name);
return FALSE;
- }
- *i = index;
}
- break;
-
- case ARG_UINT:
- {
- char *endptr;
- u_int *u = (u_int *)p;
- *u = strtoul(kw->value, &endptr, 10);
+ /* set flag that this argument has been seen */
+ *seen |= f;
- if (*endptr != '\0')
- {
- plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- }
- break;
- case ARG_ULNG:
- case ARG_PCNT:
+ /* is there a keyword list? */
+ if (list != NULL && token_info[token].type != ARG_LST)
{
- char *endptr;
- unsigned long *l = (unsigned long *)p;
+ bool match = FALSE;
- *l = strtoul(kw->value, &endptr, 10);
-
- if (token_info[token].type == ARG_ULNG)
- {
- if (*endptr != '\0')
+ while (*list != NULL && !match)
{
- plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
+ index++;
+ match = streq(kw->value, *list++);
}
- }
- else
- {
- if ((*endptr != '%') || (endptr[1] != '\0') || endptr == kw->value)
+ if (!match)
{
- plog("# bad percent value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
+ plog("# bad value: %s=%s", kw->entry->name, kw->value);
+ return FALSE;
}
- }
-
}
- break;
- case ARG_TIME:
- {
- char *endptr;
- time_t *t = (time_t *)p;
- *t = strtoul(kw->value, &endptr, 10);
-
- /* time in seconds? */
- if (*endptr == '\0' || (*endptr == 's' && endptr[1] == '\0'))
+ switch (token_info[token].type)
+ {
+ case ARG_NONE:
+ plog("# option '%s' not supported yet", kw->entry->name);
+ return FALSE;
+ case ARG_ENUM:
+ {
+ if (index < 0)
+ {
+ plog("# bad enumeration value: %s=%s (%d)"
+ , kw->entry->name, kw->value, index);
+ return FALSE;
+ }
+
+ if (token_info[token].list == LST_bool)
+ {
+ bool *b = (bool *)p;
+ *b = (index > 0);
+ }
+ else
+ {
+ int *i = (int *)p;
+ *i = index;
+ }
+ }
break;
- if (endptr[1] == '\0')
- {
- if (*endptr == 'm') /* time in minutes? */
+ case ARG_UINT:
{
- *t *= 60;
- break;
+ char *endptr;
+ u_int *u = (u_int *)p;
+
+ *u = strtoul(kw->value, &endptr, 10);
+
+ if (*endptr != '\0')
+ {
+ plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
+ return FALSE;
+ }
}
- if (*endptr == 'h') /* time in hours? */
+ break;
+ case ARG_ULNG:
+ case ARG_PCNT:
{
- *t *= 3600;
- break;
+ char *endptr;
+ unsigned long *l = (unsigned long *)p;
+
+ *l = strtoul(kw->value, &endptr, 10);
+
+ if (token_info[token].type == ARG_ULNG)
+ {
+ if (*endptr != '\0')
+ {
+ plog("# bad integer value: %s=%s", kw->entry->name, kw->value);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if ((*endptr != '%') || (endptr[1] != '\0') || endptr == kw->value)
+ {
+ plog("# bad percent value: %s=%s", kw->entry->name, kw->value);
+ return FALSE;
+ }
+ }
+
}
- if (*endptr == 'd') /* time in days? */
+ break;
+ case ARG_TIME:
{
- *t *= 3600*24;
- break;
+ char *endptr;
+ time_t *t = (time_t *)p;
+
+ *t = strtoul(kw->value, &endptr, 10);
+
+ /* time in seconds? */
+ if (*endptr == '\0' || (*endptr == 's' && endptr[1] == '\0'))
+ break;
+
+ if (endptr[1] == '\0')
+ {
+ if (*endptr == 'm') /* time in minutes? */
+ {
+ *t *= 60;
+ break;
+ }
+ if (*endptr == 'h') /* time in hours? */
+ {
+ *t *= 3600;
+ break;
+ }
+ if (*endptr == 'd') /* time in days? */
+ {
+ *t *= 3600*24;
+ break;
+ }
+ }
+ plog("# bad duration value: %s=%s", kw->entry->name, kw->value);
+ return FALSE;
}
- }
- plog("# bad duration value: %s=%s", kw->entry->name, kw->value);
- return FALSE;
- }
- case ARG_STR:
- {
- char **cp = (char **)p;
-
- /* free any existing string */
- pfreeany(*cp);
-
- /* assign the new string */
- *cp = clone_str(kw->value, "str_value");
- }
- break;
- case ARG_LST:
- {
- char ***listp = (char ***)p;
-
- /* free any existing list */
- if (*listp != NULL)
- free_list(*listp);
-
- /* create a new list and assign values */
- *listp = new_list(kw->value);
+ case ARG_STR:
+ {
+ char **cp = (char **)p;
- /* is there a keyword list? */
- if (list != NULL)
- {
- char ** lst;
+ /* free any existing string */
+ free(*cp);
- for (lst = *listp; lst && *lst; lst++)
+ /* assign the new string */
+ *cp = clone_str(kw->value);
+ }
+ break;
+ case ARG_LST:
{
- bool match = FALSE;
-
- list = token_info[token].list;
-
- while (*list != NULL && !match)
- {
- match = streq(*lst, *list++);
- }
- if (!match)
- {
- plog("# bad value: %s=%s", kw->entry->name, *lst);
- return FALSE;
- }
+ char ***listp = (char ***)p;
+
+ /* free any existing list */
+ if (*listp != NULL)
+ free_list(*listp);
+
+ /* create a new list and assign values */
+ *listp = new_list(kw->value);
+
+ /* is there a keyword list? */
+ if (list != NULL)
+ {
+ char ** lst;
+
+ for (lst = *listp; lst && *lst; lst++)
+ {
+ bool match = FALSE;
+
+ list = token_info[token].list;
+
+ while (*list != NULL && !match)
+ {
+ match = streq(*lst, *list++);
+ }
+ if (!match)
+ {
+ plog("# bad value: %s=%s", kw->entry->name, *lst);
+ return FALSE;
+ }
+ }
+ }
}
- }
+ default:
+ return TRUE;
}
- default:
- return TRUE;
- }
- *assigned = TRUE;
- return TRUE;
+ *assigned = TRUE;
+ return TRUE;
}
/*
@@ -504,37 +517,37 @@ assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw, char *base
void
free_args(kw_token_t first, kw_token_t last, char *base)
{
- kw_token_t token;
-
- for (token = first; token <= last; token++)
- {
- char *p = base + token_info[token].offset;
+ kw_token_t token;
- switch (token_info[token].type)
+ for (token = first; token <= last; token++)
{
- case ARG_STR:
- {
- char **cp = (char **)p;
+ char *p = base + token_info[token].offset;
- pfreeany(*cp);
- *cp = NULL;
- }
- break;
- case ARG_LST:
- {
- char ***listp = (char ***)p;
-
- if (*listp != NULL)
+ switch (token_info[token].type)
{
- free_list(*listp);
- *listp = NULL;
- }
- }
- break;
- default:
- break;
+ case ARG_STR:
+ {
+ char **cp = (char **)p;
+
+ free(*cp);
+ *cp = NULL;
+ }
+ break;
+ case ARG_LST:
+ {
+ char ***listp = (char ***)p;
+
+ if (*listp != NULL)
+ {
+ free_list(*listp);
+ *listp = NULL;
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
- }
}
/*
@@ -543,38 +556,38 @@ free_args(kw_token_t first, kw_token_t last, char *base)
void
clone_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
{
- kw_token_t token;
+ kw_token_t token;
- for (token = first; token <= last; token++)
- {
- if (token_info[token].type == ARG_STR)
+ for (token = first; token <= last; token++)
{
- char **cp1 = (char **)(base1 + token_info[token].offset);
- char **cp2 = (char **)(base2 + token_info[token].offset);
+ if (token_info[token].type == ARG_STR)
+ {
+ char **cp1 = (char **)(base1 + token_info[token].offset);
+ char **cp2 = (char **)(base2 + token_info[token].offset);
- *cp1 = clone_str(*cp2, "cloned str");
+ *cp1 = clone_str(*cp2);
+ }
}
- }
}
static bool
cmp_list(char **list1, char **list2)
{
- if ((list1 == NULL) && (list2 == NULL))
- return TRUE;
- if ((list1 == NULL) || (list2 == NULL))
- return FALSE;
+ if ((list1 == NULL) && (list2 == NULL))
+ return TRUE;
+ if ((list1 == NULL) || (list2 == NULL))
+ return FALSE;
- for ( ; *list1 && *list2; list1++, list2++)
- {
- if (strcmp(*list1,*list2) != 0)
- return FALSE;
- }
+ for ( ; *list1 && *list2; list1++, list2++)
+ {
+ if (strcmp(*list1,*list2) != 0)
+ return FALSE;
+ }
- if ((*list1 != NULL) || (*list2 != NULL))
- return FALSE;
+ if ((*list1 != NULL) || (*list2 != NULL))
+ return FALSE;
- return TRUE;
+ return TRUE;
}
/*
@@ -583,75 +596,75 @@ cmp_list(char **list1, char **list2)
bool
cmp_args(kw_token_t first, kw_token_t last, char *base1, char *base2)
{
- kw_token_t token;
-
- for (token = first; token <= last; token++)
- {
- char *p1 = base1 + token_info[token].offset;
- char *p2 = base2 + token_info[token].offset;
+ kw_token_t token;
- switch (token_info[token].type)
+ for (token = first; token <= last; token++)
{
- case ARG_ENUM:
- {
- int *i1 = (int *)p1;
- int *i2 = (int *)p2;
-
- if (*i1 != *i2)
- return FALSE;
- }
- break;
- case ARG_UINT:
- {
- u_int *u1 = (u_int *)p1;
- u_int *u2 = (u_int *)p2;
-
- if (*u1 != *u2)
- return FALSE;
- }
- break;
- case ARG_ULNG:
- case ARG_PCNT:
- {
- unsigned long *l1 = (unsigned long *)p1;
- unsigned long *l2 = (unsigned long *)p2;
-
- if (*l1 != *l2)
- return FALSE;
- }
- break;
- case ARG_TIME:
- {
- time_t *t1 = (time_t *)p1;
- time_t *t2 = (time_t *)p2;
-
- if (*t1 != *t2)
- return FALSE;
- }
- break;
- case ARG_STR:
- {
- char **cp1 = (char **)p1;
- char **cp2 = (char **)p2;
-
- if (*cp1 == NULL && *cp2 == NULL)
- break;
- if (*cp1 == NULL || *cp2 == NULL || strcmp(*cp1, *cp2) != 0)
- return FALSE;
- }
- break;
- case ARG_LST:
- {
- char ***listp1 = (char ***)p1;
- char ***listp2 = (char ***)p2;
-
- if (!cmp_list(*listp1, *listp2))
- return FALSE;
- }
- break;
- default:
- break;
+ char *p1 = base1 + token_info[token].offset;
+ char *p2 = base2 + token_info[token].offset;
+
+ switch (token_info[token].type)
+ {
+ case ARG_ENUM:
+ {
+ int *i1 = (int *)p1;
+ int *i2 = (int *)p2;
+
+ if (*i1 != *i2)
+ return FALSE;
+ }
+ break;
+ case ARG_UINT:
+ {
+ u_int *u1 = (u_int *)p1;
+ u_int *u2 = (u_int *)p2;
+
+ if (*u1 != *u2)
+ return FALSE;
+ }
+ break;
+ case ARG_ULNG:
+ case ARG_PCNT:
+ {
+ unsigned long *l1 = (unsigned long *)p1;
+ unsigned long *l2 = (unsigned long *)p2;
+
+ if (*l1 != *l2)
+ return FALSE;
+ }
+ break;
+ case ARG_TIME:
+ {
+ time_t *t1 = (time_t *)p1;
+ time_t *t2 = (time_t *)p2;
+
+ if (*t1 != *t2)
+ return FALSE;
+ }
+ break;
+ case ARG_STR:
+ {
+ char **cp1 = (char **)p1;
+ char **cp2 = (char **)p2;
+
+ if (*cp1 == NULL && *cp2 == NULL)
+ break;
+ if (*cp1 == NULL || *cp2 == NULL || strcmp(*cp1, *cp2) != 0)
+ return FALSE;
+ }
+ break;
+ case ARG_LST:
+ {
+ char ***listp1 = (char ***)p1;
+ char ***listp2 = (char ***)p2;
+
+ if (!cmp_list(*listp1, *listp2))
+ return FALSE;
+ }
+ break;
+ default:
+ break;
+ }
}
- }
- return TRUE;
+ return TRUE;
}
diff --git a/src/starter/args.h b/src/starter/args.h
index 7bd55bb05..b003784c8 100644
--- a/src/starter/args.h
+++ b/src/starter/args.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: args.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _ARGS_H_
@@ -23,12 +21,12 @@
extern char **new_list(char *value);
extern bool assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw
- , char *base, bool *assigned);
+ , char *base, bool *assigned);
extern void free_args(kw_token_t first, kw_token_t last, char *base);
extern void clone_args(kw_token_t first, kw_token_t last, char *base1
- , char *base2);
+ , char *base2);
extern bool cmp_args(kw_token_t first, kw_token_t last, char *base1
- , char *base2);
+ , char *base2);
#endif /* _ARGS_H_ */
diff --git a/src/starter/cmp.c b/src/starter/cmp.c
index 5abb8399b..8462a4819 100644
--- a/src/starter/cmp.c
+++ b/src/starter/cmp.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: cmp.c 3881 2008-04-27 11:04:13Z andreas $
*/
#include <string.h>
@@ -34,79 +32,79 @@
static bool
starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
-
- if (c2->dns_failed)
- {
- c2->addr = c1->addr;
- }
- else
- {
- ADDCMP(addr);
- }
- ADDCMP(nexthop);
- VARCMP(has_client);
- VARCMP(has_client_wildcard);
- VARCMP(has_port_wildcard);
- VARCMP(has_natip);
- VARCMP(has_virt);
- VARCMP(modecfg);
- VARCMP(port);
- VARCMP(protocol);
-
- return cmp_args(KW_END_FIRST, KW_END_LAST, (char *)c1, (char *)c2);
+ if ((c1 == NULL) || (c2 == NULL))
+ return FALSE;
+
+ if (c2->dns_failed)
+ {
+ c2->addr = c1->addr;
+ }
+ else
+ {
+ ADDCMP(addr);
+ }
+ ADDCMP(nexthop);
+ VARCMP(has_client);
+ VARCMP(has_client_wildcard);
+ VARCMP(has_port_wildcard);
+ VARCMP(has_natip);
+ VARCMP(has_virt);
+ VARCMP(modecfg);
+ VARCMP(port);
+ VARCMP(protocol);
+
+ return cmp_args(KW_END_FIRST, KW_END_LAST, (char *)c1, (char *)c2);
}
bool
starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2)
{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
+ if ((c1 == NULL) || (c2 == NULL))
+ return FALSE;
- VARCMP(policy);
- VARCMP(addr_family);
- VARCMP(tunnel_addr_family);
+ VARCMP(policy);
+ VARCMP(addr_family);
+ VARCMP(tunnel_addr_family);
- if (!starter_cmp_end(&c1->left, &c2->left))
- return FALSE;
- if (!starter_cmp_end(&c1->right, &c2->right))
- return FALSE;
+ if (!starter_cmp_end(&c1->left, &c2->left))
+ return FALSE;
+ if (!starter_cmp_end(&c1->right, &c2->right))
+ return FALSE;
- return cmp_args(KW_CONN_NAME, KW_CONN_LAST, (char *)c1, (char *)c2);
+ return cmp_args(KW_CONN_NAME, KW_CONN_LAST, (char *)c1, (char *)c2);
}
bool
starter_cmp_ca(starter_ca_t *c1, starter_ca_t *c2)
{
- if (c1 == NULL || c2 == NULL)
- return FALSE;
+ if (c1 == NULL || c2 == NULL)
+ return FALSE;
- return cmp_args(KW_CA_NAME, KW_CA_LAST, (char *)c1, (char *)c2);
+ return cmp_args(KW_CA_NAME, KW_CA_LAST, (char *)c1, (char *)c2);
}
bool
starter_cmp_klips(starter_config_t *c1, starter_config_t *c2)
{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
+ if ((c1 == NULL) || (c2 == NULL))
+ return FALSE;
- return cmp_args(KW_KLIPS_FIRST, KW_KLIPS_LAST, (char *)c1, (char *)c2);
+ return cmp_args(KW_KLIPS_FIRST, KW_KLIPS_LAST, (char *)c1, (char *)c2);
}
bool
starter_cmp_pluto(starter_config_t *c1, starter_config_t *c2)
{
- if ((c1 == NULL) || (c2 == NULL))
- return FALSE;
+ if ((c1 == NULL) || (c2 == NULL))
+ return FALSE;
- return cmp_args(KW_PLUTO_FIRST, KW_PLUTO_LAST, (char *)c1, (char *)c2);
+ return cmp_args(KW_PLUTO_FIRST, KW_PLUTO_LAST, (char *)c1, (char *)c2);
}
bool
starter_cmp_defaultroute(defaultroute_t *d1, defaultroute_t *d2)
{
- if ((d1 == NULL) || (d2 == NULL))
- return FALSE;
- return memcmp(d1, d2, sizeof(defaultroute_t)) == 0;
+ if ((d1 == NULL) || (d2 == NULL))
+ return FALSE;
+ return memcmp(d1, d2, sizeof(defaultroute_t)) == 0;
}
diff --git a/src/starter/cmp.h b/src/starter/cmp.h
index 24bd32ff6..cda6e44b9 100644
--- a/src/starter/cmp.h
+++ b/src/starter/cmp.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: cmp.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_CMP_H_
diff --git a/src/starter/confread.c b/src/starter/confread.c
index 855d07b51..5fd2b9fbf 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: confread.c 5002 2009-03-24 15:02:12Z martin $
*/
#include <stddef.h>
@@ -34,8 +32,8 @@
/* strings containing a colon are interpreted as an IPv6 address */
#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
-static const char ike_defaults[] = "aes128-sha-modp2048";
-static const char esp_defaults[] = "aes128-sha1, 3des-md5";
+static const char ike_defaults[] = "aes128-sha1-modp2048,3des-sha1-modp1536";
+static const char esp_defaults[] = "aes128-sha1,3des-sha1";
static const char firewall_defaults[] = "ipsec _updown iptables";
@@ -72,11 +70,11 @@ static void default_values(starter_config_t *cfg)
cfg->conn_default.seen = LEMPTY;
cfg->conn_default.startup = STARTUP_NO;
cfg->conn_default.state = STATE_IGNORE;
- cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_RSASIG |
+ cfg->conn_default.policy = POLICY_ENCRYPT | POLICY_TUNNEL | POLICY_PUBKEY |
POLICY_PFS | POLICY_MOBIKE;
- cfg->conn_default.ike = clone_str(ike_defaults, "ike_defaults");
- cfg->conn_default.esp = clone_str(esp_defaults, "esp_defaults");
+ cfg->conn_default.ike = clone_str(ike_defaults);
+ cfg->conn_default.esp = clone_str(esp_defaults);
cfg->conn_default.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
cfg->conn_default.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
cfg->conn_default.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
@@ -144,7 +142,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
{
err_t ugh = NULL;
bool assigned = FALSE;
- int has_port_wildcard; /* set if port is %any */
+ bool has_port_wildcard; /* set if port is %any */
char *name = kw->entry->name;
char *value = kw->value;
@@ -193,7 +191,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
streq(value, "%config") || streq(value, "%cfg"))
{
- pfree(end->srcip);
+ free(end->srcip);
end->srcip = NULL;
end->modecfg = TRUE;
}
@@ -336,7 +334,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
plog("# bad subnet: %s=%s [%s]", name, value, ugh);
goto err;
}
- end->subnet = clone_str(value, "subnetwithin");
+ end->subnet = clone_str(value);
break;
}
case KW_PROTOPORT:
@@ -356,7 +354,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
if (cfg->defaultroute.defined)
{
addrtot(&cfg->defaultroute.addr, 0, buf, sizeof(buf));
- end->srcip = clone_str(buf, "natip");
+ end->srcip = clone_str(buf);
}
else
{
@@ -375,7 +373,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
plog("# bad addr: %s=%s [%s]", name, value, ugh);
goto err;
}
- end->srcip = clone_str(value, "srcip");
+ end->srcip = clone_str(value);
}
end->has_natip = TRUE;
conn->policy |= POLICY_TUNNEL;
@@ -426,7 +424,7 @@ handle_firewall( const char *label, starter_end_t *end, starter_config_t *cfg)
}
else
{
- end->updown = clone_str(firewall_defaults, "firewall_defaults");
+ end->updown = clone_str(firewall_defaults);
end->firewall = FALSE;
}
}
@@ -467,9 +465,9 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
{
if (cfg->parse_also)
{
- also_t *also = alloc_thing(also_t, "also_t");
+ also_t *also = malloc_thing(also_t);
- also->name = clone_str(kw->value, "also");
+ also->name = clone_str(kw->value);
also->next = conn->also;
conn->also = also;
@@ -557,18 +555,16 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
/* also handles the cases secret|rsasig and rsasig|secret */
for (;;)
{
- if (streq(value, "rsa") || streq(value, "rsasig"))
+ if (streq(value, "rsa") || streq(value, "rsasig") ||
+ streq(value, "ecdsa") || streq(value, "ecdsasig") ||
+ streq(value, "pubkey"))
{
- conn->policy |= POLICY_RSASIG | POLICY_ENCRYPT;
+ conn->policy |= POLICY_PUBKEY | POLICY_ENCRYPT;
}
else if (streq(value, "secret") || streq(value, "psk"))
{
conn->policy |= POLICY_PSK | POLICY_ENCRYPT;
}
- else if (streq(value, "ecdsa") || streq(value, "ecdsasig"))
- {
- conn->policy |= POLICY_ECDSASIG | POLICY_ENCRYPT;
- }
else if (streq(value, "xauthrsasig"))
{
conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
@@ -698,7 +694,7 @@ static void
conn_default(char *name, starter_conn_t *conn, starter_conn_t *def)
{
memcpy(conn, def, sizeof(starter_conn_t));
- conn->name = clone_str(name, "conn name");
+ conn->name = clone_str(name);
clone_args(KW_CONN_FIRST, KW_CONN_LAST, (char *)conn, (char *)def);
clone_args(KW_END_FIRST, KW_END_LAST, (char *)&conn->left, (char *)&def->left);
@@ -727,9 +723,9 @@ load_ca(starter_ca_t *ca, kw_list_t *kw, starter_config_t *cfg)
{
if (cfg->parse_also)
{
- also_t *also = alloc_thing(also_t, "also_t");
+ also_t *also = malloc_thing(also_t);
- also->name = clone_str(kw->value, "also");
+ also->name = clone_str(kw->value);
also->next = ca->also;
ca->also = also;
@@ -766,7 +762,7 @@ static void
ca_default(char *name, starter_ca_t *ca, starter_ca_t *def)
{
memcpy(ca, def, sizeof(starter_ca_t));
- ca->name = clone_str(name, "ca name");
+ ca->name = clone_str(name);
clone_args(KW_CA_FIRST, KW_CA_LAST, (char *)ca, (char *)def);
}
@@ -896,8 +892,8 @@ free_also(also_t *head)
also_t *also = head;
head = also->next;
- pfree(also->name);
- pfree(also);
+ free(also->name);
+ free(also);
}
}
@@ -942,7 +938,7 @@ confread_free(starter_config_t *cfg)
conn = conn->next;
confread_free_conn(conn_aux);
- pfree(conn_aux);
+ free(conn_aux);
}
confread_free_ca(&cfg->ca_default);
@@ -953,10 +949,10 @@ confread_free(starter_config_t *cfg)
ca = ca->next;
confread_free_ca(ca_aux);
- pfree(ca_aux);
+ free(ca_aux);
}
- pfree(cfg);
+ free(cfg);
}
/*
@@ -980,7 +976,7 @@ confread_load(const char *file)
{
return NULL;
}
- cfg = (starter_config_t *)alloc_thing(starter_config_t, "starter_config_t");
+ cfg = malloc_thing(starter_config_t);
/* set default values */
default_values(cfg);
@@ -1021,7 +1017,7 @@ confread_load(const char *file)
DBG(DBG_CONTROL,
DBG_log("Loading ca '%s'", sca->name)
)
- ca = (starter_ca_t *)alloc_thing(starter_ca_t, "starter_ca_t");
+ ca = malloc_thing(starter_ca_t);
ca_default(sca->name, ca, &cfg->ca_default);
ca->kw = sca->kw;
@@ -1092,7 +1088,7 @@ confread_load(const char *file)
DBG(DBG_CONTROL,
DBG_log("Loading conn '%s'", sconn->name)
)
- conn = (starter_conn_t *)alloc_thing(starter_conn_t, "starter_conn_t");
+ conn = malloc_thing(starter_conn_t);
conn_default(sconn->name, conn, &cfg->conn_default);
conn->kw = sconn->kw;
diff --git a/src/starter/confread.h b/src/starter/confread.h
index 24a8d073e..b20c2e0d3 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: confread.h 4612 2008-11-11 06:37:37Z andreas $
*/
#ifndef _IPSEC_CONFREAD_H_
@@ -20,205 +18,209 @@
#ifndef _FREESWAN_H
#include <freeswan.h>
-#include "../pluto/constants.h"
#endif
#include "parser.h"
#include "interfaces.h"
typedef enum {
- STARTUP_NO,
- STARTUP_ADD,
- STARTUP_ROUTE,
- STARTUP_START
+ STARTUP_NO,
+ STARTUP_ADD,
+ STARTUP_ROUTE,
+ STARTUP_START
} startup_t;
typedef enum {
- STATE_IGNORE,
- STATE_TO_ADD,
- STATE_ADDED,
- STATE_REPLACED,
- STATE_INVALID
+ STATE_IGNORE,
+ STATE_TO_ADD,
+ STATE_ADDED,
+ STATE_REPLACED,
+ STATE_INVALID
} starter_state_t;
typedef enum {
- KEY_EXCHANGE_IKE,
- KEY_EXCHANGE_IKEV1,
- KEY_EXCHANGE_IKEV2
+ KEY_EXCHANGE_IKE,
+ KEY_EXCHANGE_IKEV1,
+ KEY_EXCHANGE_IKEV2
} keyexchange_t;
typedef enum {
- STRICT_NO,
- STRICT_YES,
- STRICT_IFURI
+ STRICT_NO,
+ STRICT_YES,
+ STRICT_IFURI
} strict_t;
typedef struct starter_end starter_end_t;
struct starter_end {
- lset_t seen;
- char *id;
- char *rsakey;
- char *cert;
- char *ca;
- char *groups;
- char *iface;
- ip_address addr;
- ip_address nexthop;
- char *subnet;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_natip;
- bool has_virt;
- bool modecfg;
- certpolicy_t sendcert;
- bool firewall;
- bool hostaccess;
- bool allow_any;
- bool dns_failed;
- char *updown;
- u_int16_t port;
- u_int8_t protocol;
- char *srcip;
+ lset_t seen;
+ char *auth;
+ char *auth2;
+ char *id;
+ char *id2;
+ char *rsakey;
+ char *cert;
+ char *cert2;
+ char *ca;
+ char *ca2;
+ char *groups;
+ char *iface;
+ ip_address addr;
+ ip_address nexthop;
+ char *subnet;
+ bool has_client;
+ bool has_client_wildcard;
+ bool has_port_wildcard;
+ bool has_natip;
+ bool has_virt;
+ bool modecfg;
+ certpolicy_t sendcert;
+ bool firewall;
+ bool hostaccess;
+ bool allow_any;
+ bool dns_failed;
+ char *updown;
+ u_int16_t port;
+ u_int8_t protocol;
+ char *srcip;
};
typedef struct also also_t;
struct also {
- char *name;
- bool included;
- also_t *next;
+ char *name;
+ bool included;
+ also_t *next;
};
typedef struct starter_conn starter_conn_t;
struct starter_conn {
- lset_t seen;
- char *name;
- also_t *also;
- kw_list_t *kw;
- u_int visit;
- startup_t startup;
- starter_state_t state;
-
- keyexchange_t keyexchange;
- u_int32_t eap_type;
- u_int32_t eap_vendor;
- char *eap_identity;
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_keying_tries;
- unsigned long sa_rekey_fuzz;
- sa_family_t addr_family;
- sa_family_t tunnel_addr_family;
- bool install_policy;
- starter_end_t left, right;
-
- unsigned long id;
-
- char *esp;
- char *ike;
- char *pfsgroup;
-
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
- int dpd_count;
-
- bool me_mediation;
- char *me_mediated_by;
- char *me_peerid;
-
- starter_conn_t *next;
+ lset_t seen;
+ char *name;
+ also_t *also;
+ kw_list_t *kw;
+ u_int visit;
+ startup_t startup;
+ starter_state_t state;
+
+ keyexchange_t keyexchange;
+ u_int32_t eap_type;
+ u_int32_t eap_vendor;
+ char *eap_identity;
+ lset_t policy;
+ time_t sa_ike_life_seconds;
+ time_t sa_ipsec_life_seconds;
+ time_t sa_rekey_margin;
+ unsigned long sa_keying_tries;
+ unsigned long sa_rekey_fuzz;
+ sa_family_t addr_family;
+ sa_family_t tunnel_addr_family;
+ bool install_policy;
+ starter_end_t left, right;
+
+ unsigned long id;
+
+ char *esp;
+ char *ike;
+ char *pfsgroup;
+
+ time_t dpd_delay;
+ time_t dpd_timeout;
+ dpd_action_t dpd_action;
+ int dpd_count;
+
+ bool me_mediation;
+ char *me_mediated_by;
+ char *me_peerid;
+
+ starter_conn_t *next;
};
typedef struct starter_ca starter_ca_t;
struct starter_ca {
- lset_t seen;
- char *name;
- also_t *also;
- kw_list_t *kw;
- u_int visit;
- startup_t startup;
- starter_state_t state;
-
- char *cacert;
- char *ldaphost;
- char *ldapbase;
- char *crluri;
- char *crluri2;
- char *ocspuri;
- char *ocspuri2;
- char *certuribase;
-
- bool strict;
-
- starter_ca_t *next;
+ lset_t seen;
+ char *name;
+ also_t *also;
+ kw_list_t *kw;
+ u_int visit;
+ startup_t startup;
+ starter_state_t state;
+
+ char *cacert;
+ char *ldaphost;
+ char *ldapbase;
+ char *crluri;
+ char *crluri2;
+ char *ocspuri;
+ char *ocspuri2;
+ char *certuribase;
+
+ bool strict;
+
+ starter_ca_t *next;
};
typedef struct starter_config starter_config_t;
struct starter_config {
- struct {
- lset_t seen;
- char **interfaces;
- char *dumpdir;
- bool charonstart;
- bool plutostart;
-
- /* pluto/charon keywords */
- char **plutodebug;
- char *charondebug;
- char *prepluto;
- char *postpluto;
- char *plutostderrlog;
- bool uniqueids;
- u_int overridemtu;
- u_int crlcheckinterval;
- bool cachecrls;
- strict_t strictcrlpolicy;
- bool nocrsend;
- bool nat_traversal;
- u_int keep_alive;
- u_int force_keepalive;
- char *virtual_private;
- char *pkcs11module;
- char *pkcs11initargs;
- bool pkcs11keepstate;
- bool pkcs11proxy;
-
- /* KLIPS keywords */
- char **klipsdebug;
- bool fragicmp;
- char *packetdefault;
- bool hidetos;
- } setup;
-
- /* information about the default route */
- defaultroute_t defaultroute;
-
- /* number of encountered parsing errors */
- u_int err;
- u_int non_fatal_err;
-
- /* do we parse also statements */
- bool parse_also;
-
- /* ca %default */
- starter_ca_t ca_default;
-
- /* connections list (without %default) */
- starter_ca_t *ca_first, *ca_last;
-
- /* conn %default */
- starter_conn_t conn_default;
-
- /* connections list (without %default) */
- starter_conn_t *conn_first, *conn_last;
+ struct {
+ lset_t seen;
+ char **interfaces;
+ char *dumpdir;
+ bool charonstart;
+ bool plutostart;
+
+ /* pluto/charon keywords */
+ char **plutodebug;
+ char *charondebug;
+ char *prepluto;
+ char *postpluto;
+ char *plutostderrlog;
+ bool uniqueids;
+ u_int overridemtu;
+ u_int crlcheckinterval;
+ bool cachecrls;
+ strict_t strictcrlpolicy;
+ bool nocrsend;
+ bool nat_traversal;
+ u_int keep_alive;
+ u_int force_keepalive;
+ char *virtual_private;
+ char *pkcs11module;
+ char *pkcs11initargs;
+ bool pkcs11keepstate;
+ bool pkcs11proxy;
+
+ /* KLIPS keywords */
+ char **klipsdebug;
+ bool fragicmp;
+ char *packetdefault;
+ bool hidetos;
+ } setup;
+
+ /* information about the default route */
+ defaultroute_t defaultroute;
+
+ /* number of encountered parsing errors */
+ u_int err;
+ u_int non_fatal_err;
+
+ /* do we parse also statements */
+ bool parse_also;
+
+ /* ca %default */
+ starter_ca_t ca_default;
+
+ /* connections list (without %default) */
+ starter_ca_t *ca_first, *ca_last;
+
+ /* conn %default */
+ starter_conn_t conn_default;
+
+ /* connections list (without %default) */
+ starter_conn_t *conn_first, *conn_last;
};
extern starter_config_t *confread_load(const char *file);
diff --git a/src/starter/exec.c b/src/starter/exec.c
index eed444c74..d4c4f0657 100644
--- a/src/starter/exec.c
+++ b/src/starter/exec.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: exec.c 3267 2007-10-08 19:57:54Z andreas $
*/
#include <stdlib.h>
@@ -37,18 +35,18 @@
int
starter_exec(const char *fmt, ...)
{
- va_list args;
- static char buf[BUF_SIZE];
- int r;
-
- va_start (args, fmt);
- vsnprintf(buf, BUF_SIZE-1, fmt, args);
- buf[BUF_SIZE - 1] = '\0';
- va_end(args);
- r = system(buf);
- DBG(DBG_CONTROL,
- DBG_log("starter_exec(%s) = %d", buf, r)
- )
- return r;
+ va_list args;
+ static char buf[BUF_SIZE];
+ int r;
+
+ va_start (args, fmt);
+ vsnprintf(buf, BUF_SIZE-1, fmt, args);
+ buf[BUF_SIZE - 1] = '\0';
+ va_end(args);
+ r = system(buf);
+ DBG(DBG_CONTROL,
+ DBG_log("starter_exec(%s) = %d", buf, r)
+ )
+ return r;
}
diff --git a/src/starter/exec.h b/src/starter/exec.h
index 49d795e1a..6a6414578 100644
--- a/src/starter/exec.h
+++ b/src/starter/exec.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: exec.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_EXEC_H_
diff --git a/src/starter/files.h b/src/starter/files.h
index a40574594..ec41c9f2e 100644
--- a/src/starter/files.h
+++ b/src/starter/files.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: files.h 4618 2008-11-11 09:22:00Z tobias $
*/
#ifndef _STARTER_FILES_H_
@@ -19,18 +17,18 @@
#define STARTER_PID_FILE IPSEC_PIDDIR "/starter.pid"
-#define PROC_NETKEY "/proc/net/pfkey"
-#define PROC_KLIPS "/proc/net/pf_key"
-#define PROC_MODULES "/proc/modules"
+#define PROC_NETKEY "/proc/net/pfkey"
+#define PROC_KLIPS "/proc/net/pf_key"
+#define PROC_MODULES "/proc/modules"
#define CONFIG_FILE IPSEC_CONFDIR "/ipsec.conf"
-#define SECRETS_FILE IPSEC_CONFDIR "/ipsec.secrets"
+#define SECRETS_FILE IPSEC_CONFDIR "/ipsec.secrets"
#define PLUTO_CMD IPSEC_DIR "/pluto"
#define PLUTO_CTL_FILE IPSEC_PIDDIR "/pluto.ctl"
#define PLUTO_PID_FILE IPSEC_PIDDIR "/pluto.pid"
-#define CHARON_CMD IPSEC_DIR "/charon"
+#define CHARON_CMD IPSEC_DIR "/charon"
#define CHARON_CTL_FILE IPSEC_PIDDIR "/charon.ctl"
#define CHARON_PID_FILE IPSEC_PIDDIR "/charon.pid"
diff --git a/src/starter/interfaces.c b/src/starter/interfaces.c
index 5cec8a217..034eac317 100644
--- a/src/starter/interfaces.c
+++ b/src/starter/interfaces.c
@@ -10,20 +10,16 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: interfaces.c 3267 2007-10-08 19:57:54Z andreas $
*/
#include <sys/socket.h>
#include <sys/ioctl.h>
-#include <linux/if.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <freeswan.h>
-#include <ipsec_tunnel.h>
#include <constants.h>
#include <defs.h>
@@ -39,114 +35,114 @@
void
get_defaultroute(defaultroute_t *defaultroute)
{
- FILE *fd;
- char line[BUF_LEN];
- bool first = TRUE;
+ FILE *fd;
+ char line[BUF_LEN];
+ bool first = TRUE;
- memset(defaultroute, 0, sizeof(defaultroute_t));
+ memset(defaultroute, 0, sizeof(defaultroute_t));
- fd = fopen("/proc/net/route", "r");
+ fd = fopen("/proc/net/route", "r");
- if (!fd)
- {
- plog("could not open 'proc/net/route'");
- return;
- }
-
- while (fgets(line, sizeof(line), fd) != 0)
- {
- char iface[11];
- char destination[9];
- char gateway[11];
- char flags[5];
- char mask[9];
-
- int refcnt;
- int use;
- int metric;
- int items;
-
- /* proc/net/route returns IP addresses in host order */
- strcpy(gateway, "0h");
-
- /* skip the header line */
- if (first)
+ if (!fd)
{
- first = FALSE;
- continue;
+ plog("could not open 'proc/net/route'");
+ return;
}
- /* parsing a single line of proc/net/route */
- items = sscanf(line, "%10s\t%8s\t%8s\t%5s\t%d\t%d\t%d\t%8s\t"
- , iface, destination, gateway+2, flags, &refcnt, &use, &metric, mask);
- if (items < 8)
+ while (fgets(line, sizeof(line), fd) != 0)
{
- plog("parsing error while scanning /proc/net/route");
- continue;
+ char iface[11];
+ char destination[9];
+ char gateway[11];
+ char flags[5];
+ char mask[9];
+
+ int refcnt;
+ int use;
+ int metric;
+ int items;
+
+ /* proc/net/route returns IP addresses in host order */
+ strcpy(gateway, "0h");
+
+ /* skip the header line */
+ if (first)
+ {
+ first = FALSE;
+ continue;
+ }
+
+ /* parsing a single line of proc/net/route */
+ items = sscanf(line, "%10s\t%8s\t%8s\t%5s\t%d\t%d\t%d\t%8s\t"
+ , iface, destination, gateway+2, flags, &refcnt, &use, &metric, mask);
+ if (items < 8)
+ {
+ plog("parsing error while scanning /proc/net/route");
+ continue;
+ }
+
+ /* check for defaultroute (destination 0.0.0.0 and mask 0.0.0.0) */
+ if (streq(destination, "00000000") && streq(mask, "00000000"))
+ {
+ if (defaultroute->defined)
+ {
+ plog("multiple default routes - cannot cope with %%defaultroute!!!");
+ defaultroute->defined = FALSE;
+ fclose(fd);
+ return;
+ }
+ ttoaddr(gateway, strlen(gateway), AF_INET, &defaultroute->nexthop);
+ strncpy(defaultroute->iface, iface, IFNAMSIZ);
+ defaultroute->defined = TRUE;
+ }
}
+ fclose(fd);
- /* check for defaultroute (destination 0.0.0.0 and mask 0.0.0.0) */
- if (streq(destination, "00000000") && streq(mask, "00000000"))
+ if (!defaultroute->defined)
{
- if (defaultroute->defined)
- {
- plog("multiple default routes - cannot cope with %%defaultroute!!!");
- defaultroute->defined = FALSE;
- fclose(fd);
- return;
- }
- ttoaddr(gateway, strlen(gateway), AF_INET, &defaultroute->nexthop);
- strncpy(defaultroute->iface, iface, IFNAMSIZ);
- defaultroute->defined = TRUE;
+ plog("no default route - cannot cope with %%defaultroute!!!");
}
- }
- fclose(fd);
-
- if (!defaultroute->defined)
- {
- plog("no default route - cannot cope with %%defaultroute!!!");
- }
- else
- {
- char addr_buf[20], nexthop_buf[20];
- struct ifreq physreq;
-
- int sock = socket(AF_INET, SOCK_DGRAM, 0);
-
- /* determine IP address of iface */
- if (sock < 0)
+ else
{
- plog("could not open SOCK_DGRAM socket");
- defaultroute->defined = FALSE;
- return;
+ char addr_buf[20], nexthop_buf[20];
+ struct ifreq physreq;
+
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+ /* determine IP address of iface */
+ if (sock < 0)
+ {
+ plog("could not open SOCK_DGRAM socket");
+ defaultroute->defined = FALSE;
+ return;
+ }
+ memset ((void*)&physreq, 0, sizeof(physreq));
+ strncpy(physreq.ifr_name, defaultroute->iface, IFNAMSIZ);
+ ioctl(sock, SIOCGIFADDR, &physreq);
+ close(sock);
+ defaultroute->addr.u.v4 = *((struct sockaddr_in *)&physreq.ifr_addr);
+
+ addrtot(&defaultroute->addr, 0, addr_buf, sizeof(addr_buf));
+ addrtot(&defaultroute->nexthop, 0, nexthop_buf, sizeof(nexthop_buf));
+
+ DBG(DBG_CONTROL,
+ DBG_log("Default route found: iface=%s, addr=%s, nexthop=%s"
+ , defaultroute->iface, addr_buf, nexthop_buf)
+ )
+
+ /* for backwards-compatibility with the awk shell scripts
+ * store the defaultroute in /var/run/ipsec.info
+ */
+ fd = fopen(INFO_FILE, "w");
+
+ if (fd)
+ {
+ fprintf(fd, "defaultroutephys=%s\n", defaultroute->iface );
+ fprintf(fd, "defaultroutevirt=ipsec0\n");
+ fprintf(fd, "defaultrouteaddr=%s\n", addr_buf);
+ fprintf(fd, "defaultroutenexthop=%s\n", nexthop_buf);
+ fclose(fd);
+ }
}
- memset ((void*)&physreq, 0, sizeof(physreq));
- strncpy(physreq.ifr_name, defaultroute->iface, IFNAMSIZ);
- ioctl(sock, SIOCGIFADDR, &physreq);
- close(sock);
- defaultroute->addr.u.v4 = *((struct sockaddr_in *)&physreq.ifr_addr);
-
- addrtot(&defaultroute->addr, 0, addr_buf, sizeof(addr_buf));
- addrtot(&defaultroute->nexthop, 0, nexthop_buf, sizeof(nexthop_buf));
-
- DBG(DBG_CONTROL,
- DBG_log("Default route found: iface=%s, addr=%s, nexthop=%s"
- , defaultroute->iface, addr_buf, nexthop_buf)
- )
-
- /* for backwards-compatibility with the awk shell scripts
- * store the defaultroute in /var/run/ipsec.info
- */
- fd = fopen(INFO_FILE, "w");
-
- if (fd)
- {
- fprintf(fd, "defaultroutephys=%s\n", defaultroute->iface );
- fprintf(fd, "defaultroutevirt=ipsec0\n");
- fprintf(fd, "defaultrouteaddr=%s\n", addr_buf);
- fprintf(fd, "defaultroutenexthop=%s\n", nexthop_buf);
- fclose(fd);
- }
- }
- return;
+ return;
}
diff --git a/src/starter/interfaces.h b/src/starter/interfaces.h
index 299113669..abe4c8f9c 100644
--- a/src/starter/interfaces.h
+++ b/src/starter/interfaces.h
@@ -10,22 +10,22 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: interfaces.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_INTERFACES_H_
#define _STARTER_INTERFACES_H_
-#include <linux/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
#include "../pluto/constants.h"
typedef struct {
- bool defined;
- char iface[IFNAMSIZ];
- ip_address addr;
- ip_address nexthop;
+ bool defined;
+ char iface[IFNAMSIZ];
+ ip_address addr;
+ ip_address nexthop;
} defaultroute_t;
extern void get_defaultroute(defaultroute_t *defaultroute);
diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c
index dd3f5f018..804467cea 100644
--- a/src/starter/invokecharon.c
+++ b/src/starter/invokecharon.c
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: invokecharon.c 5050 2009-03-27 16:14:59Z andreas $
*/
#include <sys/types.h>
@@ -41,190 +39,197 @@ static int _stop_requested;
pid_t
starter_charon_pid(void)
{
- return _charon_pid;
+ return _charon_pid;
}
void
starter_charon_sigchild(pid_t pid)
{
- if (pid == _charon_pid)
- {
- _charon_pid = 0;
- if (!_stop_requested)
+ if (pid == _charon_pid)
{
- plog("charon has died -- restart scheduled (%dsec)"
- , CHARON_RESTART_DELAY);
- alarm(CHARON_RESTART_DELAY); // restart in 5 sec
+ _charon_pid = 0;
+ if (!_stop_requested)
+ {
+ plog("charon has died -- restart scheduled (%dsec)"
+ , CHARON_RESTART_DELAY);
+ alarm(CHARON_RESTART_DELAY); // restart in 5 sec
+ }
+ unlink(CHARON_PID_FILE);
}
- unlink(CHARON_PID_FILE);
- }
}
int
starter_stop_charon (void)
{
- int i;
- pid_t pid = _charon_pid;
+ int i;
+ pid_t pid = _charon_pid;
- if (pid)
- {
- _stop_requested = 1;
-
- /* be more and more aggressive */
- for (i = 0; i < 50 && (pid = _charon_pid) != 0; i++)
+ if (pid)
{
- if (i == 0)
- {
- kill(pid, SIGINT);
- }
- else if (i < 40)
- {
- kill(pid, SIGTERM);
- }
- else if (i == 40)
- {
- kill(pid, SIGKILL);
- plog("starter_stop_charon(): charon does not respond, sending KILL");
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(200000); /* sleep for 200 ms */
+ _stop_requested = 1;
+
+ /* be more and more aggressive */
+ for (i = 0; i < 50 && (pid = _charon_pid) != 0; i++)
+ {
+ if (i == 0)
+ {
+ kill(pid, SIGINT);
+ }
+ else if (i < 40)
+ {
+ kill(pid, SIGTERM);
+ }
+ else if (i == 40)
+ {
+ kill(pid, SIGKILL);
+ plog("starter_stop_charon(): charon does not respond, sending KILL");
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(200000); /* sleep for 200 ms */
+ }
+ if (_charon_pid == 0)
+ {
+ plog("charon stopped after %d ms", 200*i);
+ return 0;
+ }
+ plog("starter_stop_charon(): can't stop charon !!!");
+ return -1;
}
- if (_charon_pid == 0)
+ else
{
- plog("charon stopped after %d ms", 200*i);
- return 0;
+ plog("stater_stop_charon(): charon was not started...");
}
- plog("starter_stop_charon(): can't stop charon !!!");
return -1;
- }
- else
- {
- plog("stater_stop_charon(): charon was not started...");
- }
- return -1;
}
int
-starter_start_charon (starter_config_t *cfg, bool no_fork)
+starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
{
- struct stat stb;
- int pid, i;
- char buffer[BUF_LEN];
- int argc = 1;
- char *arg[] = {
- CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- if (!no_fork)
- {
- arg[argc++] = "--use-syslog";
- }
-
- /* parse debug string */
- {
- int level;
- char type[4];
- char *pos = cfg->setup.charondebug;
- char *buf_pos = buffer;
-
- while (pos && sscanf(pos, "%4s %d,", type, &level) == 2)
- {
- snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "--debug-%s", type);
- arg[argc++] = buf_pos;
- buf_pos += strlen(buf_pos) + 1;
- if (buf_pos >= buffer + sizeof(buffer))
- {
- break;
- }
- snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "%d", level);
- arg[argc++] = buf_pos;
- buf_pos += strlen(buf_pos) + 1;
- if (buf_pos >= buffer + sizeof(buffer))
- {
- break;
- }
+ struct stat stb;
+ int pid, i;
+ char buffer[BUF_LEN];
+ int argc = 1;
+ char *arg[] = {
+ CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ };
- /* get next */
- pos = strchr(pos, ',');
- if (pos)
- {
- pos++;
- }
+ if (attach_gdb)
+ {
+ argc = 0;
+ arg[argc++] = "/usr/bin/gdb";
+ arg[argc++] = "--args";
+ arg[argc++] = CHARON_CMD;
+ }
+ if (!no_fork)
+ {
+ arg[argc++] = "--use-syslog";
}
- }
- if (_charon_pid)
- {
- plog("starter_start_charon(): charon already started...");
- return -1;
- }
- else
- {
- unlink(CHARON_CTL_FILE);
- _stop_requested = 0;
-
- pid = fork();
- switch (pid)
+ /* parse debug string */
{
- case -1:
- plog("can't fork(): %s", strerror(errno));
- return -1;
- case 0:
- /* child */
- setsid();
- sigprocmask(SIG_SETMASK, 0, NULL);
- /* disable glibc's malloc checker, conflicts with leak detective */
- setenv("MALLOC_CHECK_", "0", 1);
- execv(arg[0], arg);
- plog("can't execv(%s,...): %s", arg[0], strerror(errno));
- exit(1);
- default:
- /* father */
- _charon_pid = pid;
- for (i = 0; i < 500 && _charon_pid; i++)
- {
- /* wait for charon for a maximum of 500 x 20 ms = 10 s */
- usleep(20000);
- if (stat(CHARON_PID_FILE, &stb) == 0)
+ int level;
+ char type[4];
+ char *pos = cfg->setup.charondebug;
+ char *buf_pos = buffer;
+
+ while (pos && sscanf(pos, "%4s %d,", type, &level) == 2)
{
- plog("charon (%d) started after %d ms", _charon_pid, 20*(i+1));
- return 0;
+ snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "--debug-%s", type);
+ arg[argc++] = buf_pos;
+ buf_pos += strlen(buf_pos) + 1;
+ if (buf_pos >= buffer + sizeof(buffer))
+ {
+ break;
+ }
+ snprintf(buf_pos, buffer + sizeof(buffer) - buf_pos, "%d", level);
+ arg[argc++] = buf_pos;
+ buf_pos += strlen(buf_pos) + 1;
+ if (buf_pos >= buffer + sizeof(buffer))
+ {
+ break;
+ }
+
+ /* get next */
+ pos = strchr(pos, ',');
+ if (pos)
+ {
+ pos++;
+ }
}
- }
- if (_charon_pid)
- {
- /* If charon is started but with no ctl file, stop it */
- plog("charon too long to start... - kill kill");
- for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
+ }
+
+ if (_charon_pid)
+ {
+ plog("starter_start_charon(): charon already started...");
+ return -1;
+ }
+ else
+ {
+ unlink(CHARON_CTL_FILE);
+ _stop_requested = 0;
+
+ pid = fork();
+ switch (pid)
{
- if (i == 0)
- {
- kill(pid, SIGINT);
- }
- else if (i < 10)
- {
- kill(pid, SIGTERM);
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(20000); /* sleep for 20 ms */
+ case -1:
+ plog("can't fork(): %s", strerror(errno));
+ return -1;
+ case 0:
+ /* child */
+ setsid();
+ sigprocmask(SIG_SETMASK, 0, NULL);
+ /* disable glibc's malloc checker, conflicts with leak detective */
+ setenv("MALLOC_CHECK_", "0", 1);
+ execv(arg[0], arg);
+ plog("can't execv(%s,...): %s", arg[0], strerror(errno));
+ exit(1);
+ default:
+ /* father */
+ _charon_pid = pid;
+ for (i = 0; i < 500 && _charon_pid; i++)
+ {
+ /* wait for charon for a maximum of 500 x 20 ms = 10 s */
+ usleep(20000);
+ if (stat(CHARON_PID_FILE, &stb) == 0)
+ {
+ plog("charon (%d) started after %d ms", _charon_pid, 20*(i+1));
+ return 0;
+ }
+ }
+ if (_charon_pid)
+ {
+ /* If charon is started but with no ctl file, stop it */
+ plog("charon too long to start... - kill kill");
+ for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
+ {
+ if (i == 0)
+ {
+ kill(pid, SIGINT);
+ }
+ else if (i < 10)
+ {
+ kill(pid, SIGTERM);
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(20000); /* sleep for 20 ms */
+ }
+ }
+ else
+ {
+ plog("charon refused to be started");
+ }
+ return -1;
}
- }
- else
- {
- plog("charon refused to be started");
- }
- return -1;
}
- }
- return -1;
+ return -1;
}
diff --git a/src/starter/invokecharon.h b/src/starter/invokecharon.h
index c24d9bdb4..f0f470a8d 100644
--- a/src/starter/invokecharon.h
+++ b/src/starter/invokecharon.h
@@ -13,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: invokecharon.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_CHARON_H_
@@ -25,7 +23,7 @@
extern void starter_charon_sigchild (pid_t pid);
extern pid_t starter_charon_pid (void);
extern int starter_stop_charon (void);
-extern int starter_start_charon(struct starter_config *cfg, bool debug);
+extern int starter_start_charon(struct starter_config *cfg, bool no_fork, bool attach_gdb);
#endif /* _STARTER_CHARON_H_ */
diff --git a/src/starter/invokepluto.c b/src/starter/invokepluto.c
index edc587124..28bd93c5d 100644
--- a/src/starter/invokepluto.c
+++ b/src/starter/invokepluto.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: invokepluto.c 5050 2009-03-27 16:14:59Z andreas $
*/
#include <sys/types.h>
@@ -40,267 +38,277 @@ static int _stop_requested;
pid_t
starter_pluto_pid(void)
{
- return _pluto_pid;
+ return _pluto_pid;
}
void
starter_pluto_sigchild(pid_t pid)
{
- if (pid == _pluto_pid)
- {
- _pluto_pid = 0;
- if (!_stop_requested)
+ if (pid == _pluto_pid)
{
- plog("pluto has died -- restart scheduled (%dsec)"
- , PLUTO_RESTART_DELAY);
- alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
+ _pluto_pid = 0;
+ if (!_stop_requested)
+ {
+ plog("pluto has died -- restart scheduled (%dsec)"
+ , PLUTO_RESTART_DELAY);
+ alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
+ }
+ unlink(PLUTO_PID_FILE);
}
- unlink(PLUTO_PID_FILE);
- }
}
int
starter_stop_pluto (void)
{
- int i;
- pid_t pid = _pluto_pid;
-
- if (pid)
- {
- _stop_requested = 1;
+ int i;
+ pid_t pid = _pluto_pid;
- if (starter_whack_shutdown() == 0)
+ if (pid)
{
- for (i = 0; i < 400; i++)
- {
- usleep(20000); /* sleep for 20 ms */
+ _stop_requested = 1;
+
+ if (starter_whack_shutdown() == 0)
+ {
+ for (i = 0; i < 400; i++)
+ {
+ usleep(20000); /* sleep for 20 ms */
+ if (_pluto_pid == 0)
+ {
+ plog("pluto stopped after %d ms", 20*(i+1));
+ return 0;
+ }
+ }
+ }
+ /* be more and more aggressive */
+ for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
+ {
+
+ if (i < 10)
+ {
+ kill(pid, SIGTERM);
+ }
+ if (i == 10)
+ {
+ kill(pid, SIGKILL);
+ plog("starter_stop_pluto(): pluto does not respond, sending KILL");
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(100000); /* sleep for 100 ms */
+ }
if (_pluto_pid == 0)
{
- plog("pluto stopped after %d ms", 20*(i+1));
- return 0;
+ plog("pluto stopped after %d ms", 8000 + 100*i);
+ return 0;
}
- }
- }
- /* be more and more aggressive */
- for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
- {
-
- if (i < 10)
- {
- kill(pid, SIGTERM);
- }
- if (i == 10)
- {
- kill(pid, SIGKILL);
- plog("starter_stop_pluto(): pluto does not respond, sending KILL");
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(100000); /* sleep for 100 ms */
+ plog("starter_stop_pluto(): can't stop pluto !!!");
+ return -1;
}
- if (_pluto_pid == 0)
+ else
{
- plog("pluto stopped after %d ms", 8000 + 100*i);
- return 0;
+ plog("stater_stop_pluto(): pluto is not started...");
}
- plog("starter_stop_pluto(): can't stop pluto !!!");
return -1;
- }
- else
- {
- plog("stater_stop_pluto(): pluto is not started...");
- }
- return -1;
}
#define ADD_DEBUG(v) { \
- for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
- arg[argc++] = "--debug-" v; \
- }
+ for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
+ arg[argc++] = "--debug-" v; \
+ }
int
-starter_start_pluto (starter_config_t *cfg, bool no_fork)
+starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
{
- struct stat stb;
- int i;
- pid_t pid;
- char **l;
- int argc = 2;
- char *arg[] = {
- PLUTO_CMD, "--nofork"
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- printf ("starter_start_pluto entered\n");
+ struct stat stb;
+ int i;
+ pid_t pid;
+ char **l;
+ int argc = 2;
+ char *arg[] = {
+ PLUTO_CMD, "--nofork"
+ , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ };
- if (cfg->setup.plutostderrlog || no_fork)
- {
- arg[argc++] = "--stderrlog";
- }
- if (cfg->setup.uniqueids)
- {
- arg[argc++] = "--uniqueids";
- }
- ADD_DEBUG("none")
- ADD_DEBUG("all")
- ADD_DEBUG("raw")
- ADD_DEBUG("crypt")
- ADD_DEBUG("parsing")
- ADD_DEBUG("emitting")
- ADD_DEBUG("control")
- ADD_DEBUG("lifecycle")
- ADD_DEBUG("klips")
- ADD_DEBUG("dns")
- ADD_DEBUG("natt")
- ADD_DEBUG("oppo")
- ADD_DEBUG("controlmore")
- ADD_DEBUG("private")
- if (cfg->setup.crlcheckinterval > 0)
- {
- static char buf1[15];
-
- arg[argc++] = "--crlcheckinterval";
- snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
- arg[argc++] = buf1;
- }
- if (cfg->setup.cachecrls)
- {
- arg[argc++] = "--cachecrls";
- }
- if (cfg->setup.strictcrlpolicy)
- {
- arg[argc++] = "--strictcrlpolicy";
- }
- if (cfg->setup.nocrsend)
- {
- arg[argc++] = "--nocrsend";
- }
- if (cfg->setup.nat_traversal)
- {
- arg[argc++] = "--nat_traversal";
- }
- if (cfg->setup.force_keepalive)
- {
- arg[argc++] = "--force_keepalive";
- }
- if (cfg->setup.keep_alive)
- {
- static char buf2[15];
-
- arg[argc++] = "--keep_alive";
- snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
- arg[argc++] = buf2;
- }
- if (cfg->setup.virtual_private)
- {
- arg[argc++] = "--virtual_private";
- arg[argc++] = cfg->setup.virtual_private;
- }
- if (cfg->setup.pkcs11module)
- {
- arg[argc++] = "--pkcs11module";
- arg[argc++] = cfg->setup.pkcs11module;
- }
- if (cfg->setup.pkcs11initargs)
- {
- arg[argc++] = "--pkcs11initargs";
- arg[argc++] = cfg->setup.pkcs11initargs;
- }
- if (cfg->setup.pkcs11keepstate)
- {
- arg[argc++] = "--pkcs11keepstate";
- }
- if (cfg->setup.pkcs11proxy)
- {
- arg[argc++] = "--pkcs11proxy";
- }
+ printf ("starter_start_pluto entered\n");
+
+ if (attach_gdb)
+ {
+ argc = 0;
+ arg[argc++] = "/usr/bin/gdb";
+ arg[argc++] = "--args";
+ arg[argc++] = PLUTO_CMD;
+ arg[argc++] = "--nofork";
+ }
+ if (cfg->setup.plutostderrlog || no_fork)
+ {
+ arg[argc++] = "--stderrlog";
+ }
+ if (cfg->setup.uniqueids)
+ {
+ arg[argc++] = "--uniqueids";
+ }
+ ADD_DEBUG("none")
+ ADD_DEBUG("all")
+ ADD_DEBUG("raw")
+ ADD_DEBUG("crypt")
+ ADD_DEBUG("parsing")
+ ADD_DEBUG("emitting")
+ ADD_DEBUG("control")
+ ADD_DEBUG("lifecycle")
+ ADD_DEBUG("klips")
+ ADD_DEBUG("dns")
+ ADD_DEBUG("natt")
+ ADD_DEBUG("oppo")
+ ADD_DEBUG("controlmore")
+ ADD_DEBUG("private")
+ if (cfg->setup.crlcheckinterval > 0)
+ {
+ static char buf1[15];
- if (_pluto_pid)
- {
- plog("starter_start_pluto(): pluto already started...");
- return -1;
- }
- else
- {
- unlink(PLUTO_CTL_FILE);
- _stop_requested = 0;
+ arg[argc++] = "--crlcheckinterval";
+ snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
+ arg[argc++] = buf1;
+ }
+ if (cfg->setup.cachecrls)
+ {
+ arg[argc++] = "--cachecrls";
+ }
+ if (cfg->setup.strictcrlpolicy)
+ {
+ arg[argc++] = "--strictcrlpolicy";
+ }
+ if (cfg->setup.nocrsend)
+ {
+ arg[argc++] = "--nocrsend";
+ }
+ if (cfg->setup.nat_traversal)
+ {
+ arg[argc++] = "--nat_traversal";
+ }
+ if (cfg->setup.force_keepalive)
+ {
+ arg[argc++] = "--force_keepalive";
+ }
+ if (cfg->setup.keep_alive)
+ {
+ static char buf2[15];
- if (cfg->setup.prepluto)
- ignore_result(system(cfg->setup.prepluto));
+ arg[argc++] = "--keep_alive";
+ snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
+ arg[argc++] = buf2;
+ }
+ if (cfg->setup.virtual_private)
+ {
+ arg[argc++] = "--virtual_private";
+ arg[argc++] = cfg->setup.virtual_private;
+ }
+ if (cfg->setup.pkcs11module)
+ {
+ arg[argc++] = "--pkcs11module";
+ arg[argc++] = cfg->setup.pkcs11module;
+ }
+ if (cfg->setup.pkcs11initargs)
+ {
+ arg[argc++] = "--pkcs11initargs";
+ arg[argc++] = cfg->setup.pkcs11initargs;
+ }
+ if (cfg->setup.pkcs11keepstate)
+ {
+ arg[argc++] = "--pkcs11keepstate";
+ }
+ if (cfg->setup.pkcs11proxy)
+ {
+ arg[argc++] = "--pkcs11proxy";
+ }
- pid = fork();
- switch (pid)
+ if (_pluto_pid)
+ {
+ plog("starter_start_pluto(): pluto already started...");
+ return -1;
+ }
+ else
{
- case -1:
- plog("can't fork(): %s", strerror(errno));
- return -1;
- case 0:
- /* child */
- if (cfg->setup.plutostderrlog)
- {
- int f = creat(cfg->setup.plutostderrlog, 00644);
+ unlink(PLUTO_CTL_FILE);
+ _stop_requested = 0;
- /* redirect stderr to file */
- if (f < 0)
- {
- plog("couldn't open stderr redirection file '%s'",
- cfg->setup.plutostderrlog);
- }
- else
- {
- dup2(f, 2);
- }
- }
- setsid();
- sigprocmask(SIG_SETMASK, 0, NULL);
- execv(arg[0], arg);
- plog("can't execv(%s,...): %s", arg[0], strerror(errno));
- exit(1);
- default:
- /* father */
- _pluto_pid = pid;
- for (i = 0; i < 500 && _pluto_pid; i++)
- {
- /* wait for pluto for a maximum of 500 x 20 ms = 10 s */
- usleep(20000);
- if (stat(PLUTO_CTL_FILE, &stb) == 0)
- {
- plog("pluto (%d) started after %d ms", _pluto_pid, 20*(i+1));
- if (cfg->setup.postpluto)
- {
- ignore_result(system(cfg->setup.postpluto));
- }
- return 0;
- }
- }
- if (_pluto_pid)
- {
- /* If pluto is started but with no ctl file, stop it */
- plog("pluto too long to start... - kill kill");
- for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
+ if (cfg->setup.prepluto)
+ ignore_result(system(cfg->setup.prepluto));
+
+ pid = fork();
+ switch (pid)
{
- if (i < 10)
- {
- kill(pid, SIGTERM);
- }
- else
- {
- kill(pid, SIGKILL);
- }
- usleep(20000); /* sleep for 20 ms */
+ case -1:
+ plog("can't fork(): %s", strerror(errno));
+ return -1;
+ case 0:
+ /* child */
+ if (cfg->setup.plutostderrlog)
+ {
+ int f = creat(cfg->setup.plutostderrlog, 00644);
+
+ /* redirect stderr to file */
+ if (f < 0)
+ {
+ plog("couldn't open stderr redirection file '%s'",
+ cfg->setup.plutostderrlog);
+ }
+ else
+ {
+ dup2(f, 2);
+ }
+ }
+ setsid();
+ sigprocmask(SIG_SETMASK, 0, NULL);
+ /* disable glibc's malloc checker, conflicts with leak detective */
+ setenv("MALLOC_CHECK_", "0", 1);
+ execv(arg[0], arg);
+ plog("can't execv(%s,...): %s", arg[0], strerror(errno));
+ exit(1);
+ default:
+ /* father */
+ _pluto_pid = pid;
+ for (i = 0; i < 500 && _pluto_pid; i++)
+ {
+ /* wait for pluto for a maximum of 500 x 20 ms = 10 s */
+ usleep(20000);
+ if (stat(PLUTO_CTL_FILE, &stb) == 0)
+ {
+ plog("pluto (%d) started after %d ms", _pluto_pid, 20*(i+1));
+ if (cfg->setup.postpluto)
+ {
+ ignore_result(system(cfg->setup.postpluto));
+ }
+ return 0;
+ }
+ }
+ if (_pluto_pid)
+ {
+ /* If pluto is started but with no ctl file, stop it */
+ plog("pluto too long to start... - kill kill");
+ for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
+ {
+ if (i < 10)
+ {
+ kill(pid, SIGTERM);
+ }
+ else
+ {
+ kill(pid, SIGKILL);
+ }
+ usleep(20000); /* sleep for 20 ms */
+ }
+ }
+ else
+ {
+ plog("pluto refused to be started");
+ }
+ return -1;
}
- }
- else
- {
- plog("pluto refused to be started");
- }
- return -1;
}
- }
- return -1;
+ return -1;
}
diff --git a/src/starter/invokepluto.h b/src/starter/invokepluto.h
index 589a036ee..b0c89b1f1 100644
--- a/src/starter/invokepluto.h
+++ b/src/starter/invokepluto.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: invokepluto.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_PLUTO_H_
@@ -22,7 +20,7 @@
extern void starter_pluto_sigchild (pid_t pid);
extern pid_t starter_pluto_pid (void);
extern int starter_stop_pluto (void);
-extern int starter_start_pluto (struct starter_config *cfg, bool debug);
+extern int starter_start_pluto (struct starter_config *cfg, bool no_fork, bool attach_gdb);
#endif /* _STARTER_PLUTO_H_ */
diff --git a/src/starter/ipsec.conf.5 b/src/starter/ipsec.conf.5
index 565f15c66..31e676324 100644
--- a/src/starter/ipsec.conf.5
+++ b/src/starter/ipsec.conf.5
@@ -1,5 +1,4 @@
.TH IPSEC.CONF 5 "27 Jun 2007"
-.\" RCSID $Id: ipsec.conf.5 5002 2009-03-24 15:02:12Z martin $
.SH NAME
ipsec.conf \- IPsec configuration and connections
.SH DESCRIPTION
@@ -239,27 +238,27 @@ acceptable values are
.B secret
or
.B psk
-for shared secrets,
+for pre-shared secrets,
+.B pubkey
+(the default) for public key signatures as well as the synonyms
.B rsasig
-for RSA digital signatures (the default),
-.B secret|rsasig
-for either, and
+for RSA digital signatures and
+.B ecdsasig
+for Elliptic Curve DSA signatures.
.B never
-if negotiation is never to be attempted or accepted (useful for shunt-only conns).
-Digital signatures are superior in every way to shared secrets. In IKEv2, the
-two ends must not agree on this parameter, it is relevant for the
-outbound authentication method only.
+can be used if negotiation is never to be attempted or accepted (useful for
+shunt-only conns).
+Digital signatures are superior in every way to shared secrets.
IKEv1 additionally supports the values
.B xauthpsk
and
.B xauthrsasig
that will enable eXtended AUTHentication (XAUTH) in addition to IKEv1 main mode
based on shared secrets or digital RSA signatures, respectively.
-IKEv2 additionally supports the value
-.B eap,
-which indicates an initiator to request EAP authentication. The EAP method to
-use is selected by the server (see
-.B eap).
+This parameter is deprecated for IKEv2 connections, as two peers do not need
+to agree on an authentication method. Use the
+.B leftauth
+parameter instead to define authentication methods in IKEv2.
.TP
.B auto
what operation, if any, should be done automatically at IPsec startup;
@@ -350,25 +349,9 @@ in case of inactivity. This only applies to IKEv1, in IKEv2 the default
retransmission timeout applies, as every exchange is used to detect dead peers.
.TP
.B eap
-defines the EAP type to propose as server if the client has
-.B authby=eap
-selected. Acceptable values are
-.B aka
-for EAP-AKA,
-.B sim
-for EAP-SIM,
-.B gtc
-for EAP-GTC,
-.B md5
-for EAP-MD5, and
-.B mschapv2
-for EAP-MS-CHAPv2.
-Additionally, IANA assigned EAP method numbers are accepted, or a definition
-in the form
-.B eap=type-vendor
-(e.g.
-.B eap=7-12345
-) can be used to specify vendor specific EAP types.
+defines the EAP type to propose as server if the client requests EAP
+authentication. This parameter is deprecated in the favour of
+.B leftauth.
To forward EAP authentication to a RADIUS server using the EAP-RADIUS plugin,
set
@@ -509,11 +492,46 @@ and
.B no
(the default).
.TP
+.B leftauth
+Authentication method to use (local) or require (remote) in this connection.
+This parameter is supported in IKEv2 only. Acceptable values are
+.B pubkey
+for public key authentication (RSA/ECDSA),
+.B psk
+for pre-shared key authentication and
+.B eap
+to (require the) use of the Extensible Authentication Protocol. In the case
+of
+.B eap,
+an optional EAP method can be appended. Currently defined methods are
+.B eap-aka, eap-sim, eap-gtc, eap-md5
+and
+.B eap-mschapv2.
+Alternatively, IANA assigned EAP method numbers are accepted. Vendor specific
+EAP methods are defined in the form
+.B eap-type-vendor
+(e.g.
+.B eap-7-12345
+).
+.TP
+.B leftauth2
+Same as
+.B leftauth,
+but defines an additional authentication exchange. IKEv2 supports multiple
+authentication rounds using "Multiple Authentication Exchanges" defined
+in RFC4739. This allows, for example, separated authentication
+of host and user (IKEv2 only).
+.TP
.B leftca
the distinguished name of a certificate authority which is required to
lie in the trust path going from the left participant's certificate up
to the root certification authority.
.TP
+.B leftca2
+Same as
+.B leftca,
+but for the second authentication round (IKEv2 only).
+.TP
.B leftcert
the path to the left participant's X.509 certificate. The file can be coded either in
PEM or DER format. OpenPGP certificates are supported as well.
@@ -529,6 +547,11 @@ The left participant's ID can be overriden by specifying a
.B leftid
value which must be certified by the certificate, though.
.TP
+.B leftcert2
+Same as
+.B leftcert,
+but for the second authentication round (IKEv2 only).
+.TP
.B leftfirewall
whether the left participant is doing forwarding-firewalling
(including masquerading) using iptables for traffic from \fIleftsubnet\fR,
@@ -594,6 +617,11 @@ or a fully-qualified domain name preceded by
.B @
(which is used as a literal string and not resolved).
.TP
+.B leftid2
+identity to use for a second authentication for the left participant
+(IKEv2 only); defaults to
+.BR leftid .
+.TP
.B leftnexthop
this parameter is not needed any more because the NETKEY IPsec stack does
not require explicit routing entries for the traffic to be tunneled.
diff --git a/src/starter/keywords.c b/src/starter/keywords.c
index e51780dc1..3ca7a92f6 100644
--- a/src/starter/keywords.c
+++ b/src/starter/keywords.c
@@ -1,6 +1,6 @@
/* C code produced by gperf version 3.0.3 */
-/* Command-line: /usr/bin/gperf -C -G -t */
-/* Computed positions: -k'1-2,$' */
+/* Command-line: /usr/bin/gperf -m 10 -C -G -D -t */
+/* Computed positions: -k'1-2,6,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -43,8 +43,6 @@ error "gperf generated tables don't work with this execution character set. Plea
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: keywords.txt 4612 2008-11-11 06:37:37Z andreas $
*/
#include <string.h>
@@ -56,12 +54,12 @@ struct kw_entry {
kw_token_t token;
};
-#define TOTAL_KEYWORDS 102
+#define TOTAL_KEYWORDS 112
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
-#define MIN_HASH_VALUE 6
-#define MAX_HASH_VALUE 248
-/* maximum key range = 243, duplicates = 0 */
+#define MIN_HASH_VALUE 13
+#define MAX_HASH_VALUE 200
+/* maximum key range = 188, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -77,198 +75,192 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 25,
- 10, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 110, 249, 0,
- 100, 5, 75, 65, 90, 0, 249, 60, 10, 15,
- 80, 60, 15, 249, 0, 50, 35, 15, 30, 249,
- 0, 75, 0, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, 249, 249
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 3,
+ 42, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 1, 201, 9, 201, 5,
+ 39, 1, 64, 47, 62, 1, 201, 88, 5, 83,
+ 39, 30, 21, 201, 1, 10, 6, 44, 14, 201,
+ 4, 54, 4, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
+ 201, 201, 201, 201, 201, 201
};
- return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[5]];
+ /*FALLTHROUGH*/
+ case 5:
+ case 4:
+ case 3:
+ case 2:
+ hval += asso_values[(unsigned char)str[1]];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
}
static const struct kw_entry wordlist[] =
{
- {""}, {""}, {""}, {""}, {""}, {""},
+ {"right", KW_RIGHT},
{"crluri", KW_CRLURI},
- {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"rekeyfuzz", KW_REKEYFUZZ},
- {""}, {""},
- {"crluri2", KW_CRLURI2},
- {""}, {""}, {""},
- {"certuribase", KW_CERTURIBASE},
- {""},
- {"rightfirewall", KW_RIGHTFIREWALL},
- {""},
- {"rightnatip", KW_RIGHTNATIP},
- {"crlcheckinterval", KW_CRLCHECKINTERVAL},
- {"rightnexthop", KW_RIGHTNEXTHOP},
- {"rightsourceip", KW_RIGHTSOURCEIP},
- {""}, {""}, {""},
+ {"left", KW_LEFT},
{"crluri1", KW_CRLURI},
- {""}, {""}, {""}, {""},
- {"leftfirewall", KW_LEFTFIREWALL},
- {""},
- {"leftnatip", KW_LEFTNATIP},
- {"right", KW_RIGHT},
- {"leftnexthop", KW_LEFTNEXTHOP},
- {"leftsourceip", KW_LEFTSOURCEIP},
- {""},
+ {"certuribase", KW_CERTURIBASE},
+ {"leftcert", KW_LEFTCERT,},
{"rightcert", KW_RIGHTCERT},
- {""},
+ {"rightca", KW_RIGHTCA},
+ {"leftfirewall", KW_LEFTFIREWALL},
+ {"leftsendcert", KW_LEFTSENDCERT},
+ {"leftprotoport", KW_LEFTPROTOPORT},
+ {"leftgroups", KW_LEFTGROUPS},
+ {"crlcheckinterval", KW_CRLCHECKINTERVAL},
{"rightsubnet", KW_RIGHTSUBNET},
- {""},
+ {"leftca", KW_LEFTCA},
{"rightsendcert", KW_RIGHTSENDCERT},
- {"rightprotoport", KW_RIGHTPROTOPORT},
+ {"cacert", KW_CACERT},
+ {"eap", KW_EAP},
+ {"esp", KW_ESP},
+ {"cachecrls", KW_CACHECRLS},
+ {"leftnexthop", KW_LEFTNEXTHOP},
{"virtual_private", KW_VIRTUAL_PRIVATE},
- {""}, {""}, {""},
- {"left", KW_LEFT},
- {""}, {""}, {""},
- {"leftcert", KW_LEFTCERT,},
- {""},
- {"leftsubnet", KW_LEFTSUBNET},
- {"rightgroups", KW_RIGHTGROUPS},
- {"leftsendcert", KW_LEFTSENDCERT},
- {"leftprotoport", KW_LEFTPROTOPORT},
- {""},
- {"righthostaccess", KW_RIGHTHOSTACCESS},
- {""},
+ {"rightprotoport", KW_RIGHTPROTOPORT},
{"ocspuri", KW_OCSPURI},
- {"ike", KW_IKE},
- {""},
+ {"leftnatip", KW_LEFTNATIP},
+ {"rightsourceip", KW_RIGHTSOURCEIP},
+ {"ocspuri1", KW_OCSPURI},
+ {"also", KW_ALSO},
+ {"rightid", KW_RIGHTID},
{"plutostart", KW_PLUTOSTART},
- {""}, {""},
- {"esp", KW_ESP},
- {""},
- {"leftgroups", KW_LEFTGROUPS},
- {"ikelifetime", KW_IKELIFETIME},
- {"keylife", KW_KEYLIFE},
- {"ocspuri2", KW_OCSPURI2},
+ {"rightid2", KW_RIGHTID2},
+ {"compress", KW_COMPRESS},
+ {"packetdefault", KW_PACKETDEFAULT},
+ {"crluri2", KW_CRLURI2},
+ {"rightca2", KW_RIGHTCA2},
+ {"leftcert2", KW_LEFTCERT2,},
+ {"rightcert2", KW_RIGHTCERT2},
{"lefthostaccess", KW_LEFTHOSTACCESS},
- {"keep_alive", KW_KEEP_ALIVE},
- {"keyexchange", KW_KEYEXCHANGE},
- {""},
- {"prepluto", KW_PREPLUTO},
- {""},
{"rekey", KW_REKEY},
- {"mobike", KW_MOBIKE},
- {""},
- {"rightallowany", KW_RIGHTALLOWANY},
- {"rightrsasigkey", KW_RIGHTRSASIGKEY},
- {""},
- {"rightupdown", KW_RIGHTUPDOWN},
- {"pkcs11module", KW_PKCS11MODULE},
- {"ocspuri1", KW_OCSPURI},
- {""},
- {"pkcs11keepstate", KW_PKCS11KEEPSTATE},
- {"rekeymargin", KW_REKEYMARGIN},
+ {"ldapbase", KW_LDAPBASE},
+ {"rightauth2", KW_RIGHTAUTH2},
+ {"leftca2", KW_LEFTCA2},
+ {"type", KW_TYPE},
+ {"leftsubnet", KW_LEFTSUBNET},
+ {"nat_traversal", KW_NAT_TRAVERSAL},
{"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
- {"fragicmp", KW_FRAGICMP},
- {""},
- {"plutodebug", KW_PLUTODEBUG},
- {"reauth", KW_REAUTH},
+ {"leftsourceip", KW_LEFTSOURCEIP},
+ {"rightgroups", KW_RIGHTGROUPS},
+ {"rightrsasigkey", KW_RIGHTRSASIGKEY},
+ {"rightnatip", KW_RIGHTNATIP},
+ {"rightnexthop", KW_RIGHTNEXTHOP},
+ {"leftupdown", KW_LEFTUPDOWN},
{"leftallowany", KW_LEFTALLOWANY},
+ {"rightallowany", KW_RIGHTALLOWANY},
+ {"rekeyfuzz", KW_REKEYFUZZ},
+ {"xauth", KW_XAUTH},
+ {"rightauth", KW_RIGHTAUTH},
{"leftrsasigkey", KW_LEFTRSASIGKEY},
- {"plutostderrlog", KW_PLUTOSTDERRLOG},
- {"leftupdown", KW_LEFTUPDOWN},
- {"mediated_by", KW_MEDIATED_BY},
- {"rightid", KW_RIGHTID},
- {""},
- {"mediation", KW_MEDIATION},
- {""},
- {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
- {""},
- {"pfsgroup", KW_PFSGROUP},
- {""}, {""},
- {"overridemtu", KW_OVERRIDEMTU},
- {"rightca", KW_RIGHTCA},
- {"compress", KW_COMPRESS},
- {"type", KW_TYPE},
- {""},
+ {"rightfirewall", KW_RIGHTFIREWALL},
+ {"ocspuri2", KW_OCSPURI2},
+ {"auto", KW_AUTO},
+ {"ldaphost", KW_LDAPHOST},
+ {"righthostaccess", KW_RIGHTHOSTACCESS},
{"leftid", KW_LEFTID},
+ {"strictcrlpolicy", KW_STRICTCRLPOLICY},
{"dumpdir", KW_DUMPDIR},
- {"ldapbase", KW_LDAPBASE},
- {""}, {""},
- {"keyingtries", KW_KEYINGTRIES},
- {""}, {""},
- {"me_peerid", KW_ME_PEERID},
- {""},
- {"leftca", KW_LEFTCA},
- {""},
- {"eap", KW_EAP},
- {""}, {""},
- {"charonstart", KW_CHARONSTART},
- {""}, {""},
- {"pkcs11initargs", KW_PKCS11INITARGS},
- {"interfaces", KW_INTERFACES},
- {""}, {""},
- {"pfs", KW_PFS},
+ {"ike", KW_IKE},
+ {"leftid2", KW_LEFTID2},
{"postpluto", KW_POSTPLUTO},
- {"klipsdebug", KW_KLIPSDEBUG},
- {""},
- {"hidetos", KW_HIDETOS},
- {""}, {""},
- {"modeconfig", KW_MODECONFIG},
- {"cacert", KW_CACERT},
- {""},
- {"ldaphost", KW_LDAPHOST},
+ {"rightupdown", KW_RIGHTUPDOWN},
+ {"plutostderrlog", KW_PLUTOSTDERRLOG},
+ {"pfs", KW_PFS},
+ {"fragicmp", KW_FRAGICMP},
+ {"overridemtu", KW_OVERRIDEMTU},
+ {"leftauth2", KW_LEFTAUTH2},
{"uniqueids", KW_UNIQUEIDS},
+ {"prepluto", KW_PREPLUTO},
+ {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
+ {"keyexchange", KW_KEYEXCHANGE},
+ {"keep_alive", KW_KEEP_ALIVE},
+ {"hidetos", KW_HIDETOS},
{"force_keepalive", KW_FORCE_KEEPALIVE},
- {""}, {""}, {""}, {""},
- {"dpdtimeout", KW_DPDTIMEOUT},
- {"pkcs11proxy", KW_PKCS11PROXY},
- {""}, {""}, {""}, {""},
- {"charondebug", KW_CHARONDEBUG},
- {""},
{"installpolicy", KW_INSTALLPOLICY},
- {"cachecrls", KW_CACHECRLS},
- {""}, {""}, {""},
- {"packetdefault", KW_PACKETDEFAULT},
- {""},
- {"strictcrlpolicy", KW_STRICTCRLPOLICY},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {"also", KW_ALSO},
- {""}, {""}, {""}, {""},
- {"auto", KW_AUTO},
- {""}, {""}, {""}, {""}, {""}, {""},
+ {"dpdaction", KW_DPDACTION},
+ {"eap_identity", KW_EAP_IDENTITY},
{"forceencaps", KW_FORCEENCAPS},
- {""},
+ {"nocrsend", KW_NOCRSEND},
+ {"auth", KW_AUTH},
+ {"leftauth", KW_LEFTAUTH},
+ {"mobike", KW_MOBIKE},
+ {"plutodebug", KW_PLUTODEBUG},
+ {"charonstart", KW_CHARONSTART},
+ {"interfaces", KW_INTERFACES},
+ {"pkcs11module", KW_PKCS11MODULE},
{"dpddelay", KW_DPDDELAY},
- {""}, {""}, {""},
- {"eap_identity", KW_EAP_IDENTITY},
- {""},
- {"dpdaction", KW_DPDACTION},
- {"xauth", KW_XAUTH},
+ {"pkcs11keepstate", KW_PKCS11KEEPSTATE},
+ {"reauth", KW_REAUTH},
+ {"me_peerid", KW_ME_PEERID},
+ {"rekeymargin", KW_REKEYMARGIN},
+ {"pkcs11initargs", KW_PKCS11INITARGS},
+ {"mediation", KW_MEDIATION},
+ {"pfsgroup", KW_PFSGROUP},
+ {"mediated_by", KW_MEDIATED_BY},
+ {"keyingtries", KW_KEYINGTRIES},
+ {"dpdtimeout", KW_DPDTIMEOUT},
+ {"keylife", KW_KEYLIFE},
+ {"charondebug", KW_CHARONDEBUG},
+ {"ikelifetime", KW_IKELIFETIME},
{"authby", KW_AUTHBY},
- {""}, {""}, {""}, {""}, {""}, {""},
- {"nat_traversal", KW_NAT_TRAVERSAL},
- {""}, {""}, {""}, {""}, {""},
- {"auth", KW_AUTH},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""},
- {"nocrsend", KW_NOCRSEND}
+ {"pkcs11proxy", KW_PKCS11PROXY},
+ {"klipsdebug", KW_KLIPSDEBUG},
+ {"modeconfig", KW_MODECONFIG}
+ };
+
+static const short lookup[] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 0, 1, -1, 2, 3, -1, 4,
+ -1, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, -1, 17, 18, -1, -1, 19, 20,
+ 21, -1, -1, 22, 23, 24, 25, 26, 27, 28,
+ -1, -1, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, -1, 50, -1, 51, 52, 53, 54,
+ 55, -1, 56, 57, 58, -1, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, -1, 75, 76, 77, 78, -1, -1, 79,
+ 80, 81, 82, -1, 83, 84, 85, 86, -1, 87,
+ 88, 89, 90, 91, 92, 93, -1, 94, 95, -1,
+ -1, -1, 96, 97, -1, 98, 99, -1, 100, -1,
+ -1, -1, -1, -1, 101, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 102, -1, 103, -1, 104,
+ -1, 105, -1, -1, 106, 107, -1, 108, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 109, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 110,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 111
};
#ifdef __GNUC__
@@ -288,10 +280,15 @@ in_word_set (str, len)
if (key <= MAX_HASH_VALUE && key >= 0)
{
- register const char *s = wordlist[key].name;
+ register int index = lookup[key];
+
+ if (index >= 0)
+ {
+ register const char *s = wordlist[index].name;
- if (*str == *s && !strcmp (str + 1, s + 1))
- return &wordlist[key];
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return &wordlist[index];
+ }
}
}
return 0;
diff --git a/src/starter/keywords.h b/src/starter/keywords.h
index 756c33075..ae9a6d15f 100644
--- a/src/starter/keywords.h
+++ b/src/starter/keywords.h
@@ -11,177 +11,185 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: keywords.h 4612 2008-11-11 06:37:37Z andreas $
*/
#ifndef _KEYWORDS_H_
#define _KEYWORDS_H_
typedef enum {
- /* config setup keywords */
- KW_INTERFACES,
- KW_DUMPDIR,
- KW_CHARONSTART,
- KW_PLUTOSTART,
-
- /* pluto/charon keywords */
- KW_PLUTODEBUG,
- KW_CHARONDEBUG,
- KW_PREPLUTO,
- KW_POSTPLUTO,
- KW_PLUTOSTDERRLOG,
- KW_UNIQUEIDS,
- KW_OVERRIDEMTU,
- KW_CRLCHECKINTERVAL,
- KW_CACHECRLS,
- KW_STRICTCRLPOLICY,
- KW_NOCRSEND,
- KW_NAT_TRAVERSAL,
- KW_KEEP_ALIVE,
- KW_FORCE_KEEPALIVE,
- KW_VIRTUAL_PRIVATE,
- KW_PKCS11MODULE,
- KW_PKCS11INITARGS,
- KW_PKCS11KEEPSTATE,
- KW_PKCS11PROXY,
-
-#define KW_PLUTO_FIRST KW_PLUTODEBUG
-#define KW_PLUTO_LAST KW_PKCS11PROXY
-
- /* KLIPS keywords */
- KW_KLIPSDEBUG,
- KW_FRAGICMP,
- KW_PACKETDEFAULT,
- KW_HIDETOS,
-
-#define KW_KLIPS_FIRST KW_KLIPSDEBUG
-#define KW_KLIPS_LAST KW_HIDETOS
-
-#define KW_SETUP_FIRST KW_INTERFACES
-#define KW_SETUP_LAST KW_HIDETOS
-
- /* conn section keywords */
- KW_CONN_NAME,
- KW_CONN_SETUP,
- KW_KEYEXCHANGE,
- KW_TYPE,
- KW_PFS,
- KW_COMPRESS,
- KW_INSTALLPOLICY,
- KW_AUTH,
- KW_AUTHBY,
- KW_EAP,
- KW_EAP_IDENTITY,
- KW_MOBIKE,
- KW_FORCEENCAPS,
- KW_IKELIFETIME,
- KW_KEYLIFE,
- KW_REKEYMARGIN,
- KW_KEYINGTRIES,
- KW_REKEYFUZZ,
- KW_REKEY,
- KW_REAUTH,
- KW_IKE,
- KW_ESP,
- KW_PFSGROUP,
- KW_DPDDELAY,
- KW_DPDTIMEOUT,
- KW_DPDACTION,
- KW_MODECONFIG,
- KW_XAUTH,
- KW_MEDIATION,
- KW_MEDIATED_BY,
- KW_ME_PEERID,
-
-#define KW_CONN_FIRST KW_CONN_SETUP
-#define KW_CONN_LAST KW_ME_PEERID
+ /* config setup keywords */
+ KW_INTERFACES,
+ KW_DUMPDIR,
+ KW_CHARONSTART,
+ KW_PLUTOSTART,
+
+ /* pluto/charon keywords */
+ KW_PLUTODEBUG,
+ KW_CHARONDEBUG,
+ KW_PREPLUTO,
+ KW_POSTPLUTO,
+ KW_PLUTOSTDERRLOG,
+ KW_UNIQUEIDS,
+ KW_OVERRIDEMTU,
+ KW_CRLCHECKINTERVAL,
+ KW_CACHECRLS,
+ KW_STRICTCRLPOLICY,
+ KW_NOCRSEND,
+ KW_NAT_TRAVERSAL,
+ KW_KEEP_ALIVE,
+ KW_FORCE_KEEPALIVE,
+ KW_VIRTUAL_PRIVATE,
+ KW_PKCS11MODULE,
+ KW_PKCS11INITARGS,
+ KW_PKCS11KEEPSTATE,
+ KW_PKCS11PROXY,
+
+#define KW_PLUTO_FIRST KW_PLUTODEBUG
+#define KW_PLUTO_LAST KW_PKCS11PROXY
+
+ /* KLIPS keywords */
+ KW_KLIPSDEBUG,
+ KW_FRAGICMP,
+ KW_PACKETDEFAULT,
+ KW_HIDETOS,
+
+#define KW_KLIPS_FIRST KW_KLIPSDEBUG
+#define KW_KLIPS_LAST KW_HIDETOS
+
+#define KW_SETUP_FIRST KW_INTERFACES
+#define KW_SETUP_LAST KW_HIDETOS
+
+ /* conn section keywords */
+ KW_CONN_NAME,
+ KW_CONN_SETUP,
+ KW_KEYEXCHANGE,
+ KW_TYPE,
+ KW_PFS,
+ KW_COMPRESS,
+ KW_INSTALLPOLICY,
+ KW_AUTH,
+ KW_AUTHBY,
+ KW_EAP,
+ KW_EAP_IDENTITY,
+ KW_MOBIKE,
+ KW_FORCEENCAPS,
+ KW_IKELIFETIME,
+ KW_KEYLIFE,
+ KW_REKEYMARGIN,
+ KW_KEYINGTRIES,
+ KW_REKEYFUZZ,
+ KW_REKEY,
+ KW_REAUTH,
+ KW_IKE,
+ KW_ESP,
+ KW_PFSGROUP,
+ KW_DPDDELAY,
+ KW_DPDTIMEOUT,
+ KW_DPDACTION,
+ KW_MODECONFIG,
+ KW_XAUTH,
+ KW_MEDIATION,
+ KW_MEDIATED_BY,
+ KW_ME_PEERID,
+
+#define KW_CONN_FIRST KW_CONN_SETUP
+#define KW_CONN_LAST KW_ME_PEERID
/* ca section keywords */
- KW_CA_NAME,
- KW_CA_SETUP,
- KW_CACERT,
- KW_LDAPHOST,
- KW_LDAPBASE,
- KW_CRLURI,
- KW_CRLURI2,
- KW_OCSPURI,
- KW_OCSPURI2,
- KW_CERTURIBASE,
-
-#define KW_CA_FIRST KW_CA_SETUP
-#define KW_CA_LAST KW_CERTURIBASE
+ KW_CA_NAME,
+ KW_CA_SETUP,
+ KW_CACERT,
+ KW_LDAPHOST,
+ KW_LDAPBASE,
+ KW_CRLURI,
+ KW_CRLURI2,
+ KW_OCSPURI,
+ KW_OCSPURI2,
+ KW_CERTURIBASE,
+
+#define KW_CA_FIRST KW_CA_SETUP
+#define KW_CA_LAST KW_CERTURIBASE
/* end keywords */
- KW_HOST,
- KW_NEXTHOP,
- KW_SUBNET,
- KW_SUBNETWITHIN,
- KW_PROTOPORT,
- KW_SOURCEIP,
- KW_NATIP,
- KW_FIREWALL,
- KW_HOSTACCESS,
- KW_ALLOWANY,
- KW_UPDOWN,
- KW_ID,
- KW_RSASIGKEY,
- KW_CERT,
- KW_SENDCERT,
- KW_CA,
- KW_GROUPS,
- KW_IFACE,
-
-#define KW_END_FIRST KW_HOST
-#define KW_END_LAST KW_IFACE
+ KW_HOST,
+ KW_NEXTHOP,
+ KW_SUBNET,
+ KW_SUBNETWITHIN,
+ KW_PROTOPORT,
+ KW_SOURCEIP,
+ KW_NATIP,
+ KW_FIREWALL,
+ KW_HOSTACCESS,
+ KW_ALLOWANY,
+ KW_UPDOWN,
+ KW_ID,
+ KW_RSASIGKEY,
+ KW_CERT,
+ KW_SENDCERT,
+ KW_CA,
+ KW_GROUPS,
+ KW_IFACE,
+
+#define KW_END_FIRST KW_HOST
+#define KW_END_LAST KW_IFACE
/* left end keywords */
- KW_LEFT,
- KW_LEFTNEXTHOP,
- KW_LEFTSUBNET,
- KW_LEFTSUBNETWITHIN,
- KW_LEFTPROTOPORT,
- KW_LEFTSOURCEIP,
- KW_LEFTNATIP,
- KW_LEFTFIREWALL,
- KW_LEFTHOSTACCESS,
- KW_LEFTALLOWANY,
- KW_LEFTUPDOWN,
- KW_LEFTID,
- KW_LEFTRSASIGKEY,
- KW_LEFTCERT,
- KW_LEFTSENDCERT,
- KW_LEFTCA,
- KW_LEFTGROUPS,
-
-#define KW_LEFT_FIRST KW_LEFT
-#define KW_LEFT_LAST KW_LEFTGROUPS
+ KW_LEFT,
+ KW_LEFTNEXTHOP,
+ KW_LEFTSUBNET,
+ KW_LEFTSUBNETWITHIN,
+ KW_LEFTPROTOPORT,
+ KW_LEFTSOURCEIP,
+ KW_LEFTNATIP,
+ KW_LEFTFIREWALL,
+ KW_LEFTHOSTACCESS,
+ KW_LEFTALLOWANY,
+ KW_LEFTUPDOWN,
+ KW_LEFTAUTH,
+ KW_LEFTAUTH2,
+ KW_LEFTID,
+ KW_LEFTID2,
+ KW_LEFTRSASIGKEY,
+ KW_LEFTCERT,
+ KW_LEFTCERT2,
+ KW_LEFTSENDCERT,
+ KW_LEFTCA,
+ KW_LEFTCA2,
+ KW_LEFTGROUPS,
+
+#define KW_LEFT_FIRST KW_LEFT
+#define KW_LEFT_LAST KW_LEFTGROUPS
/* right end keywords */
- KW_RIGHT,
- KW_RIGHTNEXTHOP,
- KW_RIGHTSUBNET,
- KW_RIGHTSUBNETWITHIN,
- KW_RIGHTPROTOPORT,
- KW_RIGHTSOURCEIP,
- KW_RIGHTNATIP,
- KW_RIGHTFIREWALL,
- KW_RIGHTHOSTACCESS,
- KW_RIGHTALLOWANY,
- KW_RIGHTUPDOWN,
- KW_RIGHTID,
- KW_RIGHTRSASIGKEY,
- KW_RIGHTCERT,
- KW_RIGHTSENDCERT,
- KW_RIGHTCA,
- KW_RIGHTGROUPS,
-
-#define KW_RIGHT_FIRST KW_RIGHT
-#define KW_RIGHT_LAST KW_RIGHTGROUPS
-
- /* general section keywords */
- KW_ALSO,
- KW_AUTO
+ KW_RIGHT,
+ KW_RIGHTNEXTHOP,
+ KW_RIGHTSUBNET,
+ KW_RIGHTSUBNETWITHIN,
+ KW_RIGHTPROTOPORT,
+ KW_RIGHTSOURCEIP,
+ KW_RIGHTNATIP,
+ KW_RIGHTFIREWALL,
+ KW_RIGHTHOSTACCESS,
+ KW_RIGHTALLOWANY,
+ KW_RIGHTUPDOWN,
+ KW_RIGHTAUTH,
+ KW_RIGHTAUTH2,
+ KW_RIGHTID,
+ KW_RIGHTID2,
+ KW_RIGHTRSASIGKEY,
+ KW_RIGHTCERT,
+ KW_RIGHTCERT2,
+ KW_RIGHTSENDCERT,
+ KW_RIGHTCA,
+ KW_RIGHTCA2,
+ KW_RIGHTGROUPS,
+
+#define KW_RIGHT_FIRST KW_RIGHT
+#define KW_RIGHT_LAST KW_RIGHTGROUPS
+
+ /* general section keywords */
+ KW_ALSO,
+ KW_AUTO
} kw_token_t;
diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt
index 8dfa03325..66c894850 100644
--- a/src/starter/keywords.txt
+++ b/src/starter/keywords.txt
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: keywords.txt 4612 2008-11-11 06:37:37Z andreas $
*/
#include <string.h>
@@ -104,10 +102,15 @@ lefthostaccess, KW_LEFTHOSTACCESS
leftallowany, KW_LEFTALLOWANY
leftupdown, KW_LEFTUPDOWN
leftid, KW_LEFTID
+leftid2, KW_LEFTID2
+leftauth, KW_LEFTAUTH
+leftauth2, KW_LEFTAUTH2
leftrsasigkey, KW_LEFTRSASIGKEY
leftcert, KW_LEFTCERT,
+leftcert2, KW_LEFTCERT2,
leftsendcert, KW_LEFTSENDCERT
leftca, KW_LEFTCA
+leftca2, KW_LEFTCA2
leftgroups, KW_LEFTGROUPS
right, KW_RIGHT
rightnexthop, KW_RIGHTNEXTHOP
@@ -121,10 +124,15 @@ righthostaccess, KW_RIGHTHOSTACCESS
rightallowany, KW_RIGHTALLOWANY
rightupdown, KW_RIGHTUPDOWN
rightid, KW_RIGHTID
+rightid2, KW_RIGHTID2
+rightauth, KW_RIGHTAUTH
+rightauth2, KW_RIGHTAUTH2
rightrsasigkey, KW_RIGHTRSASIGKEY
rightcert, KW_RIGHTCERT
+rightcert2, KW_RIGHTCERT2
rightsendcert, KW_RIGHTSENDCERT
rightca, KW_RIGHTCA
+rightca2, KW_RIGHTCA2
rightgroups, KW_RIGHTGROUPS
also, KW_ALSO
auto, KW_AUTO
diff --git a/src/starter/klips.c b/src/starter/klips.c
index 5c8164419..061dee50c 100644
--- a/src/starter/klips.c
+++ b/src/starter/klips.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: klips.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <sys/types.h>
@@ -29,54 +27,54 @@
bool
starter_klips_init(void)
{
- struct stat stb;
-
- if (stat(PROC_KLIPS, &stb) != 0)
- {
- /* ipsec module makes the pf_key proc interface visible */
- if (stat(PROC_MODULES, &stb) == 0)
- {
- ignore_result(system("modprobe -qv ipsec"));
- }
+ struct stat stb;
- /* now test again */
if (stat(PROC_KLIPS, &stb) != 0)
{
- DBG(DBG_CONTROL,
- DBG_log("kernel appears to lack the KLIPS IPsec stack")
- )
- return FALSE;
+ /* ipsec module makes the pf_key proc interface visible */
+ if (stat(PROC_MODULES, &stb) == 0)
+ {
+ ignore_result(system("modprobe -qv ipsec"));
+ }
+
+ /* now test again */
+ if (stat(PROC_KLIPS, &stb) != 0)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("kernel appears to lack the KLIPS IPsec stack")
+ )
+ return FALSE;
+ }
}
- }
-
- /* load crypto algorithm modules */
- ignore_result(system("modprobe -qv ipsec_aes"));
- ignore_result(system("modprobe -qv ipsec_blowfish"));
- ignore_result(system("modprobe -qv ipsec_sha2"));
+
+ /* load crypto algorithm modules */
+ ignore_result(system("modprobe -qv ipsec_aes"));
+ ignore_result(system("modprobe -qv ipsec_blowfish"));
+ ignore_result(system("modprobe -qv ipsec_sha2"));
- DBG(DBG_CONTROL,
- DBG_log("Found KLIPS IPsec stack")
- )
-
- return TRUE;
+ DBG(DBG_CONTROL,
+ DBG_log("Found KLIPS IPsec stack")
+ )
+
+ return TRUE;
}
void
starter_klips_cleanup(void)
{
- if (system("type eroute > /dev/null 2>&1") == 0)
- {
- ignore_result(system("spi --clear"));
- ignore_result(system("eroute --clear"));
- }
- else if (system("type setkey > /dev/null 2>&1") == 0)
- {
- ignore_result(system("setkey -F"));
- ignore_result(system("setkey -FP"));
- }
- else
- {
- plog("WARNING: cannot flush IPsec state/policy database");
- }
+ if (system("type eroute > /dev/null 2>&1") == 0)
+ {
+ ignore_result(system("spi --clear"));
+ ignore_result(system("eroute --clear"));
+ }
+ else if (system("type setkey > /dev/null 2>&1") == 0)
+ {
+ ignore_result(system("setkey -F"));
+ ignore_result(system("setkey -FP"));
+ }
+ else
+ {
+ plog("WARNING: cannot flush IPsec state/policy database");
+ }
}
diff --git a/src/starter/klips.h b/src/starter/klips.h
index 60055b4f1..e93348df1 100644
--- a/src/starter/klips.h
+++ b/src/starter/klips.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: klips.h 4618 2008-11-11 09:22:00Z tobias $
*/
#ifndef _STARTER_KLIPS_H_
diff --git a/src/starter/loglite.c b/src/starter/loglite.c
index 94d9b79bb..415cf931c 100644
--- a/src/starter/loglite.c
+++ b/src/starter/loglite.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: loglite.c 3267 2007-10-08 19:57:54Z andreas $
*/
#include <stdio.h>
@@ -23,7 +21,7 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
-#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
+#include <signal.h> /* used only if MSG_NOSIGNAL not defined */
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -36,118 +34,118 @@
#include <whack.h>
bool
- log_to_stderr = FALSE, /* should log go to stderr? */
- log_to_syslog = TRUE; /* should log go to syslog? */
+ log_to_stderr = FALSE, /* should log go to stderr? */
+ log_to_syslog = TRUE; /* should log go to syslog? */
void
init_log(const char *program)
{
- if (log_to_stderr)
- setbuf(stderr, NULL);
- if (log_to_syslog)
- openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
+ if (log_to_stderr)
+ setbuf(stderr, NULL);
+ if (log_to_syslog)
+ openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
}
void
close_log(void)
{
- if (log_to_syslog)
- closelog();
+ if (log_to_syslog)
+ closelog();
}
void
plog(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
}
void
loglog(int mess_no, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "%s\n", m);
- if (log_to_syslog)
- syslog(LOG_WARNING, "%s", m);
+ if (log_to_stderr)
+ fprintf(stderr, "%s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_WARNING, "%s", m);
}
void
log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ if (log_to_stderr)
+ fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
}
void
exit_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s\n", m);
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s", m);
- exit(1);
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s", m);
+ exit(1);
}
void
exit_log_errno_routine(int e, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
-
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
-
- if (log_to_stderr)
- fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
- if (log_to_syslog)
- syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
- exit(1);
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
+
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
+
+ if (log_to_stderr)
+ fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
+ if (log_to_syslog)
+ syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
+ exit(1);
}
void
whack_log(int mess_no, const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- fprintf(stderr, "%s\n", m);
+ fprintf(stderr, "%s\n", m);
}
/* Build up a diagnostic in a static buffer.
@@ -165,16 +163,16 @@ char diag_space[sizeof(diag_space)];
err_t
builddiag(const char *fmt, ...)
{
- static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
- char t[sizeof(diag_space)]; /* build result here first */
- va_list args;
-
- va_start(args, fmt);
- t[0] = '\0'; /* in case nothing terminates string */
- vsnprintf(t, sizeof(t), fmt, args);
- va_end(args);
- strcpy(diag_space, t);
- return diag_space;
+ static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
+ char t[sizeof(diag_space)]; /* build result here first */
+ va_list args;
+
+ va_start(args, fmt);
+ t[0] = '\0'; /* in case nothing terminates string */
+ vsnprintf(t, sizeof(t), fmt, args);
+ va_end(args);
+ strcpy(diag_space, t);
+ return diag_space;
}
/* Debugging message support */
@@ -184,29 +182,29 @@ builddiag(const char *fmt, ...)
void
switch_fail(int n, const char *file_str, unsigned long line_no)
{
- char buf[30];
+ char buf[30];
- snprintf(buf, sizeof(buf), "case %d unexpected", n);
- passert_fail(buf, file_str, line_no);
+ snprintf(buf, sizeof(buf), "case %d unexpected", n);
+ passert_fail(buf, file_str, line_no);
}
void
passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
- abort(); /* exiting correctly doesn't always work */
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ abort(); /* exiting correctly doesn't always work */
}
lset_t
- base_debugging = DBG_NONE, /* default to reporting nothing */
- cur_debugging = DBG_NONE;
+ base_debugging = DBG_NONE, /* default to reporting nothing */
+ cur_debugging = DBG_NONE;
void
pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
{
- /* we will get a possibly unplanned prefix. Hope it works */
- loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
+ /* we will get a possibly unplanned prefix. Hope it works */
+ loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
}
/* log a debugging message (prefixed by "| ") */
@@ -214,17 +212,17 @@ pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
void
DBG_log(const char *message, ...)
{
- va_list args;
- char m[LOG_WIDTH]; /* longer messages will be truncated */
+ va_list args;
+ char m[LOG_WIDTH]; /* longer messages will be truncated */
- va_start(args, message);
- vsnprintf(m, sizeof(m), message, args);
- va_end(args);
+ va_start(args, message);
+ vsnprintf(m, sizeof(m), message, args);
+ va_end(args);
- if (log_to_stderr)
- fprintf(stderr, "| %s\n", m);
- if (log_to_syslog)
- syslog(LOG_DEBUG, "| %s", m);
+ if (log_to_stderr)
+ fprintf(stderr, "| %s\n", m);
+ if (log_to_syslog)
+ syslog(LOG_DEBUG, "| %s", m);
}
/* dump raw bytes in hex to stderr (for lack of any better destination) */
@@ -232,62 +230,62 @@ DBG_log(const char *message, ...)
void
DBG_dump(const char *label, const void *p, size_t len)
{
-# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
-# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
- char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
- char *bp;
- const unsigned char *cp = p;
+# define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
+# define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
+ char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
+ char *bp;
+ const unsigned char *cp = p;
- bp = buf;
-
- if (label != NULL && label[0] != '\0')
- {
- /* Handle the label. Care must be taken to avoid buffer overrun. */
- size_t llen = strlen(label);
+ bp = buf;
- if (llen + 1 > sizeof(buf))
+ if (label != NULL && label[0] != '\0')
{
- DBG_log("%s", label);
+ /* Handle the label. Care must be taken to avoid buffer overrun. */
+ size_t llen = strlen(label);
+
+ if (llen + 1 > sizeof(buf))
+ {
+ DBG_log("%s", label);
+ }
+ else
+ {
+ strcpy(buf, label);
+ if (buf[llen-1] == '\n')
+ {
+ buf[llen-1] = '\0'; /* get rid of newline */
+ DBG_log("%s", buf);
+ }
+ else if (llen < DUMP_LABEL_WIDTH)
+ {
+ bp = buf + llen;
+ }
+ else
+ {
+ DBG_log("%s", buf);
+ }
+ }
}
- else
- {
- strcpy(buf, label);
- if (buf[llen-1] == '\n')
- {
- buf[llen-1] = '\0'; /* get rid of newline */
- DBG_log("%s", buf);
- }
- else if (llen < DUMP_LABEL_WIDTH)
- {
- bp = buf + llen;
- }
- else
- {
- DBG_log("%s", buf);
- }
- }
- }
- do {
- int i, j;
-
- for (i = 0; len!=0 && i!=4; i++)
- {
- *bp++ = ' ';
- for (j = 0; len!=0 && j!=4; len--, j++)
- {
- static const char hexdig[] = "0123456789abcdef";
-
- *bp++ = ' ';
- *bp++ = hexdig[(*cp >> 4) & 0xF];
- *bp++ = hexdig[*cp & 0xF];
- cp++;
- }
- }
- *bp = '\0';
- DBG_log("%s", buf);
- bp = buf;
- } while (len != 0);
+ do {
+ int i, j;
+
+ for (i = 0; len!=0 && i!=4; i++)
+ {
+ *bp++ = ' ';
+ for (j = 0; len!=0 && j!=4; len--, j++)
+ {
+ static const char hexdig[] = "0123456789abcdef";
+
+ *bp++ = ' ';
+ *bp++ = hexdig[(*cp >> 4) & 0xF];
+ *bp++ = hexdig[*cp & 0xF];
+ cp++;
+ }
+ }
+ *bp = '\0';
+ DBG_log("%s", buf);
+ bp = buf;
+ } while (len != 0);
# undef DUMP_LABEL_WIDTH
# undef DUMP_WIDTH
}
diff --git a/src/starter/netkey.c b/src/starter/netkey.c
index 1490abf29..e0449f0b2 100644
--- a/src/starter/netkey.c
+++ b/src/starter/netkey.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: netkey.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <sys/types.h>
@@ -29,57 +27,57 @@
bool
starter_netkey_init(void)
{
- struct stat stb;
+ struct stat stb;
- if (stat(PROC_NETKEY, &stb) != 0)
- {
- /* af_key module makes the netkey proc interface visible */
- if (stat(PROC_MODULES, &stb) == 0)
+ if (stat(PROC_NETKEY, &stb) != 0)
{
- ignore_result(system("modprobe -qv af_key"));
+ /* af_key module makes the netkey proc interface visible */
+ if (stat(PROC_MODULES, &stb) == 0)
+ {
+ ignore_result(system("modprobe -qv af_key"));
+ }
+
+ /* now test again */
+ if (stat(PROC_NETKEY, &stb) != 0)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("kernel appears to lack the native netkey IPsec stack")
+ )
+ return FALSE;
+ }
}
- /* now test again */
- if (stat(PROC_NETKEY, &stb) != 0)
+ /* make sure that all required IPsec modules are loaded */
+ if (stat(PROC_MODULES, &stb) == 0)
{
- DBG(DBG_CONTROL,
- DBG_log("kernel appears to lack the native netkey IPsec stack")
- )
- return FALSE;
+ ignore_result(system("modprobe -qv ah4"));
+ ignore_result(system("modprobe -qv esp4"));
+ ignore_result(system("modprobe -qv ipcomp"));
+ ignore_result(system("modprobe -qv xfrm4_tunnel"));
+ ignore_result(system("modprobe -qv xfrm_user"));
}
- }
-
- /* make sure that all required IPsec modules are loaded */
- if (stat(PROC_MODULES, &stb) == 0)
- {
- ignore_result(system("modprobe -qv ah4"));
- ignore_result(system("modprobe -qv esp4"));
- ignore_result(system("modprobe -qv ipcomp"));
- ignore_result(system("modprobe -qv xfrm4_tunnel"));
- ignore_result(system("modprobe -qv xfrm_user"));
- }
- DBG(DBG_CONTROL,
- DBG_log("Found netkey IPsec stack")
- )
- return TRUE;
+ DBG(DBG_CONTROL,
+ DBG_log("Found netkey IPsec stack")
+ )
+ return TRUE;
}
void
starter_netkey_cleanup(void)
{
- if (system("ip xfrm state > /dev/null 2>&1") == 0)
- {
- ignore_result(system("ip xfrm state flush"));
- ignore_result(system("ip xfrm policy flush"));
- }
- else if (system("type setkey > /dev/null 2>&1") == 0)
- {
- ignore_result(system("setkey -F"));
- ignore_result(system("setkey -FP"));
- }
- else
- {
- plog("WARNING: cannot flush IPsec state/policy database");
- }
+ if (system("ip xfrm state > /dev/null 2>&1") == 0)
+ {
+ ignore_result(system("ip xfrm state flush"));
+ ignore_result(system("ip xfrm policy flush"));
+ }
+ else if (system("type setkey > /dev/null 2>&1") == 0)
+ {
+ ignore_result(system("setkey -F"));
+ ignore_result(system("setkey -FP"));
+ }
+ else
+ {
+ plog("WARNING: cannot flush IPsec state/policy database");
+ }
}
diff --git a/src/starter/netkey.h b/src/starter/netkey.h
index dc9cacbf8..55f6a7c47 100644
--- a/src/starter/netkey.h
+++ b/src/starter/netkey.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: netkey.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_NETKEY_H_
diff --git a/src/starter/parser.h b/src/starter/parser.h
index 3af20b60e..1c6cf20ef 100644
--- a/src/starter/parser.h
+++ b/src/starter/parser.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: parser.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _IPSEC_PARSER_H_
@@ -22,32 +20,32 @@
typedef struct kw_entry kw_entry_t;
struct kw_entry {
- char *name;
- kw_token_t token;
+ char *name;
+ kw_token_t token;
};
typedef struct kw_list kw_list_t;
struct kw_list {
- kw_entry_t *entry;
- char *value;
- kw_list_t *next;
+ kw_entry_t *entry;
+ char *value;
+ kw_list_t *next;
};
typedef struct section_list section_list_t;
struct section_list {
- char *name;
- kw_list_t *kw;
- section_list_t *next;
+ char *name;
+ kw_list_t *kw;
+ section_list_t *next;
};
typedef struct config_parsed config_parsed_t;
struct config_parsed {
- kw_list_t *config_setup;
- section_list_t *conn_first, *conn_last;
- section_list_t *ca_first, *ca_last;
+ kw_list_t *config_setup;
+ section_list_t *conn_first, *conn_last;
+ section_list_t *ca_first, *ca_last;
};
config_parsed_t *parser_load_conf (const char *file);
diff --git a/src/starter/parser.l b/src/starter/parser.l
index e51d655df..5857c0815 100644
--- a/src/starter/parser.l
+++ b/src/starter/parser.l
@@ -1,3 +1,5 @@
+%option noinput
+%option nounput
%{
/* FreeS/WAN config file parser (parser.l)
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
@@ -11,8 +13,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: parser.l 4632 2008-11-11 18:37:19Z martin $
*/
#include <string.h>
@@ -23,8 +23,6 @@
#define MAX_INCLUDE_DEPTH 20
-#define YY_NO_INPUT
-#define YY_NO_UNPUT
extern void yyerror(const char *);
extern int yylex (void);
@@ -43,149 +41,149 @@ int _parser_y_include (const char *filename);
void _parser_y_error(char *b, int size, const char *s)
{
- extern char *yytext; // was: char yytext[];
+ extern char *yytext; // was: char yytext[];
- snprintf(b, size, "%s:%d: %s [%s]",
- __parser_y_private.filename[__parser_y_private.stack_ptr],
- __parser_y_private.line[__parser_y_private.stack_ptr],
- s, yytext);
+ snprintf(b, size, "%s:%d: %s [%s]",
+ __parser_y_private.filename[__parser_y_private.stack_ptr],
+ __parser_y_private.line[__parser_y_private.stack_ptr],
+ s, yytext);
}
void _parser_y_init (const char *f)
{
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
- __parser_y_private.line[0] = 1;
- __parser_y_private.filename[0] = strdup(f);
+ memset(&__parser_y_private, 0, sizeof(__parser_y_private));
+ __parser_y_private.line[0] = 1;
+ __parser_y_private.filename[0] = strdup(f);
}
void _parser_y_fini (void)
{
- unsigned int i;
-
- for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
- {
- if (__parser_y_private.filename[i])
- free(__parser_y_private.filename[i]);
- if (__parser_y_private.file[i])
- fclose(__parser_y_private.file[i]);
- }
- memset(&__parser_y_private, 0, sizeof(__parser_y_private));
-}
-
-int _parser_y_include (const char *filename)
-{
- glob_t files;
- int i, ret;
-
- ret = glob(filename, GLOB_ERR, NULL, &files);
- if (ret)
- {
- const char *err;
+ unsigned int i;
- switch (ret)
+ for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
{
- case GLOB_NOSPACE:
- err = "include files ran out of memory";
- break;
- case GLOB_ABORTED:
- err = "include files aborted due to read error";
- break;
- case GLOB_NOMATCH:
- err = "include files found no matches";
- break;
- default:
- err = "unknown include files error";
+ if (__parser_y_private.filename[i])
+ free(__parser_y_private.filename[i]);
+ if (__parser_y_private.file[i])
+ fclose(__parser_y_private.file[i]);
}
- yyerror(err);
- return 1;
- }
+ memset(&__parser_y_private, 0, sizeof(__parser_y_private));
+}
- for (i = 0; i < files.gl_pathc; i++)
- {
- FILE *f;
- unsigned int p = __parser_y_private.stack_ptr + 1;
+int _parser_y_include (const char *filename)
+{
+ glob_t files;
+ int i, ret;
- if (p >= MAX_INCLUDE_DEPTH)
+ ret = glob(filename, GLOB_ERR, NULL, &files);
+ if (ret)
{
- yyerror("max inclusion depth reached");
- return 1;
+ const char *err;
+
+ switch (ret)
+ {
+ case GLOB_NOSPACE:
+ err = "include files ran out of memory";
+ break;
+ case GLOB_ABORTED:
+ err = "include files aborted due to read error";
+ break;
+ case GLOB_NOMATCH:
+ err = "include files found no matches";
+ break;
+ default:
+ err = "unknown include files error";
+ }
+ yyerror(err);
+ return 1;
}
- f = fopen(files.gl_pathv[i], "r");
- if (!f)
+ for (i = 0; i < files.gl_pathc; i++)
{
- yyerror("can't open include filename");
- continue;
+ FILE *f;
+ unsigned int p = __parser_y_private.stack_ptr + 1;
+
+ if (p >= MAX_INCLUDE_DEPTH)
+ {
+ yyerror("max inclusion depth reached");
+ return 1;
+ }
+
+ f = fopen(files.gl_pathv[i], "r");
+ if (!f)
+ {
+ yyerror("can't open include filename");
+ continue;
+ }
+
+ __parser_y_private.stack_ptr++;
+ __parser_y_private.file[p] = f;
+ __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
+ __parser_y_private.line[p] = 1;
+ __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
+
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
}
-
- __parser_y_private.stack_ptr++;
- __parser_y_private.file[p] = f;
- __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
- __parser_y_private.line[p] = 1;
- __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
-
- yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
- }
- globfree(&files);
- return 0;
+ globfree(&files);
+ return 0;
}
%}
%%
-<<EOF>> {
- if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
- free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
- __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
- }
- if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
- fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
- __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
- yy_delete_buffer (YY_CURRENT_BUFFER);
- yy_switch_to_buffer
- (__parser_y_private.stack[__parser_y_private.stack_ptr]);
- }
- if (--__parser_y_private.stack_ptr < 0) {
- yyterminate();
- }
+<<EOF>> {
+ if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
+ free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
+ __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
+ }
+ if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
+ fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
+ __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
+ yy_delete_buffer (YY_CURRENT_BUFFER);
+ yy_switch_to_buffer
+ (__parser_y_private.stack[__parser_y_private.stack_ptr]);
+ }
+ if (--__parser_y_private.stack_ptr < 0) {
+ yyterminate();
+ }
}
-^[\t ]+ return FIRST_SPACES;
+^[\t ]+ return FIRST_SPACES;
-[\t ]+ /* ignore spaces in line */ ;
+[\t ]+ /* ignore spaces in line */ ;
-= return EQUAL;
+= return EQUAL;
-\n|#.*\n {
- __parser_y_private.line[__parser_y_private.stack_ptr]++;
- return EOL;
- }
+\n|#.*\n {
+ __parser_y_private.line[__parser_y_private.stack_ptr]++;
+ return EOL;
+ }
-config return CONFIG;
-setup return SETUP;
-conn return CONN;
-ca return CA;
-include return INCLUDE;
-version return FILE_VERSION;
+config return CONFIG;
+setup return SETUP;
+conn return CONN;
+ca return CA;
+include return INCLUDE;
+version return FILE_VERSION;
-[^\"= \t\n]+ {
- yylval.s = strdup(yytext);
- return STRING;
- }
+[^\"= \t\n]+ {
+ yylval.s = strdup(yytext);
+ return STRING;
+ }
-\"[^\"\n]*\" {
- yylval.s = strdup(yytext+1);
- if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
- return STRING;
- }
+\"[^\"\n]*\" {
+ yylval.s = strdup(yytext+1);
+ if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
+ return STRING;
+ }
-. yyerror(yytext);
+. yyerror(yytext);
%%
int yywrap(void)
{
- return 1;
+ return 1;
}
diff --git a/src/starter/parser.y b/src/starter/parser.y
index 14148d965..4533228c2 100644
--- a/src/starter/parser.y
+++ b/src/starter/parser.y
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: parser.y 3267 2007-10-08 19:57:54Z andreas $
*/
#include <stdio.h>
@@ -27,7 +25,7 @@
#include "parser.h"
#define YYERROR_VERBOSE
-#define ERRSTRING_LEN 256
+#define ERRSTRING_LEN 256
/**
* Bison
@@ -64,220 +62,215 @@ extern kw_entry_t *in_word_set (char *str, unsigned int len);
*/
config_file:
- config_file section_or_include
- | /* NULL */
- ;
+ config_file section_or_include
+ | /* NULL */
+ ;
section_or_include:
- FILE_VERSION STRING EOL
- {
- free($2);
- }
- | CONFIG SETUP EOL
- {
- _parser_kw = &(_parser_cfg->config_setup);
- _parser_kw_last = NULL;
- } kw_section
- | CONN STRING EOL
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
-
- section->name = clone_str($2, "conn section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->conn_first)
- _parser_cfg->conn_first = section;
- if (_parser_cfg->conn_last)
- _parser_cfg->conn_last->next = section;
- _parser_cfg->conn_last = section;
- _parser_kw_last = NULL;
- free($2);
- } kw_section
- | CA STRING EOL
- {
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
- section->name = clone_str($2, "ca section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->ca_first)
- _parser_cfg->ca_first = section;
- if (_parser_cfg->ca_last)
- _parser_cfg->ca_last->next = section;
- _parser_cfg->ca_last = section;
- _parser_kw_last = NULL;
- free($2);
- } kw_section
- | INCLUDE STRING
- {
- extern void _parser_y_include (const char *f);
- _parser_y_include($2);
- free($2);
- } EOL
- | EOL
- ;
+ FILE_VERSION STRING EOL
+ {
+ free($2);
+ }
+ | CONFIG SETUP EOL
+ {
+ _parser_kw = &(_parser_cfg->config_setup);
+ _parser_kw_last = NULL;
+ } kw_section
+ | CONN STRING EOL
+ {
+ section_list_t *section = malloc_thing(section_list_t);
+
+ section->name = clone_str($2);
+ section->kw = NULL;
+ section->next = NULL;
+ _parser_kw = &(section->kw);
+ if (!_parser_cfg->conn_first)
+ _parser_cfg->conn_first = section;
+ if (_parser_cfg->conn_last)
+ _parser_cfg->conn_last->next = section;
+ _parser_cfg->conn_last = section;
+ _parser_kw_last = NULL;
+ free($2);
+ } kw_section
+ | CA STRING EOL
+ {
+ section_list_t *section = malloc_thing(section_list_t);
+ section->name = clone_str($2);
+ section->kw = NULL;
+ section->next = NULL;
+ _parser_kw = &(section->kw);
+ if (!_parser_cfg->ca_first)
+ _parser_cfg->ca_first = section;
+ if (_parser_cfg->ca_last)
+ _parser_cfg->ca_last->next = section;
+ _parser_cfg->ca_last = section;
+ _parser_kw_last = NULL;
+ free($2);
+ } kw_section
+ | INCLUDE STRING
+ {
+ extern void _parser_y_include (const char *f);
+ _parser_y_include($2);
+ free($2);
+ } EOL
+ | EOL
+ ;
kw_section:
- FIRST_SPACES statement_kw EOL kw_section
- |
- ;
+ FIRST_SPACES statement_kw EOL kw_section
+ |
+ ;
statement_kw:
- STRING EQUAL STRING
- {
- kw_list_t *new;
- kw_entry_t *entry = in_word_set($1, strlen($1));
-
- if (entry == NULL)
- {
- snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
- yyerror(errbuf);
- }
- else if (_parser_kw)
+ STRING EQUAL STRING
{
- new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
- new->entry = entry;
- new->value = clone_str($3, "kw_list value");
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw)
- *_parser_kw = new;
+ kw_list_t *new;
+ kw_entry_t *entry = in_word_set($1, strlen($1));
+
+ if (entry == NULL)
+ {
+ snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
+ yyerror(errbuf);
+ }
+ else if (_parser_kw)
+ {
+ new = (kw_list_t *)malloc_thing(kw_list_t);
+ new->entry = entry;
+ new->value = clone_str($3);
+ new->next = NULL;
+ if (_parser_kw_last)
+ _parser_kw_last->next = new;
+ _parser_kw_last = new;
+ if (!*_parser_kw)
+ *_parser_kw = new;
+ }
+ free($1);
+ free($3);
}
- free($1);
- free($3);
- }
- | STRING EQUAL
- {
- free($1);
- }
- |
- ;
+ | STRING EQUAL
+ {
+ free($1);
+ }
+ |
+ ;
%%
void
yyerror(const char *s)
{
- if (_save_errors_)
- _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
+ if (_save_errors_)
+ _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
}
config_parsed_t *
parser_load_conf(const char *file)
{
- config_parsed_t *cfg = NULL;
- int err = 0;
- FILE *f;
+ config_parsed_t *cfg = NULL;
+ int err = 0;
+ FILE *f;
- extern void _parser_y_init (const char *f);
- extern FILE *yyin;
+ extern void _parser_y_init (const char *f);
+ extern FILE *yyin;
- memset(parser_errstring, 0, ERRSTRING_LEN+1);
+ memset(parser_errstring, 0, ERRSTRING_LEN+1);
- cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
- if (cfg)
- {
- memset(cfg, 0, sizeof(config_parsed_t));
- f = fopen(file, "r");
- if (f)
+ cfg = (config_parsed_t *)malloc_thing(config_parsed_t);
+ if (cfg)
{
- yyin = f;
- _parser_y_init(file);
- _save_errors_ = 1;
- _parser_cfg = cfg;
+ memset(cfg, 0, sizeof(config_parsed_t));
+ f = fopen(file, "r");
+ if (f)
+ {
+ yyin = f;
+ _parser_y_init(file);
+ _save_errors_ = 1;
+ _parser_cfg = cfg;
+
+ if (yyparse() !=0 )
+ {
+ if (parser_errstring[0] == '\0')
+ {
+ snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
+ }
+ _save_errors_ = 0;
+ while (yyparse() != 0);
+ err++;
+ }
+ else if (parser_errstring[0] != '\0')
+ {
+ err++;
+ }
+ else
+ {
+ /**
+ * Config valid
+ */
+ }
- if (yyparse() !=0 )
- {
- if (parser_errstring[0] == '\0')
+ fclose(f);
+ }
+ else
{
- snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
+ err++;
}
- _save_errors_ = 0;
- while (yyparse() != 0);
- err++;
- }
- else if (parser_errstring[0] != '\0')
- {
- err++;
- }
- else
- {
- /**
- * Config valid
- */
- }
-
- fclose(f);
}
else
{
- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
- err++;
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
+ err++;
}
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
- err++;
- }
- if (err)
- {
- plog("%s", parser_errstring);
+ if (err)
+ {
+ plog("%s", parser_errstring);
- if (cfg)
- parser_free_conf(cfg);
- cfg = NULL;
- }
+ if (cfg)
+ parser_free_conf(cfg);
+ cfg = NULL;
+ }
- return cfg;
+ return cfg;
}
static void
parser_free_kwlist(kw_list_t *list)
{
- kw_list_t *elt;
+ kw_list_t *elt;
- while (list)
- {
- elt = list;
- list = list->next;
- if (elt->value)
- pfree(elt->value);
- pfree(elt);
- }
+ while (list)
+ {
+ elt = list;
+ list = list->next;
+ free(elt->value);
+ free(elt);
+ }
}
void
parser_free_conf(config_parsed_t *cfg)
{
- section_list_t *sec;
- if (cfg)
- {
- parser_free_kwlist(cfg->config_setup);
- while (cfg->conn_first)
- {
- sec = cfg->conn_first;
- cfg->conn_first = cfg->conn_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- while (cfg->ca_first)
+ section_list_t *sec;
+ if (cfg)
{
- sec = cfg->ca_first;
- cfg->ca_first = cfg->ca_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
+ parser_free_kwlist(cfg->config_setup);
+ while (cfg->conn_first)
+ {
+ sec = cfg->conn_first;
+ cfg->conn_first = cfg->conn_first->next;
+ free(sec->name);
+ parser_free_kwlist(sec->kw);
+ free(sec);
+ }
+ while (cfg->ca_first)
+ {
+ sec = cfg->ca_first;
+ cfg->ca_first = cfg->ca_first->next;
+ free(sec->name);
+ parser_free_kwlist(sec->kw);
+ free(sec);
+ }
+ free(cfg);
}
- pfree(cfg);
- }
}
diff --git a/src/starter/starter.c b/src/starter/starter.c
index e4ad5286c..2d2f452b5 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: starter.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <sys/types.h>
@@ -71,662 +69,666 @@ static unsigned int _action_ = 0;
static void
fsig(int signal)
{
- switch (signal)
- {
- case SIGCHLD:
+ switch (signal)
{
- int status;
- pid_t pid;
- char *name = NULL;
-
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
- {
- if (pid == starter_pluto_pid())
- name = " (Pluto)";
- if (pid == starter_charon_pid())
- name = " (Charon)";
- if (WIFSIGNALED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has been killed by sig %d\n",
- pid, name?name:"", WTERMSIG(status))
- )
- else if (WIFSTOPPED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has been stopped by sig %d\n",
- pid, name?name:"", WSTOPSIG(status))
- )
- else if (WIFEXITED(status))
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has quit (exit code %d)\n",
- pid, name?name:"", WEXITSTATUS(status))
- )
- else
- DBG(DBG_CONTROL,
- DBG_log("child %d%s has quit", pid, name?name:"")
- )
- if (pid == starter_pluto_pid())
- starter_pluto_sigchild(pid);
- if (pid == starter_charon_pid())
- starter_charon_sigchild(pid);
- }
+ case SIGCHLD:
+ {
+ int status;
+ pid_t pid;
+ char *name = NULL;
+
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ if (pid == starter_pluto_pid())
+ name = " (Pluto)";
+ if (pid == starter_charon_pid())
+ name = " (Charon)";
+ if (WIFSIGNALED(status))
+ DBG(DBG_CONTROL,
+ DBG_log("child %d%s has been killed by sig %d\n",
+ pid, name?name:"", WTERMSIG(status))
+ )
+ else if (WIFSTOPPED(status))
+ DBG(DBG_CONTROL,
+ DBG_log("child %d%s has been stopped by sig %d\n",
+ pid, name?name:"", WSTOPSIG(status))
+ )
+ else if (WIFEXITED(status))
+ DBG(DBG_CONTROL,
+ DBG_log("child %d%s has quit (exit code %d)\n",
+ pid, name?name:"", WEXITSTATUS(status))
+ )
+ else
+ DBG(DBG_CONTROL,
+ DBG_log("child %d%s has quit", pid, name?name:"")
+ )
+ if (pid == starter_pluto_pid())
+ starter_pluto_sigchild(pid);
+ if (pid == starter_charon_pid())
+ starter_charon_sigchild(pid);
+ }
+ }
+ break;
+
+ case SIGPIPE:
+ /** ignore **/
+ break;
+
+ case SIGALRM:
+ _action_ |= FLAG_ACTION_START_PLUTO;
+ _action_ |= FLAG_ACTION_START_CHARON;
+ break;
+
+ case SIGHUP:
+ _action_ |= FLAG_ACTION_UPDATE;
+ break;
+
+ case SIGTERM:
+ case SIGQUIT:
+ case SIGINT:
+ _action_ |= FLAG_ACTION_QUIT;
+ break;
+
+ case SIGUSR1:
+ _action_ |= FLAG_ACTION_RELOAD;
+ _action_ |= FLAG_ACTION_UPDATE;
+ break;
+
+ default:
+ plog("fsig(): unknown signal %d -- investigate", signal);
+ break;
}
- break;
-
- case SIGPIPE:
- /** ignore **/
- break;
-
- case SIGALRM:
- _action_ |= FLAG_ACTION_START_PLUTO;
- _action_ |= FLAG_ACTION_START_CHARON;
- break;
-
- case SIGHUP:
- _action_ |= FLAG_ACTION_UPDATE;
- break;
-
- case SIGTERM:
- case SIGQUIT:
- case SIGINT:
- _action_ |= FLAG_ACTION_QUIT;
- break;
-
- case SIGUSR1:
- _action_ |= FLAG_ACTION_RELOAD;
- _action_ |= FLAG_ACTION_UPDATE;
- break;
-
- default:
- plog("fsig(): unknown signal %d -- investigate", signal);
- break;
- }
}
static void generate_selfcert()
{
- struct stat stb;
-
- /* if ipsec.secrets file is missing then generate RSA default key pair */
- if (stat(SECRETS_FILE, &stb) != 0)
- {
- mode_t oldmask;
- FILE *f;
- uid_t uid = 0;
- gid_t gid = 0;
+ struct stat stb;
+
+ /* if ipsec.secrets file is missing then generate RSA default key pair */
+ if (stat(SECRETS_FILE, &stb) != 0)
+ {
+ mode_t oldmask;
+ FILE *f;
+ uid_t uid = 0;
+ gid_t gid = 0;
#ifdef IPSEC_GROUP
- {
- char buf[1024];
- struct group group, *grp;
-
- if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 &&
- grp)
{
- gid = grp->gr_gid;
+ char buf[1024];
+ struct group group, *grp;
+
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 && grp)
+ {
+ gid = grp->gr_gid;
+ }
}
- }
#endif
#ifdef IPSEC_USER
- {
- char buf[1024];
- struct passwd passwd, *pwp;
-
- if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 &&
- pwp)
{
- uid = pwp->pw_uid;
+ char buf[1024];
+ struct passwd passwd, *pwp;
+
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 && pwp)
+ {
+ uid = pwp->pw_uid;
+ }
+ }
+#endif
+ setegid(gid);
+ seteuid(uid);
+ ignore_result(system("ipsec scepclient --out pkcs1 --out cert-self --quiet"));
+ seteuid(0);
+ setegid(0);
+
+ /* ipsec.secrets is root readable only */
+ oldmask = umask(0066);
+
+ f = fopen(SECRETS_FILE, "w");
+ if (f)
+ {
+ fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
+ fprintf(f, "\n");
+ fprintf(f, ": RSA myKey.der\n");
+ fclose(f);
}
+ ignore_result(chown(SECRETS_FILE, uid, gid));
+ umask(oldmask);
}
-#endif
- setegid(gid);
- seteuid(uid);
- ignore_result(system("ipsec scepclient --out pkcs1 --out cert-self --quiet"));
- seteuid(0);
- setegid(0);
-
- /* ipsec.secrets is root readable only */
- oldmask = umask(0066);
-
- f = fopen(SECRETS_FILE, "w");
- if (f)
- {
- fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
- fprintf(f, "\n");
- fprintf(f, ": RSA myKey.der\n");
- fclose(f);
- }
- ignore_result(chown(SECRETS_FILE, uid, gid));
- umask(oldmask);
- }
}
static void
usage(char *name)
{
- fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
- "[--debug|--debug-more|--debug-all]\n");
- exit(LSB_RC_INVALID_ARGUMENT);
+ fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
+ "[--debug|--debug-more|--debug-all]\n");
+ exit(LSB_RC_INVALID_ARGUMENT);
}
int main (int argc, char **argv)
{
- starter_config_t *cfg = NULL;
- starter_config_t *new_cfg;
- starter_conn_t *conn, *conn2;
- starter_ca_t *ca, *ca2;
-
- struct stat stb;
-
- char *err = NULL;
- int i;
- int id = 1;
- struct timeval tv;
- unsigned long auto_update = 0;
- time_t last_reload;
- bool no_fork = FALSE;
-
- /* global variables defined in log.h */
- log_to_stderr = TRUE;
- base_debugging = DBG_NONE;
-
- /* parse command line */
- for (i = 1; i < argc; i++)
- {
- if (streq(argv[i], "--debug"))
+ starter_config_t *cfg = NULL;
+ starter_config_t *new_cfg;
+ starter_conn_t *conn, *conn2;
+ starter_ca_t *ca, *ca2;
+
+ struct stat stb;
+
+ char *err = NULL;
+ int i;
+ int id = 1;
+ struct timeval tv;
+ unsigned long auto_update = 0;
+ time_t last_reload;
+ bool no_fork = FALSE;
+ bool attach_gdb = FALSE;
+
+ /* global variables defined in log.h */
+ log_to_stderr = TRUE;
+ base_debugging = DBG_NONE;
+
+ /* parse command line */
+ for (i = 1; i < argc; i++)
{
- base_debugging |= DBG_CONTROL;
+ if (streq(argv[i], "--debug"))
+ {
+ base_debugging |= DBG_CONTROL;
+ }
+ else if (streq(argv[i], "--debug-more"))
+ {
+ base_debugging |= DBG_CONTROLMORE;
+ }
+ else if (streq(argv[i], "--debug-all"))
+ {
+ base_debugging |= DBG_ALL;
+ }
+ else if (streq(argv[i], "--nofork"))
+ {
+ no_fork = TRUE;
+ }
+ else if (streq(argv[i], "--attach-gdb"))
+ {
+ no_fork = TRUE;
+ attach_gdb = TRUE;
+ }
+ else if (streq(argv[i], "--auto-update") && i+1 < argc)
+ {
+ auto_update = atoi(argv[++i]);
+ if (!auto_update)
+ usage(argv[0]);
+ }
+ else
+ {
+ usage(argv[0]);
+ }
}
- else if (streq(argv[i], "--debug-more"))
+
+ /* Init */
+ init_log("ipsec_starter");
+ cur_debugging = base_debugging;
+
+ signal(SIGHUP, fsig);
+ signal(SIGCHLD, fsig);
+ signal(SIGPIPE, fsig);
+ signal(SIGINT, fsig);
+ signal(SIGTERM, fsig);
+ signal(SIGQUIT, fsig);
+ signal(SIGALRM, fsig);
+ signal(SIGUSR1, fsig);
+
+ plog("Starting strongSwan "VERSION" IPsec [starter]...");
+
+ /* verify that we can start */
+ if (getuid() != 0)
{
- base_debugging |= DBG_CONTROLMORE;
+ plog("permission denied (must be superuser)");
+ exit(LSB_RC_NOT_ALLOWED);
}
- else if (streq(argv[i], "--debug-all"))
+
+ if (stat(PLUTO_PID_FILE, &stb) == 0)
{
- base_debugging |= DBG_ALL;
+ plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
}
- else if (streq(argv[i], "--nofork"))
+ else
{
- no_fork = TRUE;
+ _action_ |= FLAG_ACTION_START_PLUTO;
}
- else if (streq(argv[i], "--auto-update") && i+1 < argc)
+ if (stat(CHARON_PID_FILE, &stb) == 0)
{
- auto_update = atoi(argv[++i]);
- if (!auto_update)
- usage(argv[0]);
+ plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
}
else
{
- usage(argv[0]);
+ _action_ |= FLAG_ACTION_START_CHARON;
}
- }
-
- /* Init */
- init_log("ipsec_starter");
- cur_debugging = base_debugging;
-
- signal(SIGHUP, fsig);
- signal(SIGCHLD, fsig);
- signal(SIGPIPE, fsig);
- signal(SIGINT, fsig);
- signal(SIGTERM, fsig);
- signal(SIGQUIT, fsig);
- signal(SIGALRM, fsig);
- signal(SIGUSR1, fsig);
-
- plog("Starting strongSwan %s IPsec [starter]...", ipsec_version_code());
-
- /* verify that we can start */
- if (getuid() != 0)
- {
- plog("permission denied (must be superuser)");
- exit(LSB_RC_NOT_ALLOWED);
- }
-
- if (stat(PLUTO_PID_FILE, &stb) == 0)
- {
- plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
- }
- else
- {
- _action_ |= FLAG_ACTION_START_PLUTO;
- }
- if (stat(CHARON_PID_FILE, &stb) == 0)
- {
- plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
- }
- else
- {
- _action_ |= FLAG_ACTION_START_CHARON;
- }
- if (stat(DEV_RANDOM, &stb) != 0)
- {
- plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
- exit(LSB_RC_FAILURE);
- }
-
- if (stat(DEV_URANDOM, &stb)!= 0)
- {
- plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
- exit(LSB_RC_FAILURE);
- }
-
- cfg = confread_load(CONFIG_FILE);
- if (cfg == NULL || cfg->err > 0)
- {
- plog("unable to start strongSwan -- fatal errors in config");
- if (cfg)
+ if (stat(DEV_RANDOM, &stb) != 0)
{
- confread_free(cfg);
+ plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
+ exit(LSB_RC_FAILURE);
}
- exit(LSB_RC_INVALID_ARGUMENT);
- }
- /* determine if we have a native netkey IPsec stack */
- if (!starter_netkey_init())
- {
- plog("no netkey IPSec stack detected");
- if (!starter_klips_init())
+ if (stat(DEV_URANDOM, &stb)!= 0)
{
- plog("no KLIPS IPSec stack detected");
- exit(LSB_RC_FAILURE);
+ plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
+ exit(LSB_RC_FAILURE);
}
- }
-
- last_reload = time(NULL);
-
- if (stat(STARTER_PID_FILE, &stb) == 0)
- {
- plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
- exit(LSB_RC_SUCCESS);
- }
-
- generate_selfcert();
-
- /* fork if we're not debugging stuff */
- if (!no_fork)
- {
- log_to_stderr = FALSE;
- switch (fork())
+ cfg = confread_load(CONFIG_FILE);
+ if (cfg == NULL || cfg->err > 0)
{
- case 0:
- {
- int fnull = open("/dev/null", O_RDWR);
-
- if (fnull >= 0)
+ plog("unable to start strongSwan -- fatal errors in config");
+ if (cfg)
{
- dup2(fnull, STDIN_FILENO);
- dup2(fnull, STDOUT_FILENO);
- dup2(fnull, STDERR_FILENO);
- close(fnull);
+ confread_free(cfg);
}
- setsid();
- }
- break;
- case -1:
- plog("can't fork: %s", strerror(errno));
- break;
- default:
- exit(LSB_RC_SUCCESS);
+ exit(LSB_RC_INVALID_ARGUMENT);
}
- }
- /* save pid file in /var/run/starter.pid */
- {
- FILE *fd = fopen(STARTER_PID_FILE, "w");
-
- if (fd)
+ /* determine if we have a native netkey IPsec stack */
+ if (!starter_netkey_init())
{
- fprintf(fd, "%u\n", getpid());
- fclose(fd);
+ plog("no netkey IPsec stack detected");
+ if (!starter_klips_init())
+ {
+ plog("no KLIPS IPsec stack detected");
+ plog("no known IPsec stack detected, ignoring!");
+ }
}
- }
-
- for (;;)
- {
- /*
- * Stop pluto/charon (if started) and exit
- */
- if (_action_ & FLAG_ACTION_QUIT)
+
+ last_reload = time(NULL);
+
+ if (stat(STARTER_PID_FILE, &stb) == 0)
{
- if (starter_pluto_pid())
- starter_stop_pluto();
- if (starter_charon_pid())
- starter_stop_charon();
- starter_netkey_cleanup();
- confread_free(cfg);
- unlink(STARTER_PID_FILE);
- unlink(INFO_FILE);
-#ifdef LEAK_DETECTIVE
- report_leaks();
-#endif /* LEAK_DETECTIVE */
- close_log();
- plog("ipsec starter stopped");
- exit(LSB_RC_SUCCESS);
+ plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
+ exit(LSB_RC_SUCCESS);
}
+
+ generate_selfcert();
- /*
- * Delete all connections. Will be added below
- */
- if (_action_ & FLAG_ACTION_RELOAD)
+ /* fork if we're not debugging stuff */
+ if (!no_fork)
{
- if (starter_pluto_pid() || starter_charon_pid())
- {
- for (conn = cfg->conn_first; conn; conn = conn->next)
+ log_to_stderr = FALSE;
+
+ switch (fork())
{
- if (conn->state == STATE_ADDED)
- {
- if (starter_charon_pid())
- {
- starter_stroke_del_conn(conn);
- }
- if (starter_pluto_pid())
+ case 0:
{
- starter_whack_del_conn(conn);
+ int fnull = open("/dev/null", O_RDWR);
+
+ if (fnull >= 0)
+ {
+ dup2(fnull, STDIN_FILENO);
+ dup2(fnull, STDOUT_FILENO);
+ dup2(fnull, STDERR_FILENO);
+ close(fnull);
+ }
+ setsid();
}
- conn->state = STATE_TO_ADD;
- }
+ break;
+ case -1:
+ plog("can't fork: %s", strerror(errno));
+ break;
+ default:
+ exit(LSB_RC_SUCCESS);
}
- for (ca = cfg->ca_first; ca; ca = ca->next)
+ }
+
+ /* save pid file in /var/run/starter.pid */
+ {
+ FILE *fd = fopen(STARTER_PID_FILE, "w");
+
+ if (fd)
{
- if (ca->state == STATE_ADDED)
- {
- if (starter_charon_pid())
- {
- starter_stroke_del_ca(ca);
- }
- if (starter_pluto_pid())
- {
- starter_whack_del_ca(ca);
- }
- ca->state = STATE_TO_ADD;
- }
+ fprintf(fd, "%u\n", getpid());
+ fclose(fd);
}
- }
- _action_ &= ~FLAG_ACTION_RELOAD;
}
- /*
- * Update configuration
- */
- if (_action_ & FLAG_ACTION_UPDATE)
+ for (;;)
{
- err = NULL;
- DBG(DBG_CONTROL,
- DBG_log("Reloading config...")
- );
- new_cfg = confread_load(CONFIG_FILE);
-
- if (new_cfg && (new_cfg->err + new_cfg->non_fatal_err == 0))
- {
- /* Switch to new config. New conn will be loaded below */
- if (!starter_cmp_defaultroute(&new_cfg->defaultroute
- , &cfg->defaultroute))
+ /*
+ * Stop pluto/charon (if started) and exit
+ */
+ if (_action_ & FLAG_ACTION_QUIT)
{
- _action_ |= FLAG_ACTION_LISTEN;
+ if (starter_pluto_pid())
+ starter_stop_pluto();
+ if (starter_charon_pid())
+ starter_stop_charon();
+ starter_netkey_cleanup();
+ confread_free(cfg);
+ unlink(STARTER_PID_FILE);
+ unlink(INFO_FILE);
+#ifdef LEAK_DETECTIVE
+ report_leaks();
+#endif /* LEAK_DETECTIVE */
+ close_log();
+ plog("ipsec starter stopped");
+ exit(LSB_RC_SUCCESS);
}
- if (!starter_cmp_pluto(cfg, new_cfg))
+ /*
+ * Delete all connections. Will be added below
+ */
+ if (_action_ & FLAG_ACTION_RELOAD)
{
- plog("Pluto has changed");
- if (starter_pluto_pid())
- starter_stop_pluto();
- _action_ &= ~FLAG_ACTION_LISTEN;
- _action_ |= FLAG_ACTION_START_PLUTO;
+ if (starter_pluto_pid() || starter_charon_pid())
+ {
+ for (conn = cfg->conn_first; conn; conn = conn->next)
+ {
+ if (conn->state == STATE_ADDED)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_del_conn(conn);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_del_conn(conn);
+ }
+ conn->state = STATE_TO_ADD;
+ }
+ }
+ for (ca = cfg->ca_first; ca; ca = ca->next)
+ {
+ if (ca->state == STATE_ADDED)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_del_ca(ca);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_del_ca(ca);
+ }
+ ca->state = STATE_TO_ADD;
+ }
+ }
+ }
+ _action_ &= ~FLAG_ACTION_RELOAD;
}
- else
+
+ /*
+ * Update configuration
+ */
+ if (_action_ & FLAG_ACTION_UPDATE)
{
- /* Only reload conn and ca sections if pluto is not killed */
+ err = NULL;
+ DBG(DBG_CONTROL,
+ DBG_log("Reloading config...")
+ );
+ new_cfg = confread_load(CONFIG_FILE);
- /* Look for new connections that are already loaded */
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
+ if (new_cfg && (new_cfg->err + new_cfg->non_fatal_err == 0))
{
- for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
- {
- if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
+ /* Switch to new config. New conn will be loaded below */
+ if (!starter_cmp_defaultroute(&new_cfg->defaultroute
+ , &cfg->defaultroute))
{
- conn->state = STATE_REPLACED;
- conn2->state = STATE_ADDED;
- conn2->id = conn->id;
- break;
+ _action_ |= FLAG_ACTION_LISTEN;
}
- }
- }
- }
- /* Remove conn sections that have become unused */
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
+ if (!starter_cmp_pluto(cfg, new_cfg))
+ {
+ plog("Pluto has changed");
+ if (starter_pluto_pid())
+ starter_stop_pluto();
+ _action_ &= ~FLAG_ACTION_LISTEN;
+ _action_ |= FLAG_ACTION_START_PLUTO;
+ }
+ else
+ {
+ /* Only reload conn and ca sections if pluto is not killed */
+
+ /* Look for new connections that are already loaded */
+ for (conn = cfg->conn_first; conn; conn = conn->next)
+ {
+ if (conn->state == STATE_ADDED)
+ {
+ for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
+ {
+ if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
+ {
+ conn->state = STATE_REPLACED;
+ conn2->state = STATE_ADDED;
+ conn2->id = conn->id;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Remove conn sections that have become unused */
+ for (conn = cfg->conn_first; conn; conn = conn->next)
+ {
+ if (conn->state == STATE_ADDED)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_del_conn(conn);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_del_conn(conn);
+ }
+ }
+ }
+
+ /* Look for new ca sections that are already loaded */
+ for (ca = cfg->ca_first; ca; ca = ca->next)
+ {
+ if (ca->state == STATE_ADDED)
+ {
+ for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
+ {
+ if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
+ {
+ ca->state = STATE_REPLACED;
+ ca2->state = STATE_ADDED;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Remove ca sections that have become unused */
+ for (ca = cfg->ca_first; ca; ca = ca->next)
+ {
+ if (ca->state == STATE_ADDED)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_del_ca(ca);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_del_ca(ca);
+ }
+ }
+ }
+ }
+ confread_free(cfg);
+ cfg = new_cfg;
+ }
+ else
{
- if (starter_charon_pid())
- {
- starter_stroke_del_conn(conn);
- }
- if (starter_pluto_pid())
- {
- starter_whack_del_conn(conn);
- }
+ plog("can't reload config file due to errors -- keeping old one");
+ if (new_cfg)
+ {
+ confread_free(new_cfg);
+ }
}
- }
+ _action_ &= ~FLAG_ACTION_UPDATE;
+ last_reload = time(NULL);
+ }
- /* Look for new ca sections that are already loaded */
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
+ /*
+ * Start pluto
+ */
+ if (_action_ & FLAG_ACTION_START_PLUTO)
+ {
+ if (cfg->setup.plutostart && !starter_pluto_pid())
{
- for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
- {
- if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
+ DBG(DBG_CONTROL,
+ DBG_log("Attempting to start pluto...")
+ );
+
+ if (starter_start_pluto(cfg, no_fork, attach_gdb) == 0)
+ {
+ starter_whack_listen();
+ }
+ else
{
- ca->state = STATE_REPLACED;
- ca2->state = STATE_ADDED;
- break;
+ /* schedule next try */
+ alarm(PLUTO_RESTART_DELAY);
}
- }
}
- }
+ _action_ &= ~FLAG_ACTION_START_PLUTO;
- /* Remove ca sections that have become unused */
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
+ for (ca = cfg->ca_first; ca; ca = ca->next)
{
- if (starter_charon_pid())
- {
- starter_stroke_del_ca(ca);
- }
- if (starter_pluto_pid())
- {
- starter_whack_del_ca(ca);
- }
+ if (ca->state == STATE_ADDED)
+ ca->state = STATE_TO_ADD;
}
- }
- }
- confread_free(cfg);
- cfg = new_cfg;
- }
- else
- {
- plog("can't reload config file due to errors -- keeping old one");
- if (new_cfg)
- {
- confread_free(new_cfg);
- }
- }
- _action_ &= ~FLAG_ACTION_UPDATE;
- last_reload = time(NULL);
- }
- /*
- * Start pluto
- */
- if (_action_ & FLAG_ACTION_START_PLUTO)
- {
- if (cfg->setup.plutostart && !starter_pluto_pid())
- {
- DBG(DBG_CONTROL,
- DBG_log("Attempting to start pluto...")
- );
-
- if (starter_start_pluto(cfg, no_fork) == 0)
- {
- starter_whack_listen();
- }
- else
- {
- /* schedule next try */
- alarm(PLUTO_RESTART_DELAY);
+ for (conn = cfg->conn_first; conn; conn = conn->next)
+ {
+ if (conn->state == STATE_ADDED)
+ conn->state = STATE_TO_ADD;
+ }
}
- }
- _action_ &= ~FLAG_ACTION_START_PLUTO;
-
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_ADDED)
- ca->state = STATE_TO_ADD;
- }
-
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_ADDED)
- conn->state = STATE_TO_ADD;
- }
- }
-
- /*
- * Start charon
- */
- if (_action_ & FLAG_ACTION_START_CHARON)
- {
- if (cfg->setup.charonstart && !starter_charon_pid())
- {
- DBG(DBG_CONTROL,
- DBG_log("Attempting to start charon...")
- );
- if (starter_start_charon(cfg, no_fork))
+
+ /*
+ * Start charon
+ */
+ if (_action_ & FLAG_ACTION_START_CHARON)
{
- /* schedule next try */
- alarm(PLUTO_RESTART_DELAY);
+ if (cfg->setup.charonstart && !starter_charon_pid())
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("Attempting to start charon...")
+ );
+ if (starter_start_charon(cfg, no_fork, attach_gdb))
+ {
+ /* schedule next try */
+ alarm(PLUTO_RESTART_DELAY);
+ }
+ starter_stroke_configure(cfg);
+ }
+ _action_ &= ~FLAG_ACTION_START_CHARON;
}
- starter_stroke_configure(cfg);
- }
- _action_ &= ~FLAG_ACTION_START_CHARON;
- }
-
- /*
- * Tell pluto to reread its interfaces
- */
- if (_action_ & FLAG_ACTION_LISTEN)
- {
- if (starter_pluto_pid())
- {
- starter_whack_listen();
- _action_ &= ~FLAG_ACTION_LISTEN;
- }
- }
- /*
- * Add stale conn and ca sections
- */
- if (starter_pluto_pid() || starter_charon_pid())
- {
- for (ca = cfg->ca_first; ca; ca = ca->next)
- {
- if (ca->state == STATE_TO_ADD)
+ /*
+ * Tell pluto to reread its interfaces
+ */
+ if (_action_ & FLAG_ACTION_LISTEN)
{
- if (starter_charon_pid())
- {
- starter_stroke_add_ca(ca);
- }
- if (starter_pluto_pid())
- {
- starter_whack_add_ca(ca);
- }
- ca->state = STATE_ADDED;
+ if (starter_pluto_pid())
+ {
+ starter_whack_listen();
+ _action_ &= ~FLAG_ACTION_LISTEN;
+ }
}
- }
- for (conn = cfg->conn_first; conn; conn = conn->next)
- {
- if (conn->state == STATE_TO_ADD)
+ /*
+ * Add stale conn and ca sections
+ */
+ if (starter_pluto_pid() || starter_charon_pid())
{
- if (conn->id == 0)
- {
- /* affect new unique id */
- conn->id = id++;
- }
- if (starter_charon_pid())
- {
- starter_stroke_add_conn(cfg, conn);
- }
- if (starter_pluto_pid())
- {
- starter_whack_add_conn(conn);
- }
- conn->state = STATE_ADDED;
-
- if (conn->startup == STARTUP_START)
- {
- if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+ for (ca = cfg->ca_first; ca; ca = ca->next)
{
- if (starter_charon_pid())
- {
- starter_stroke_initiate_conn(conn);
- }
- }
- else
- {
- if (starter_pluto_pid())
- {
- starter_whack_initiate_conn(conn);
- }
- }
- }
- else if (conn->startup == STARTUP_ROUTE)
- {
- if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
- {
- if (starter_charon_pid())
- {
- starter_stroke_route_conn(conn);
- }
+ if (ca->state == STATE_TO_ADD)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_add_ca(ca);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_add_ca(ca);
+ }
+ ca->state = STATE_ADDED;
+ }
}
- else
+
+ for (conn = cfg->conn_first; conn; conn = conn->next)
{
- if (starter_pluto_pid())
- {
- starter_whack_route_conn(conn);
- }
+ if (conn->state == STATE_TO_ADD)
+ {
+ if (conn->id == 0)
+ {
+ /* affect new unique id */
+ conn->id = id++;
+ }
+ if (starter_charon_pid())
+ {
+ starter_stroke_add_conn(cfg, conn);
+ }
+ if (starter_pluto_pid())
+ {
+ starter_whack_add_conn(conn);
+ }
+ conn->state = STATE_ADDED;
+
+ if (conn->startup == STARTUP_START)
+ {
+ if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_initiate_conn(conn);
+ }
+ }
+ else
+ {
+ if (starter_pluto_pid())
+ {
+ starter_whack_initiate_conn(conn);
+ }
+ }
+ }
+ else if (conn->startup == STARTUP_ROUTE)
+ {
+ if (conn->keyexchange == KEY_EXCHANGE_IKEV2)
+ {
+ if (starter_charon_pid())
+ {
+ starter_stroke_route_conn(conn);
+ }
+ }
+ else
+ {
+ if (starter_pluto_pid())
+ {
+ starter_whack_route_conn(conn);
+ }
+ }
+ }
+ }
}
- }
}
- }
- }
- /*
- * If auto_update activated, when to stop select
- */
- if (auto_update)
- {
- time_t now = time(NULL);
+ /*
+ * If auto_update activated, when to stop select
+ */
+ if (auto_update)
+ {
+ time_t now = time(NULL);
- tv.tv_sec = (now < last_reload + auto_update)
- ? (last_reload + auto_update-now) : 0;
- tv.tv_usec = 0;
- }
+ tv.tv_sec = (now < last_reload + auto_update)
+ ? (last_reload + auto_update-now) : 0;
+ tv.tv_usec = 0;
+ }
- /*
- * Wait for something to happen
- */
- if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
- {
- /* timeout -> auto_update */
- _action_ |= FLAG_ACTION_UPDATE;
+ /*
+ * Wait for something to happen
+ */
+ if (select(0, NULL, NULL, NULL, auto_update ? &tv : NULL) == 0)
+ {
+ /* timeout -> auto_update */
+ _action_ |= FLAG_ACTION_UPDATE;
+ }
}
- }
- exit(LSB_RC_SUCCESS);
+ exit(LSB_RC_SUCCESS);
}
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index a1339f2a5..054e37fa7 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: starterstroke.c 4856 2009-02-05 22:13:48Z andreas $
*/
#include <sys/types.h>
@@ -21,10 +19,10 @@
#include <stddef.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#include <linux/xfrm.h>
#include <freeswan.h>
@@ -42,6 +40,15 @@
#define IPV6_LEN 16
/**
+ * Mode of an IPsec SA, must be the same as in charons kernel_ipsec.h
+ */
+enum ipsec_mode_t {
+ MODE_TRANSPORT = 1,
+ MODE_TUNNEL,
+ MODE_BEET
+};
+
+/**
* Authentication methods, must be the same as in charons authenticator.h
*/
enum auth_method_t {
@@ -68,9 +75,12 @@ static char* push_string(stroke_msg_t *msg, char *string)
static int send_stroke_msg (stroke_msg_t *msg)
{
- struct sockaddr_un ctl_addr = { AF_UNIX, CHARON_CTL_FILE };
+ struct sockaddr_un ctl_addr;
int byte_count;
char buffer[64];
+
+ ctl_addr.sun_family = AF_UNIX;
+ strcpy(ctl_addr.sun_path, CHARON_CTL_FILE);
/* starter is not called from commandline, and therefore absolutely silent */
msg->output_verbosity = -1;
@@ -164,9 +174,14 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
{
char buffer[INET6_ADDRSTRLEN];
+ msg_end->auth = push_string(msg, conn_end->auth);
+ msg_end->auth2 = push_string(msg, conn_end->auth2);
msg_end->id = push_string(msg, conn_end->id);
+ msg_end->id2 = push_string(msg, conn_end->id2);
msg_end->cert = push_string(msg, conn_end->cert);
+ msg_end->cert2 = push_string(msg, conn_end->cert2);
msg_end->ca = push_string(msg, conn_end->ca);
+ msg_end->ca2 = push_string(msg, conn_end->ca2);
msg_end->groups = push_string(msg, conn_end->groups);
msg_end->updown = push_string(msg, conn_end->updown);
ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
@@ -224,7 +239,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
msg.add_conn.name = push_string(&msg, connection_name(conn));
/* PUBKEY is preferred to PSK and EAP */
- if (conn->policy & POLICY_RSASIG || conn->policy & POLICY_ECDSASIG)
+ if (conn->policy & POLICY_PUBKEY)
{
msg.add_conn.auth_method = AUTH_PUBKEY;
}
@@ -242,20 +257,20 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
if (conn->policy & POLICY_TUNNEL)
{
- msg.add_conn.mode = XFRM_MODE_TUNNEL;
+ msg.add_conn.mode = MODE_TUNNEL;
}
else if (conn->policy & POLICY_BEET)
{
- msg.add_conn.mode = XFRM_MODE_BEET;
+ msg.add_conn.mode = MODE_BEET;
}
else if (conn->policy & POLICY_PROXY)
{
- msg.add_conn.mode = XFRM_MODE_TRANSPORT;
+ msg.add_conn.mode = MODE_TRANSPORT;
msg.add_conn.proxy_mode = TRUE;
}
else
{
- msg.add_conn.mode = XFRM_MODE_TRANSPORT;
+ msg.add_conn.mode = MODE_TRANSPORT;
}
if (!(conn->policy & POLICY_DONT_REKEY))
diff --git a/src/starter/starterstroke.h b/src/starter/starterstroke.h
index e6b9e5504..f9b01c99a 100644
--- a/src/starter/starterstroke.h
+++ b/src/starter/starterstroke.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: starterstroke.h 3825 2008-04-17 15:01:57Z martin $
*/
#ifndef _STARTER_STROKE_H_
diff --git a/src/starter/starterwhack.c b/src/starter/starterwhack.c
index 8b7d500b8..44b442ae2 100644
--- a/src/starter/starterwhack.c
+++ b/src/starter/starterwhack.c
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: starterwhack.c 3880 2008-04-27 10:49:31Z andreas $
*/
#include <sys/types.h>
@@ -19,6 +17,7 @@
#include <sys/un.h>
#include <stddef.h>
#include <unistd.h>
+#include <string.h>
#include <errno.h>
#include <freeswan.h>
@@ -32,386 +31,389 @@
#include "confread.h"
#include "files.h"
-#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
+#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static int
pack_str (char **p, char **next, char **roof)
{
- const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
- size_t len = strlen(s) + 1;
-
- if ((*roof - *next) < len)
- {
- return 0; /* not enough space */
- }
- else
- {
- strcpy(*next, s);
- *next += len;
- *p = NULL; /* don't send pointers on the wire! */
- return 1;
- }
+ const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
+ size_t len = strlen(s) + 1;
+
+ if ((*roof - *next) < len)
+ {
+ return 0; /* not enough space */
+ }
+ else
+ {
+ strcpy(*next, s);
+ *next += len;
+ *p = NULL; /* don't send pointers on the wire! */
+ return 1;
+ }
}
static int
send_whack_msg (whack_message_t *msg)
{
- struct sockaddr_un ctl_addr = { AF_UNIX, PLUTO_CTL_FILE };
- int sock;
- ssize_t len;
- char *str_next, *str_roof;
-
- /* pack strings */
- str_next = (char *)msg->string;
- str_roof = (char *)&msg->string[sizeof(msg->string)];
-
- if (!pack_str(&msg->name, &str_next, &str_roof)
- || !pack_str(&msg->left.id, &str_next, &str_roof)
- || !pack_str(&msg->left.cert, &str_next, &str_roof)
- || !pack_str(&msg->left.ca, &str_next, &str_roof)
- || !pack_str(&msg->left.groups, &str_next, &str_roof)
- || !pack_str(&msg->left.updown, &str_next, &str_roof)
- || !pack_str(&msg->left.virt, &str_next, &str_roof)
- || !pack_str(&msg->right.id, &str_next, &str_roof)
- || !pack_str(&msg->right.cert, &str_next, &str_roof)
- || !pack_str(&msg->right.ca, &str_next, &str_roof)
- || !pack_str(&msg->right.groups, &str_next, &str_roof)
- || !pack_str(&msg->right.updown, &str_next, &str_roof)
- || !pack_str(&msg->right.virt, &str_next, &str_roof)
- || !pack_str(&msg->keyid, &str_next, &str_roof)
- || !pack_str(&msg->myid, &str_next, &str_roof)
- || !pack_str(&msg->cacert, &str_next, &str_roof)
- || !pack_str(&msg->ldaphost, &str_next, &str_roof)
- || !pack_str(&msg->ldapbase, &str_next, &str_roof)
- || !pack_str(&msg->crluri, &str_next, &str_roof)
- || !pack_str(&msg->crluri2, &str_next, &str_roof)
- || !pack_str(&msg->ocspuri, &str_next, &str_roof)
- || !pack_str(&msg->ike, &str_next, &str_roof)
- || !pack_str(&msg->esp, &str_next, &str_roof)
- || !pack_str(&msg->sc_data, &str_next, &str_roof)
- || (str_roof - str_next < msg->keyval.len))
- {
- plog("send_wack_msg(): can't pack strings");
- return -1;
- }
- if (msg->keyval.ptr)
- memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
- msg->keyval.ptr = NULL;
- str_next += msg->keyval.len;
- len = str_next - (char *)msg;
-
- /* connect to pluto ctl */
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0)
- {
- plog("socket() failed: %s", strerror(errno));
- return -1;
- }
- if (connect(sock, (struct sockaddr *)&ctl_addr,
- offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
- {
- plog("connect(pluto_ctl) failed: %s", strerror(errno));
- close(sock);
- return -1;
- }
+ struct sockaddr_un ctl_addr;
+ int sock;
+ ssize_t len;
+ char *str_next, *str_roof;
+
+ ctl_addr.sun_family = AF_UNIX;
+ strcpy(ctl_addr.sun_path, PLUTO_CTL_FILE);
+
+ /* pack strings */
+ str_next = (char *)msg->string;
+ str_roof = (char *)&msg->string[sizeof(msg->string)];
+
+ if (!pack_str(&msg->name, &str_next, &str_roof)
+ || !pack_str(&msg->left.id, &str_next, &str_roof)
+ || !pack_str(&msg->left.cert, &str_next, &str_roof)
+ || !pack_str(&msg->left.ca, &str_next, &str_roof)
+ || !pack_str(&msg->left.groups, &str_next, &str_roof)
+ || !pack_str(&msg->left.updown, &str_next, &str_roof)
+ || !pack_str(&msg->left.virt, &str_next, &str_roof)
+ || !pack_str(&msg->right.id, &str_next, &str_roof)
+ || !pack_str(&msg->right.cert, &str_next, &str_roof)
+ || !pack_str(&msg->right.ca, &str_next, &str_roof)
+ || !pack_str(&msg->right.groups, &str_next, &str_roof)
+ || !pack_str(&msg->right.updown, &str_next, &str_roof)
+ || !pack_str(&msg->right.virt, &str_next, &str_roof)
+ || !pack_str(&msg->keyid, &str_next, &str_roof)
+ || !pack_str(&msg->myid, &str_next, &str_roof)
+ || !pack_str(&msg->cacert, &str_next, &str_roof)
+ || !pack_str(&msg->ldaphost, &str_next, &str_roof)
+ || !pack_str(&msg->ldapbase, &str_next, &str_roof)
+ || !pack_str(&msg->crluri, &str_next, &str_roof)
+ || !pack_str(&msg->crluri2, &str_next, &str_roof)
+ || !pack_str(&msg->ocspuri, &str_next, &str_roof)
+ || !pack_str(&msg->ike, &str_next, &str_roof)
+ || !pack_str(&msg->esp, &str_next, &str_roof)
+ || !pack_str(&msg->sc_data, &str_next, &str_roof)
+ || (str_roof - str_next < msg->keyval.len))
+ {
+ plog("send_wack_msg(): can't pack strings");
+ return -1;
+ }
+ if (msg->keyval.ptr)
+ memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
+ msg->keyval.ptr = NULL;
+ str_next += msg->keyval.len;
+ len = str_next - (char *)msg;
+
+ /* connect to pluto ctl */
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ plog("socket() failed: %s", strerror(errno));
+ return -1;
+ }
+ if (connect(sock, (struct sockaddr *)&ctl_addr,
+ offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
+ {
+ plog("connect(pluto_ctl) failed: %s", strerror(errno));
+ close(sock);
+ return -1;
+ }
- /* send message */
- if (write(sock, msg, len) != len)
- {
- plog("write(pluto_ctl) failed: %s", strerror(errno));
- close(sock);
- return -1;
- }
+ /* send message */
+ if (write(sock, msg, len) != len)
+ {
+ plog("write(pluto_ctl) failed: %s", strerror(errno));
+ close(sock);
+ return -1;
+ }
- /* TODO: read reply */
- close(sock);
- return 0;
+ /* TODO: read reply */
+ close(sock);
+ return 0;
}
static void
init_whack_msg(whack_message_t *msg)
{
- memset(msg, 0, sizeof(whack_message_t));
- msg->magic = WHACK_MAGIC;
+ memset(msg, 0, sizeof(whack_message_t));
+ msg->magic = WHACK_MAGIC;
}
static char *
connection_name(starter_conn_t *conn)
{
- /* if connection name is '%auto', create a new name like conn_xxxxx */
- static char buf[32];
-
- if (streq(conn->name, "%auto"))
- {
- sprintf(buf, "conn_%ld", conn->id);
- return buf;
- }
- return conn->name;
+ /* if connection name is '%auto', create a new name like conn_xxxxx */
+ static char buf[32];
+
+ if (streq(conn->name, "%auto"))
+ {
+ sprintf(buf, "conn_%ld", conn->id);
+ return buf;
+ }
+ return conn->name;
}
static void
set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
{
- if (end->srcip && end->srcip[0] != '%')
- {
- int len = 0;
- char *pos;
+ if (end->srcip && end->srcip[0] != '%')
+ {
+ int len = 0;
+ char *pos;
+
+ pos = strchr(end->srcip, '/');
+ if (pos)
+ {
+ /* use first address only for pluto */
+ len = pos - end->srcip;
+ }
+ w->has_srcip = !end->has_natip;
+ ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
+ }
+ else
+ {
+ anyaddr(AF_INET, &w->host_srcip);
+ }
+
+ w->id = end->id;
+ w->cert = end->cert;
+ w->ca = end->ca;
+ w->groups = end->groups;
+ w->host_addr = end->addr;
+ w->has_client = end->has_client;
+
+ if (family == AF_INET6 && isanyaddr(&end->nexthop))
+ {
+ anyaddr(AF_INET6, &end->nexthop);
+ }
+ w->host_nexthop = end->nexthop;
- pos = strchr(end->srcip, '/');
- if (pos)
+ if (w->has_client)
{
- /* use first address only for pluto */
- len = pos - end->srcip;
+ char *pos;
+ int len = 0;
+
+ pos = strchr(end->subnet, ',');
+ if (pos)
+ {
+ len = pos - end->subnet;
+ }
+ ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
}
- w->has_srcip = !end->has_natip;
- ttoaddr(end->srcip, len, ip_version(end->srcip), &w->host_srcip);
- }
- else
- {
- anyaddr(AF_INET, &w->host_srcip);
- }
-
- w->id = end->id;
- w->cert = end->cert;
- w->ca = end->ca;
- w->groups = end->groups;
- w->host_addr = end->addr;
- w->has_client = end->has_client;
-
- if (family == AF_INET6 && isanyaddr(&end->nexthop))
- {
- anyaddr(AF_INET6, &end->nexthop);
- }
- w->host_nexthop = end->nexthop;
-
- if (w->has_client)
- {
- char *pos;
- int len = 0;
-
- pos = strchr(end->subnet, ',');
- if (pos)
+ else
{
- len = pos - end->subnet;
+ if (end->has_virt)
+ {
+ w->virt = end->subnet;
+ }
+ w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
}
- ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
- }
- else
- {
- if (end->has_virt)
+
+ w->has_client_wildcard = end->has_client_wildcard;
+ w->has_port_wildcard = end->has_port_wildcard;
+ w->has_natip = end->has_natip;
+ w->allow_any = end->allow_any && !end->dns_failed;
+ w->modecfg = end->modecfg;
+ w->hostaccess = end->hostaccess;
+ w->sendcert = end->sendcert;
+ w->updown = end->updown;
+ w->host_port = IKE_UDP_PORT;
+ w->port = end->port;
+ w->protocol = end->protocol;
+
+ if (w->port != 0)
{
- w->virt = end->subnet;
+ int port = htons(w->port);
+
+ setportof(port, &w->host_addr);
+ setportof(port, &w->client.addr);
}
- w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
- }
-
- w->has_client_wildcard = end->has_client_wildcard;
- w->has_port_wildcard = end->has_port_wildcard;
- w->has_natip = end->has_natip;
- w->allow_any = end->allow_any && !end->dns_failed;
- w->modecfg = end->modecfg;
- w->hostaccess = end->hostaccess;
- w->sendcert = end->sendcert;
- w->updown = end->updown;
- w->host_port = IKE_UDP_PORT;
- w->port = end->port;
- w->protocol = end->protocol;
-
- if (w->port != 0)
- {
- int port = htons(w->port);
-
- setportof(port, &w->host_addr);
- setportof(port, &w->client.addr);
- }
}
static int
starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
, const char *lr)
{
- const char *err;
- static char keyspace[1024 + 4];
- whack_message_t msg;
-
- init_whack_msg(&msg);
-
- msg.whack_key = TRUE;
- msg.pubkey_alg = PUBKEY_ALG_RSA;
- if (end->id && end->rsakey)
- {
- /* special values to ignore */
- if (streq(end->rsakey, "")
- || streq(end->rsakey, "%none")
- || streq(end->rsakey, "%cert")
- || streq(end->rsakey, "0x00"))
- {
- return 0;
- }
- msg.keyid = end->id;
- err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
- if (err)
- {
- plog("conn %s/%s: rsakey malformed [%s]", connection_name(conn), lr, err);
- return 1;
- }
- else
+ const char *err;
+ static char keyspace[1024 + 4];
+ whack_message_t msg;
+
+ init_whack_msg(&msg);
+
+ msg.whack_key = TRUE;
+ msg.pubkey_alg = PUBKEY_ALG_RSA;
+ if (end->id && end->rsakey)
{
- msg.keyval.ptr = keyspace;
- return send_whack_msg(&msg);
+ /* special values to ignore */
+ if (streq(end->rsakey, "")
+ || streq(end->rsakey, "%none")
+ || streq(end->rsakey, "%cert")
+ || streq(end->rsakey, "0x00"))
+ {
+ return 0;
+ }
+ msg.keyid = end->id;
+ err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
+ if (err)
+ {
+ plog("conn %s/%s: rsakey malformed [%s]", connection_name(conn), lr, err);
+ return 1;
+ }
+ else
+ {
+ msg.keyval.ptr = keyspace;
+ return send_whack_msg(&msg);
+ }
}
- }
- return 0;
+ return 0;
}
int
starter_whack_add_conn(starter_conn_t *conn)
{
- whack_message_t msg;
- int r;
-
- init_whack_msg(&msg);
-
- msg.whack_connection = TRUE;
- msg.name = connection_name(conn);
-
- msg.ikev1 = conn->keyexchange != KEY_EXCHANGE_IKEV2;
- msg.addr_family = conn->addr_family;
- msg.tunnel_addr_family = conn->tunnel_addr_family;
- msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
- msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
- msg.sa_rekey_margin = conn->sa_rekey_margin;
- msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
- msg.sa_keying_tries = conn->sa_keying_tries;
- msg.policy = conn->policy;
-
- /*
- * Make sure the IKEv2-only policy bits are unset for IKEv1 connections
- */
- msg.policy &= ~POLICY_DONT_REAUTH;
- msg.policy &= ~POLICY_BEET;
- msg.policy &= ~POLICY_MOBIKE;
- msg.policy &= ~POLICY_FORCE_ENCAP;
-
- set_whack_end(&msg.left, &conn->left, conn->addr_family);
- set_whack_end(&msg.right, &conn->right, conn->addr_family);
-
- msg.esp = conn->esp;
- msg.ike = conn->ike;
- msg.pfsgroup = conn->pfsgroup;
-
- /* taken from pluto/whack.c */
- if (msg.pfsgroup)
- {
- char esp_buf[256];
-
- snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
- , msg.esp ? msg.esp : ""
- , msg.pfsgroup ? msg.pfsgroup : "");
- msg.esp = esp_buf;
-
- DBG(DBG_CONTROL,
- DBG_log("Setting --esp=%s", msg.esp)
- )
- }
- msg.dpd_delay = conn->dpd_delay;
- msg.dpd_timeout = conn->dpd_timeout;
- msg.dpd_action = conn->dpd_action;
+ whack_message_t msg;
+ int r;
+
+ init_whack_msg(&msg);
+
+ msg.whack_connection = TRUE;
+ msg.name = connection_name(conn);
+
+ msg.ikev1 = conn->keyexchange != KEY_EXCHANGE_IKEV2;
+ msg.addr_family = conn->addr_family;
+ msg.tunnel_addr_family = conn->tunnel_addr_family;
+ msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
+ msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
+ msg.sa_rekey_margin = conn->sa_rekey_margin;
+ msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
+ msg.sa_keying_tries = conn->sa_keying_tries;
+ msg.policy = conn->policy;
+
+ /*
+ * Make sure the IKEv2-only policy bits are unset for IKEv1 connections
+ */
+ msg.policy &= ~POLICY_DONT_REAUTH;
+ msg.policy &= ~POLICY_BEET;
+ msg.policy &= ~POLICY_MOBIKE;
+ msg.policy &= ~POLICY_FORCE_ENCAP;
+
+ set_whack_end(&msg.left, &conn->left, conn->addr_family);
+ set_whack_end(&msg.right, &conn->right, conn->addr_family);
+
+ msg.esp = conn->esp;
+ msg.ike = conn->ike;
+ msg.pfsgroup = conn->pfsgroup;
+
+ /* taken from pluto/whack.c */
+ if (msg.pfsgroup)
+ {
+ char esp_buf[256];
+
+ snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
+ , msg.esp ? msg.esp : ""
+ , msg.pfsgroup ? msg.pfsgroup : "");
+ msg.esp = esp_buf;
+
+ DBG(DBG_CONTROL,
+ DBG_log("Setting --esp=%s", msg.esp)
+ )
+ }
+ msg.dpd_delay = conn->dpd_delay;
+ msg.dpd_timeout = conn->dpd_timeout;
+ msg.dpd_action = conn->dpd_action;
/* msg.dpd_count = conn->dpd_count; not supported yet by strongSwan */
- r = send_whack_msg(&msg);
+ r = send_whack_msg(&msg);
- if (r == 0 && (conn->policy & POLICY_RSASIG))
- {
- r += starter_whack_add_pubkey (conn, &conn->left, "left");
- r += starter_whack_add_pubkey (conn, &conn->right, "right");
- }
+ if (r == 0 && (conn->policy & POLICY_PUBKEY))
+ {
+ r += starter_whack_add_pubkey (conn, &conn->left, "left");
+ r += starter_whack_add_pubkey (conn, &conn->right, "right");
+ }
- return r;
+ return r;
}
int
starter_whack_del_conn(starter_conn_t *conn)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_delete = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
+ init_whack_msg(&msg);
+ msg.whack_delete = TRUE;
+ msg.name = connection_name(conn);
+ return send_whack_msg(&msg);
}
int
starter_whack_route_conn(starter_conn_t *conn)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_route = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
+ init_whack_msg(&msg);
+ msg.whack_route = TRUE;
+ msg.name = connection_name(conn);
+ return send_whack_msg(&msg);
}
int
starter_whack_initiate_conn(starter_conn_t *conn)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_initiate = TRUE;
- msg.whack_async = TRUE;
- msg.name = connection_name(conn);
- return send_whack_msg(&msg);
+ init_whack_msg(&msg);
+ msg.whack_initiate = TRUE;
+ msg.whack_async = TRUE;
+ msg.name = connection_name(conn);
+ return send_whack_msg(&msg);
}
int
starter_whack_listen(void)
{
- whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_listen = TRUE;
- return send_whack_msg(&msg);
+ whack_message_t msg;
+ init_whack_msg(&msg);
+ msg.whack_listen = TRUE;
+ return send_whack_msg(&msg);
}
int starter_whack_shutdown(void)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
- msg.whack_shutdown = TRUE;
- return send_whack_msg(&msg);
+ init_whack_msg(&msg);
+ msg.whack_shutdown = TRUE;
+ return send_whack_msg(&msg);
}
int
starter_whack_add_ca(starter_ca_t *ca)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
+ init_whack_msg(&msg);
- msg.whack_ca = TRUE;
- msg.name = ca->name;
- msg.cacert = ca->cacert;
- msg.ldaphost = ca->ldaphost;
- msg.ldapbase = ca->ldapbase;
- msg.crluri = ca->crluri;
- msg.crluri2 = ca->crluri2;
- msg.ocspuri = ca->ocspuri;
- msg.whack_strict = ca->strict;
+ msg.whack_ca = TRUE;
+ msg.name = ca->name;
+ msg.cacert = ca->cacert;
+ msg.ldaphost = ca->ldaphost;
+ msg.ldapbase = ca->ldapbase;
+ msg.crluri = ca->crluri;
+ msg.crluri2 = ca->crluri2;
+ msg.ocspuri = ca->ocspuri;
+ msg.whack_strict = ca->strict;
- return send_whack_msg(&msg);
+ return send_whack_msg(&msg);
}
int
starter_whack_del_ca(starter_ca_t *ca)
{
- whack_message_t msg;
+ whack_message_t msg;
- init_whack_msg(&msg);
+ init_whack_msg(&msg);
- msg.whack_delete = TRUE;
- msg.whack_ca = TRUE;
- msg.name = ca->name;
+ msg.whack_delete = TRUE;
+ msg.whack_ca = TRUE;
+ msg.name = ca->name;
- return send_whack_msg(&msg);
+ return send_whack_msg(&msg);
}
diff --git a/src/starter/starterwhack.h b/src/starter/starterwhack.h
index 7acc75ec0..d56b02421 100644
--- a/src/starter/starterwhack.h
+++ b/src/starter/starterwhack.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: starterwhack.h 3267 2007-10-08 19:57:54Z andreas $
*/
#ifndef _STARTER_WHACK_H_
diff --git a/src/starter/y.tab.c b/src/starter/y.tab.c
index 87abc5c33..b78c1b1f9 100644
--- a/src/starter/y.tab.c
+++ b/src/starter/y.tab.c
@@ -94,7 +94,7 @@
/* Copy the first part of user declarations. */
-#line 1 "parser.y"
+#line 1 "./parser.y"
/* strongSwan config file parser (parser.y)
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
@@ -108,8 +108,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: parser.y 3267 2007-10-08 19:57:54Z andreas $
*/
#include <stdio.h>
@@ -124,7 +122,7 @@
#include "parser.h"
#define YYERROR_VERBOSE
-#define ERRSTRING_LEN 256
+#define ERRSTRING_LEN 256
/**
* Bison
@@ -170,10 +168,10 @@ extern kw_entry_t *in_word_set (char *str, unsigned int len);
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 56 "parser.y"
+#line 54 "./parser.y"
{ char *s; }
/* Line 187 of yacc.c. */
-#line 177 "y.tab.c"
+#line 175 "y.tab.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -186,7 +184,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 190 "y.tab.c"
+#line 188 "y.tab.c"
#ifdef short
# undef short
@@ -474,8 +472,8 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 67, 67, 68, 72, 77, 76, 82, 81, 99,
- 98, 115, 114, 120, 124, 125, 129, 154, 158
+ 0, 65, 65, 66, 70, 75, 74, 80, 79, 96,
+ 95, 111, 110, 116, 120, 121, 125, 150, 154
};
#endif
@@ -1390,106 +1388,104 @@ yyreduce:
switch (yyn)
{
case 4:
-#line 73 "parser.y"
+#line 71 "./parser.y"
{
- free((yyvsp[(2) - (3)].s));
- }
+ free((yyvsp[(2) - (3)].s));
+ }
break;
case 5:
-#line 77 "parser.y"
+#line 75 "./parser.y"
{
- _parser_kw = &(_parser_cfg->config_setup);
- _parser_kw_last = NULL;
- }
+ _parser_kw = &(_parser_cfg->config_setup);
+ _parser_kw_last = NULL;
+ }
break;
case 7:
-#line 82 "parser.y"
+#line 80 "./parser.y"
{
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
-
- section->name = clone_str((yyvsp[(2) - (3)].s), "conn section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->conn_first)
- _parser_cfg->conn_first = section;
- if (_parser_cfg->conn_last)
- _parser_cfg->conn_last->next = section;
- _parser_cfg->conn_last = section;
- _parser_kw_last = NULL;
- free((yyvsp[(2) - (3)].s));
- }
+ section_list_t *section = malloc_thing(section_list_t);
+
+ section->name = clone_str((yyvsp[(2) - (3)].s));
+ section->kw = NULL;
+ section->next = NULL;
+ _parser_kw = &(section->kw);
+ if (!_parser_cfg->conn_first)
+ _parser_cfg->conn_first = section;
+ if (_parser_cfg->conn_last)
+ _parser_cfg->conn_last->next = section;
+ _parser_cfg->conn_last = section;
+ _parser_kw_last = NULL;
+ free((yyvsp[(2) - (3)].s));
+ }
break;
case 9:
-#line 99 "parser.y"
+#line 96 "./parser.y"
{
- section_list_t *section = (section_list_t *)alloc_thing(section_list_t
- , "section_list_t");
- section->name = clone_str((yyvsp[(2) - (3)].s), "ca section name");
- section->kw = NULL;
- section->next = NULL;
- _parser_kw = &(section->kw);
- if (!_parser_cfg->ca_first)
- _parser_cfg->ca_first = section;
- if (_parser_cfg->ca_last)
- _parser_cfg->ca_last->next = section;
- _parser_cfg->ca_last = section;
- _parser_kw_last = NULL;
- free((yyvsp[(2) - (3)].s));
- }
+ section_list_t *section = malloc_thing(section_list_t);
+ section->name = clone_str((yyvsp[(2) - (3)].s));
+ section->kw = NULL;
+ section->next = NULL;
+ _parser_kw = &(section->kw);
+ if (!_parser_cfg->ca_first)
+ _parser_cfg->ca_first = section;
+ if (_parser_cfg->ca_last)
+ _parser_cfg->ca_last->next = section;
+ _parser_cfg->ca_last = section;
+ _parser_kw_last = NULL;
+ free((yyvsp[(2) - (3)].s));
+ }
break;
case 11:
-#line 115 "parser.y"
+#line 111 "./parser.y"
{
- extern void _parser_y_include (const char *f);
- _parser_y_include((yyvsp[(2) - (2)].s));
- free((yyvsp[(2) - (2)].s));
- }
+ extern void _parser_y_include (const char *f);
+ _parser_y_include((yyvsp[(2) - (2)].s));
+ free((yyvsp[(2) - (2)].s));
+ }
break;
case 16:
-#line 130 "parser.y"
+#line 126 "./parser.y"
{
- kw_list_t *new;
- kw_entry_t *entry = in_word_set((yyvsp[(1) - (3)].s), strlen((yyvsp[(1) - (3)].s)));
+ kw_list_t *new;
+ kw_entry_t *entry = in_word_set((yyvsp[(1) - (3)].s), strlen((yyvsp[(1) - (3)].s)));
- if (entry == NULL)
- {
- snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", (yyvsp[(1) - (3)].s));
- yyerror(errbuf);
- }
- else if (_parser_kw)
- {
- new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
- new->entry = entry;
- new->value = clone_str((yyvsp[(3) - (3)].s), "kw_list value");
- new->next = NULL;
- if (_parser_kw_last)
- _parser_kw_last->next = new;
- _parser_kw_last = new;
- if (!*_parser_kw)
- *_parser_kw = new;
+ if (entry == NULL)
+ {
+ snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", (yyvsp[(1) - (3)].s));
+ yyerror(errbuf);
+ }
+ else if (_parser_kw)
+ {
+ new = (kw_list_t *)malloc_thing(kw_list_t);
+ new->entry = entry;
+ new->value = clone_str((yyvsp[(3) - (3)].s));
+ new->next = NULL;
+ if (_parser_kw_last)
+ _parser_kw_last->next = new;
+ _parser_kw_last = new;
+ if (!*_parser_kw)
+ *_parser_kw = new;
+ }
+ free((yyvsp[(1) - (3)].s));
+ free((yyvsp[(3) - (3)].s));
}
- free((yyvsp[(1) - (3)].s));
- free((yyvsp[(3) - (3)].s));
- }
break;
case 17:
-#line 155 "parser.y"
+#line 151 "./parser.y"
{
- free((yyvsp[(1) - (2)].s));
- }
+ free((yyvsp[(1) - (2)].s));
+ }
break;
/* Line 1267 of yacc.c. */
-#line 1493 "y.tab.c"
+#line 1489 "y.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1703,128 +1699,125 @@ yyreturn:
}
-#line 161 "parser.y"
+#line 157 "./parser.y"
void
yyerror(const char *s)
{
- if (_save_errors_)
- _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
+ if (_save_errors_)
+ _parser_y_error(parser_errstring, ERRSTRING_LEN, s);
}
config_parsed_t *
parser_load_conf(const char *file)
{
- config_parsed_t *cfg = NULL;
- int err = 0;
- FILE *f;
+ config_parsed_t *cfg = NULL;
+ int err = 0;
+ FILE *f;
- extern void _parser_y_init (const char *f);
- extern FILE *yyin;
+ extern void _parser_y_init (const char *f);
+ extern FILE *yyin;
- memset(parser_errstring, 0, ERRSTRING_LEN+1);
+ memset(parser_errstring, 0, ERRSTRING_LEN+1);
- cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
- if (cfg)
- {
- memset(cfg, 0, sizeof(config_parsed_t));
- f = fopen(file, "r");
- if (f)
+ cfg = (config_parsed_t *)malloc_thing(config_parsed_t);
+ if (cfg)
{
- yyin = f;
- _parser_y_init(file);
- _save_errors_ = 1;
- _parser_cfg = cfg;
-
- if (yyparse() !=0 )
- {
- if (parser_errstring[0] == '\0')
+ memset(cfg, 0, sizeof(config_parsed_t));
+ f = fopen(file, "r");
+ if (f)
{
- snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
+ yyin = f;
+ _parser_y_init(file);
+ _save_errors_ = 1;
+ _parser_cfg = cfg;
+
+ if (yyparse() !=0 )
+ {
+ if (parser_errstring[0] == '\0')
+ {
+ snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
+ }
+ _save_errors_ = 0;
+ while (yyparse() != 0);
+ err++;
+ }
+ else if (parser_errstring[0] != '\0')
+ {
+ err++;
+ }
+ else
+ {
+ /**
+ * Config valid
+ */
+ }
+
+ fclose(f);
+ }
+ else
+ {
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
+ err++;
}
- _save_errors_ = 0;
- while (yyparse() != 0);
- err++;
- }
- else if (parser_errstring[0] != '\0')
- {
- err++;
- }
- else
- {
- /**
- * Config valid
- */
- }
-
- fclose(f);
}
else
{
- snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
- err++;
+ snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
+ err++;
}
- }
- else
- {
- snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
- err++;
- }
- if (err)
- {
- plog("%s", parser_errstring);
+ if (err)
+ {
+ plog("%s", parser_errstring);
- if (cfg)
- parser_free_conf(cfg);
- cfg = NULL;
- }
+ if (cfg)
+ parser_free_conf(cfg);
+ cfg = NULL;
+ }
- return cfg;
+ return cfg;
}
static void
parser_free_kwlist(kw_list_t *list)
{
- kw_list_t *elt;
+ kw_list_t *elt;
- while (list)
- {
- elt = list;
- list = list->next;
- if (elt->value)
- pfree(elt->value);
- pfree(elt);
- }
+ while (list)
+ {
+ elt = list;
+ list = list->next;
+ free(elt->value);
+ free(elt);
+ }
}
void
parser_free_conf(config_parsed_t *cfg)
{
- section_list_t *sec;
- if (cfg)
- {
- parser_free_kwlist(cfg->config_setup);
- while (cfg->conn_first)
- {
- sec = cfg->conn_first;
- cfg->conn_first = cfg->conn_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
- }
- while (cfg->ca_first)
+ section_list_t *sec;
+ if (cfg)
{
- sec = cfg->ca_first;
- cfg->ca_first = cfg->ca_first->next;
- if (sec->name)
- pfree(sec->name);
- parser_free_kwlist(sec->kw);
- pfree(sec);
+ parser_free_kwlist(cfg->config_setup);
+ while (cfg->conn_first)
+ {
+ sec = cfg->conn_first;
+ cfg->conn_first = cfg->conn_first->next;
+ free(sec->name);
+ parser_free_kwlist(sec->kw);
+ free(sec);
+ }
+ while (cfg->ca_first)
+ {
+ sec = cfg->ca_first;
+ cfg->ca_first = cfg->ca_first->next;
+ free(sec->name);
+ parser_free_kwlist(sec->kw);
+ free(sec);
+ }
+ free(cfg);
}
- pfree(cfg);
- }
}
diff --git a/src/starter/y.tab.h b/src/starter/y.tab.h
index 1cf56de3a..871de1e97 100644
--- a/src/starter/y.tab.h
+++ b/src/starter/y.tab.h
@@ -68,7 +68,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 56 "parser.y"
+#line 54 "./parser.y"
{ char *s; }
/* Line 1489 of yacc.c. */
#line 75 "y.tab.h"
diff --git a/src/stroke/Makefile.am b/src/stroke/Makefile.am
index df20252e2..afca95fce 100644
--- a/src/stroke/Makefile.am
+++ b/src/stroke/Makefile.am
@@ -3,8 +3,9 @@ ipsec_PROGRAMS = stroke
stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
INCLUDES = -I$(top_srcdir)/src/libstrongswan
EXTRA_DIST = stroke_keywords.txt
+BUILT_SOURCES = stroke_keywords.c
MAINTAINERCLEANFILES = stroke_keywords.c
AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
-stroke_keywords.c: stroke_keywords.txt stroke_keywords.h
- $(GPERF) -C -G -t < $< > $@
+stroke_keywords.c: $(srcdir)/stroke_keywords.txt $(srcdir)/stroke_keywords.h
+ $(GPERF) -m 10 -D -C -G -t < $(srcdir)/stroke_keywords.txt > $@
diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in
index 0d78d9425..dde80348e 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -79,6 +79,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -101,6 +102,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -112,6 +116,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -125,6 +130,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -185,6 +192,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -196,6 +204,7 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
@@ -203,9 +212,11 @@ xml_LIBS = @xml_LIBS@
stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
INCLUDES = -I$(top_srcdir)/src/libstrongswan
EXTRA_DIST = stroke_keywords.txt
+BUILT_SOURCES = stroke_keywords.c
MAINTAINERCLEANFILES = stroke_keywords.c
AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
-all: all-am
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -213,8 +224,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -311,7 +322,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -380,13 +391,15 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
-check: check-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
-install: install-am
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@@ -410,6 +423,7 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
@@ -487,8 +501,8 @@ uninstall-am: uninstall-ipsecPROGRAMS
tags uninstall uninstall-am uninstall-ipsecPROGRAMS
-stroke_keywords.c: stroke_keywords.txt stroke_keywords.h
- $(GPERF) -C -G -t < $< > $@
+stroke_keywords.c: $(srcdir)/stroke_keywords.txt $(srcdir)/stroke_keywords.h
+ $(GPERF) -m 10 -D -C -G -t < $(srcdir)/stroke_keywords.txt > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index 01cbcb5b0..c27a8ca3e 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: stroke.c 4783 2008-12-10 13:00:02Z martin $
*/
#include <stdlib.h>
@@ -27,6 +25,7 @@
#include <errno.h>
#include <stdio.h>
#include <stddef.h>
+#include <string.h>
#include "stroke_msg.h"
#include "stroke_keywords.h"
@@ -54,10 +53,13 @@ static char* push_string(stroke_msg_t *msg, char *string)
static int send_stroke_msg (stroke_msg_t *msg)
{
- struct sockaddr_un ctl_addr = { AF_UNIX, STROKE_SOCKET };
+ struct sockaddr_un ctl_addr;
int sock;
char buffer[64];
int byte_count;
+
+ ctl_addr.sun_family = AF_UNIX;
+ strcpy(ctl_addr.sun_path, STROKE_SOCKET);
msg->output_verbosity = 1; /* CONTROL */
@@ -246,7 +248,8 @@ static int reread(stroke_keyword_t kw)
}
static int purge_flags[] = {
- PURGE_OCSP
+ PURGE_OCSP,
+ PURGE_IKE,
};
static int purge(stroke_keyword_t kw)
@@ -330,6 +333,8 @@ static void exit_usage(char *error)
printf(" stroke rereadsecrets|rereadcrls|rereadall\n");
printf(" Purge ocsp cache entries:\n");
printf(" stroke purgeocsp\n");
+ printf(" Purge IKE_SAs without a CHILD_SA:\n");
+ printf(" stroke purgeike\n");
printf(" Show leases of a pool:\n");
printf(" stroke leases [POOL [ADDRESS]]\n");
exit_error(error);
@@ -441,6 +446,7 @@ int main(int argc, char *argv[])
res = reread(token->kw);
break;
case STROKE_PURGE_OCSP:
+ case STROKE_PURGE_IKE:
res = purge(token->kw);
break;
case STROKE_LEASES:
diff --git a/src/stroke/stroke_keywords.c b/src/stroke/stroke_keywords.c
index a5d17edc2..bb9705743 100644
--- a/src/stroke/stroke_keywords.c
+++ b/src/stroke/stroke_keywords.c
@@ -1,5 +1,5 @@
/* C code produced by gperf version 3.0.3 */
-/* Command-line: /usr/bin/gperf -C -G -t */
+/* Command-line: /usr/bin/gperf -m 10 -D -C -G -t */
/* Computed positions: -k'1,5,7' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -43,8 +43,6 @@ error "gperf generated tables don't work with this execution character set. Plea
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: stroke_keywords.txt 4783 2008-12-10 13:00:02Z martin $
*/
#include <string.h>
@@ -56,12 +54,12 @@ struct stroke_token {
stroke_keyword_t kw;
};
-#define TOTAL_KEYWORDS 32
+#define TOTAL_KEYWORDS 33
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 15
#define MIN_HASH_VALUE 3
-#define MAX_HASH_VALUE 65
-/* maximum key range = 63, duplicates = 0 */
+#define MAX_HASH_VALUE 39
+/* maximum key range = 37, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -77,32 +75,32 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 0, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 0, 0, 5,
- 45, 0, 66, 10, 66, 15, 66, 66, 0, 66,
- 66, 20, 0, 66, 10, 10, 0, 10, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 66, 66
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 17, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 0, 4, 1,
+ 1, 0, 40, 17, 40, 18, 40, 4, 0, 40,
+ 40, 12, 17, 40, 6, 3, 19, 12, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40
};
register int hval = len;
@@ -127,53 +125,46 @@ hash (str, len)
static const struct stroke_token wordlist[] =
{
- {""}, {""}, {""},
{"add", STROKE_ADD},
- {""}, {""},
+ {"del", STROKE_DEL},
+ {"down", STROKE_DOWN},
{"leases", STROKE_LEASES},
{"listall", STROKE_LIST_ALL},
{"loglevel", STROKE_LOGLEVEL},
- {""},
- {"listacerts", STROKE_LIST_ACERTS},
- {"listpubkeys", STROKE_LIST_PUBKEYS},
- {"up", STROKE_UP},
{"listcrls", STROKE_LIST_CRLS},
- {"purgeocsp", STROKE_PURGE_OCSP},
+ {"listacerts", STROKE_LIST_ACERTS},
{"route", STROKE_ROUTE},
{"listaacerts", STROKE_LIST_AACERTS},
- {""},
- {"listalgs", STROKE_LIST_ALGS},
- {"rereadall", STROKE_REREAD_ALL},
- {""},
{"listcacerts", STROKE_LIST_CACERTS},
- {"rereadacerts", STROKE_REREAD_ACERTS},
- {"rereadaacerts", STROKE_REREAD_AACERTS},
+ {"up", STROKE_UP},
+ {"rereadall", STROKE_REREAD_ALL},
{"listcerts", STROKE_LIST_CERTS},
{"rereadcrls", STROKE_REREAD_CRLS},
- {"status", STROKE_STATUS},
- {"unroute", STROKE_UNROUTE},
+ {"rereadacerts", STROKE_REREAD_ACERTS},
+ {"rereadaacerts", STROKE_REREAD_AACERTS},
{"rereadcacerts", STROKE_REREAD_CACERTS},
- {"statusall", STROKE_STATUSALL},
- {""},
- {"listcainfos", STROKE_LIST_CAINFOS},
- {""},
+ {"status", STROKE_STATUS},
{"rereadsecrets", STROKE_REREAD_SECRETS},
- {""}, {""}, {""}, {""},
{"listocsp", STROKE_LIST_OCSP},
- {""},
- {"listgroups", STROKE_LIST_GROUPS},
- {""}, {""},
+ {"statusall", STROKE_STATUSALL},
+ {"listalgs", STROKE_LIST_ALGS},
+ {"delete", STROKE_DELETE},
+ {"purgeocsp", STROKE_PURGE_OCSP},
{"listocspcerts", STROKE_LIST_OCSPCERTS},
- {""},
+ {"purgeike", STROKE_PURGE_IKE},
+ {"listcainfos", STROKE_LIST_CAINFOS},
+ {"unroute", STROKE_UNROUTE},
+ {"listpubkeys", STROKE_LIST_PUBKEYS},
{"rereadocspcerts", STROKE_REREAD_OCSPCERTS},
- {""}, {""},
- {"del", STROKE_DEL},
- {"down", STROKE_DOWN},
- {""},
- {"delete", STROKE_DELETE},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""}, {""}, {""}, {""},
- {"down-srcip", STROKE_DOWN_SRCIP}
+ {"down-srcip", STROKE_DOWN_SRCIP},
+ {"listgroups", STROKE_LIST_GROUPS}
+ };
+
+static const short lookup[] =
+ {
+ -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, 32
};
#ifdef __GNUC__
@@ -193,10 +184,15 @@ in_word_set (str, len)
if (key <= MAX_HASH_VALUE && key >= 0)
{
- register const char *s = wordlist[key].name;
+ register int index = lookup[key];
+
+ if (index >= 0)
+ {
+ register const char *s = wordlist[index].name;
- if (*str == *s && !strcmp (str + 1, s + 1))
- return &wordlist[key];
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return &wordlist[index];
+ }
}
}
return 0;
diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h
index e089b5660..6332000db 100644
--- a/src/stroke/stroke_keywords.h
+++ b/src/stroke/stroke_keywords.h
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: stroke_keywords.h 4783 2008-12-10 13:00:02Z martin $
*/
#ifndef _STROKE_KEYWORDS_H_
@@ -50,6 +48,7 @@ typedef enum {
STROKE_REREAD_CRLS,
STROKE_REREAD_ALL,
STROKE_PURGE_OCSP,
+ STROKE_PURGE_IKE,
STROKE_LEASES
} stroke_keyword_t;
diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt
index 3ec259a24..96fa0bf3a 100644
--- a/src/stroke/stroke_keywords.txt
+++ b/src/stroke/stroke_keywords.txt
@@ -12,8 +12,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: stroke_keywords.txt 4783 2008-12-10 13:00:02Z martin $
*/
#include <string.h>
@@ -57,4 +55,5 @@ rereadacerts, STROKE_REREAD_ACERTS
rereadcrls, STROKE_REREAD_CRLS
rereadall, STROKE_REREAD_ALL
purgeocsp, STROKE_PURGE_OCSP
+purgeike, STROKE_PURGE_IKE
leases, STROKE_LEASES
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 81ad2e397..704c88c58 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -18,8 +18,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: stroke_msg.h 4783 2008-12-10 13:00:02Z martin $
*/
#ifndef STROKE_MSG_H_
@@ -105,6 +103,8 @@ enum purge_flag_t {
PURGE_NONE = 0x0000,
/** purge ocsp cache entries */
PURGE_OCSP = 0x0001,
+ /** purge IKE_SAs without a CHILD_SA */
+ PURGE_IKE = 0x0002,
};
/**
@@ -123,9 +123,15 @@ typedef struct stroke_end_t stroke_end_t;
* definition of a peer in a stroke message
*/
struct stroke_end_t {
+ char *auth;
+ char *auth2;
char *id;
+ char *id2;
+ char *eap_id;
char *cert;
+ char *cert2;
char *ca;
+ char *ca2;
char *groups;
char *updown;
char *address;
@@ -206,6 +212,7 @@ struct stroke_msg_t {
struct {
char *name;
int ikev2;
+ /* next three are deprecated, use stroke_end_t.auth instead */
int auth_method;
u_int32_t eap_type;
u_int32_t eap_vendor;
diff --git a/src/strongswan.conf b/src/strongswan.conf
index 661792a67..0ec4ae9ef 100644
--- a/src/strongswan.conf
+++ b/src/strongswan.conf
@@ -6,12 +6,11 @@ charon {
threads = 16
# plugins to load in charon
- # load = aes des gmp hmac md5 random sha1 sha2 pubkey xcbc x509 stroke
+ # load = aes des sha1 md5 sha2 hmac gmp random pubkey xcbc x509 stroke
plugins {
-
+
sql {
-
# loglevel to log into sql database
loglevel = -1
@@ -23,3 +22,16 @@ charon {
# ...
}
+
+pluto {
+
+ # plugins to load in pluto
+ # load = aes des sha1 md5 sha2 hmac gmp random pubkey
+
+}
+
+libstrongswan {
+
+ # set to no, the DH exponent size is optimized
+ # dh_exponent_ansi_x9_42 = no
+}
diff --git a/src/whack/Makefile.am b/src/whack/Makefile.am
index 985245026..27f856231 100644
--- a/src/whack/Makefile.am
+++ b/src/whack/Makefile.am
@@ -1,8 +1,15 @@
ipsec_PROGRAMS = whack
whack_SOURCES = whack.c whack.h
-INCLUDES = -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto
-whack_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
+
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto
+
+whack_LDADD = \
+$(top_builddir)/src/libstrongswan/libstrongswan.la \
+$(top_builddir)/src/libfreeswan/libfreeswan.a
AM_CFLAGS = -DDEBUG
diff --git a/src/whack/Makefile.in b/src/whack/Makefile.in
index 5c9762cd3..7e2be4d1b 100644
--- a/src/whack/Makefile.in
+++ b/src/whack/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -46,7 +46,9 @@ ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am_whack_OBJECTS = whack.$(OBJEXT)
whack_OBJECTS = $(am_whack_OBJECTS)
-whack_DEPENDENCIES = $(top_builddir)/src/libfreeswan/libfreeswan.a
+whack_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libfreeswan/libfreeswan.a
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -79,6 +81,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -101,6 +104,9 @@ LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
@@ -112,6 +118,7 @@ MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
@@ -125,6 +132,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -185,6 +194,7 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -196,13 +206,21 @@ srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
whack_SOURCES = whack.c whack.h
-INCLUDES = -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto
-whack_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto
+
+whack_LDADD = \
+$(top_builddir)/src/libstrongswan/libstrongswan.la \
+$(top_builddir)/src/libfreeswan/libfreeswan.a
+
AM_CFLAGS = -DDEBUG
all: all-am
@@ -212,8 +230,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -309,7 +327,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/src/whack/whack.c b/src/whack/whack.c
index a4236a8b4..28112500e 100644
--- a/src/whack/whack.c
+++ b/src/whack/whack.c
@@ -11,8 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: whack.c 4632 2008-11-11 18:37:19Z martin $
*/
#include <stdio.h>
@@ -32,248 +30,263 @@
#include <freeswan.h>
+#include <utils/optionsfrom.h>
+
#include "constants.h"
#include "defs.h"
#include "whack.h"
-static void
-help(void)
+static void help(void)
{
- fprintf(stderr
- , "Usage:\n\n"
- "all forms:"
- " [--optionsfrom <filename>]"
- " [--ctlbase <path>]"
- " [--label <string>]"
- "\n\n"
- "help: whack"
- " [--help]"
- " [--version]"
- "\n\n"
- "connection: whack"
- " --name <connection_name>"
- " \\\n "
- " [--ipv4 | --ipv6]"
- " [--tunnelipv4 | --tunnelipv6]"
- " \\\n "
- " (--host <ip-address> | --id <identity>)"
- " \\\n "
- " [--cert <path>]"
- " [--ca <distinguished name>]"
- " [--sendcert <policy>]"
- " \\\n "
- " [--groups <access control groups>]"
- " \\\n "
- " [--ikeport <port-number>]"
- " [--nexthop <ip-address>]"
- " [--srcip <ip-address>]"
- " \\\n "
- " [--client <subnet> | --clientwithin <address range>]"
- " [--clientprotoport <protocol>/<port>]"
- " \\\n "
- " [--dnskeyondemand]"
- " [--updown <updown>]"
- " \\\n "
- " --to"
- " (--host <ip-address> | --id <identity>)"
- " \\\n "
- " [--cert <path>]"
- " [--ca <distinguished name>]"
- " [--sendcert <policy>]"
- " \\\n "
- " [--ikeport <port-number>]"
- " [--nexthop <ip-address>]"
- " [--srcip <ip-address>]"
- " \\\n "
- " [--client <subnet> | --clientwithin <address range>]"
- " [--clientprotoport <protocol>/<port>]"
- " \\\n "
- " [--dnskeyondemand]"
- " [--updown <updown>]"
- " [--psk]"
- " [--rsasig]"
- " \\\n "
- " [--encrypt]"
- " [--authenticate]"
- " [--compress]"
- " [--tunnel]"
- " [--pfs]"
- " \\\n "
- " [--ikelifetime <seconds>]"
- " [--ipseclifetime <seconds>]"
- " \\\n "
- " [--reykeymargin <seconds>]"
- " [--reykeyfuzz <percentage>]"
- " \\\n "
- " [--keyingtries <count>]"
- " \\\n "
- " [--esp <esp-algos>]"
- " \\\n "
- " [--dontrekey]"
-
- " [--dpdaction (none|clear|hold|restart)]"
- " \\\n "
- " [--dpddelay <seconds> --dpdtimeout <seconds>]"
- " \\\n "
- " [--initiateontraffic|--pass|--drop|--reject]"
- " \\\n "
- " [--failnone|--failpass|--faildrop|--failreject]"
- "\n\n"
- "routing: whack"
- " (--route | --unroute)"
- " --name <connection_name>"
- "\n\n"
- "initiation:"
- "\n "
- " whack"
- " (--initiate | --terminate)"
- " --name <connection_name>"
- " [--asynchronous]"
- "\n\n"
- "opportunistic initiation: whack"
- " [--tunnelipv4 | --tunnelipv6]"
- " \\\n "
- " --oppohere <ip-address>"
- " --oppothere <ip-address>"
- "\n\n"
- "delete: whack"
- " --delete"
- " (--name <connection_name> | --caname <ca name>)"
- "\n\n"
- "deletestate: whack"
- " --deletestate <state_object_number>"
- " --crash <ip-address>"
- "\n\n"
- "pubkey: whack"
- " --keyid <id>"
- " [--addkey]"
- " [--pubkeyrsa <key>]"
- "\n\n"
- "myid: whack"
- " --myid <id>"
- "\n\n"
- "ca: whack"
- " --caname <name>"
- " --cacert <path>"
- " \\\n "
- " [--ldaphost <hostname>]"
- " [--ldapbase <base>]"
- " \\\n "
- " [--crluri <uri>]"
- " [--crluri2 <uri>]"
- " [--ocspuri <uri>]"
- " [--strictcrlpolicy]"
- "\n\n"
+ fprintf(stderr
+ , "Usage:\n\n"
+ "all forms:"
+ " [--optionsfrom <filename>]"
+ " [--ctlbase <path>]"
+ " [--label <string>]"
+ "\n\n"
+ "help: whack"
+ " [--help]"
+ " [--version]"
+ "\n\n"
+ "connection: whack"
+ " --name <connection_name>"
+ " \\\n "
+ " [--ipv4 | --ipv6]"
+ " [--tunnelipv4 | --tunnelipv6]"
+ " \\\n "
+ " (--host <ip-address> | --id <identity>)"
+ " \\\n "
+ " [--cert <path>]"
+ " [--ca <distinguished name>]"
+ " [--sendcert <policy>]"
+ " \\\n "
+ " [--groups <access control groups>]"
+ " \\\n "
+ " [--ikeport <port-number>]"
+ " [--nexthop <ip-address>]"
+ " [--srcip <ip-address>]"
+ " \\\n "
+ " [--client <subnet> | --clientwithin <address range>]"
+ " [--clientprotoport <protocol>/<port>]"
+ " \\\n "
+ " [--dnskeyondemand]"
+ " [--updown <updown>]"
+ " \\\n "
+ " --to"
+ " (--host <ip-address> | --id <identity>)"
+ " \\\n "
+ " [--cert <path>]"
+ " [--ca <distinguished name>]"
+ " [--sendcert <policy>]"
+ " \\\n "
+ " [--ikeport <port-number>]"
+ " [--nexthop <ip-address>]"
+ " [--srcip <ip-address>]"
+ " \\\n "
+ " [--client <subnet> | --clientwithin <address range>]"
+ " [--clientprotoport <protocol>/<port>]"
+ " \\\n "
+ " [--dnskeyondemand]"
+ " [--updown <updown>]"
+ " [--psk]"
+ " [--rsasig]"
+ " \\\n "
+ " [--encrypt]"
+ " [--authenticate]"
+ " [--compress]"
+ " [--tunnel]"
+ " [--pfs]"
+ " \\\n "
+ " [--ikelifetime <seconds>]"
+ " [--ipseclifetime <seconds>]"
+ " \\\n "
+ " [--reykeymargin <seconds>]"
+ " [--reykeyfuzz <percentage>]"
+ " \\\n "
+ " [--keyingtries <count>]"
+ " \\\n "
+ " [--esp <esp-algos>]"
+ " \\\n "
+ " [--dontrekey]"
+
+ " [--dpdaction (none|clear|hold|restart)]"
+ " \\\n "
+ " [--dpddelay <seconds> --dpdtimeout <seconds>]"
+ " \\\n "
+ " [--initiateontraffic|--pass|--drop|--reject]"
+ " \\\n "
+ " [--failnone|--failpass|--faildrop|--failreject]"
+ "\n\n"
+ "routing: whack"
+ " (--route | --unroute)"
+ " --name <connection_name>"
+ "\n\n"
+ "initiation:"
+ "\n "
+ " whack"
+ " (--initiate | --terminate)"
+ " --name <connection_name>"
+ " [--asynchronous]"
+ "\n\n"
+ "opportunistic initiation: whack"
+ " [--tunnelipv4 | --tunnelipv6]"
+ " \\\n "
+ " --oppohere <ip-address>"
+ " --oppothere <ip-address>"
+ "\n\n"
+ "delete: whack"
+ " --delete"
+ " (--name <connection_name> | --caname <ca name>)"
+ "\n\n"
+ "deletestate: whack"
+ " --deletestate <state_object_number>"
+ " --crash <ip-address>"
+ "\n\n"
+ "pubkey: whack"
+ " --keyid <id>"
+ " [--addkey]"
+ " [--pubkeyrsa <key>]"
+ "\n\n"
+ "myid: whack"
+ " --myid <id>"
+ "\n\n"
+ "ca: whack"
+ " --caname <name>"
+ " --cacert <path>"
+ " \\\n "
+ " [--ldaphost <hostname>]"
+ " [--ldapbase <base>]"
+ " \\\n "
+ " [--crluri <uri>]"
+ " [--crluri2 <uri>]"
+ " [--ocspuri <uri>]"
+ " [--strictcrlpolicy]"
+ "\n\n"
#ifdef DEBUG
- "debug: whack [--name <connection_name>]"
- " \\\n "
- " [--debug-none]"
- " [--debug-all]"
- " \\\n "
- " [--debug-raw]"
- " [--debug-crypt]"
- " [--debug-parsing]"
- " [--debug-emitting]"
- " \\\n "
- " [--debug-control]"
- " [--debug-lifecycle]"
- " [--debug-klips]"
- " [--debug-dns]"
- " \\\n "
- " [--debug-natt]"
- " [--debug-oppo]"
- " [--debug-controlmore]"
- " [--debug-private]"
- "\n\n"
+ "debug: whack [--name <connection_name>]"
+ " \\\n "
+ " [--debug-none]"
+ " [--debug-all]"
+ " \\\n "
+ " [--debug-raw]"
+ " [--debug-crypt]"
+ " [--debug-parsing]"
+ " [--debug-emitting]"
+ " \\\n "
+ " [--debug-control]"
+ " [--debug-lifecycle]"
+ " [--debug-klips]"
+ " [--debug-dns]"
+ " \\\n "
+ " [--debug-natt]"
+ " [--debug-oppo]"
+ " [--debug-controlmore]"
+ " [--debug-private]"
+ "\n\n"
#endif
- "listen: whack"
- " (--listen | --unlisten)"
- "\n\n"
- "list: whack [--utc]"
- " [--listalgs]"
- " [--listpubkeys]"
- " [--listcerts]"
- " [--listcacerts]"
- " \\\n "
- " [--listacerts]"
- " [--listaacerts]"
- " [--listocspcerts]"
- " [--listgroups]"
- " \\\n "
- " [--listcainfos]"
- " [--listcrls]"
- " [--listocsp]"
- " [--listcards]"
- " [--listall]"
- "\n\n"
- "purge: whack"
- " [--purgeocsp]"
- "\n\n"
- "reread: whack"
- " [--rereadsecrets]"
- " [--rereadcacerts]"
- " [--rereadaacerts]"
- " \\\n "
- " [--rereadocspcerts]"
- " [--rereadacerts]"
- " [--rereadcrls]"
- " [--rereadall]"
- "\n\n"
- "status: whack"
- " [--name <connection_name>] --status|--statusall"
- "\n\n"
- "scdecrypt: whack"
- " --scencrypt|scdecrypt <value>"
- " [--inbase <base>]"
- " [--outbase <base>]"
- " [--keyid <id>]"
- "\n\n"
- "shutdown: whack"
- " --shutdown"
- "\n\n"
- "strongSwan %s\n"
- , ipsec_version_code());
+ "listen: whack"
+ " (--listen | --unlisten)"
+ "\n\n"
+ "list: whack [--utc]"
+ " [--listalgs]"
+ " [--listpubkeys]"
+ " [--listcerts]"
+ " [--listcacerts]"
+ " \\\n "
+ " [--listacerts]"
+ " [--listaacerts]"
+ " [--listocspcerts]"
+ " [--listgroups]"
+ " \\\n "
+ " [--listcainfos]"
+ " [--listcrls]"
+ " [--listocsp]"
+ " [--listcards]"
+ " [--listall]"
+ "\n\n"
+ "purge: whack"
+ " [--purgeocsp]"
+ "\n\n"
+ "reread: whack"
+ " [--rereadsecrets]"
+ " [--rereadcacerts]"
+ " [--rereadaacerts]"
+ " \\\n "
+ " [--rereadocspcerts]"
+ " [--rereadacerts]"
+ " [--rereadcrls]"
+ " [--rereadall]"
+ "\n\n"
+ "status: whack"
+ " [--name <connection_name>] --status|--statusall"
+ "\n\n"
+ "scdecrypt: whack"
+ " --scencrypt|scdecrypt <value>"
+ " [--inbase <base>]"
+ " [--outbase <base>]"
+ " [--keyid <id>]"
+ "\n\n"
+ "shutdown: whack"
+ " --shutdown"
+ "\n\n"
+ "strongSwan "VERSION"\n");
}
-static const char *label = NULL; /* --label operand, saved for diagnostics */
+static const char *label = NULL; /* --label operand, saved for diagnostics */
-static const char *name = NULL; /* --name operand, saved for diagnostics */
+static const char *name = NULL; /* --name operand, saved for diagnostics */
-/* print a string as a diagnostic, then exit whack unhappily */
-static void
-diag(const char *mess)
+/* options read by optionsfrom */
+options_t *options;
+
+/**
+ * exit whack after cleaning up
+ */
+static void whack_exit(int status)
{
- if (mess != NULL)
- {
- fprintf(stderr, "whack error: ");
- if (label != NULL)
- fprintf(stderr, "%s ", label);
- if (name != NULL)
- fprintf(stderr, "\"%s\" ", name);
- fprintf(stderr, "%s\n", mess);
- }
-
- exit(RC_WHACK_PROBLEM);
+ options->destroy(options);
+ exit(status);
}
-/* conditially calls diag; prints second arg, if non-NULL, as quoted string */
-static void
-diagq(err_t ugh, const char *this)
+/**
+ * print a string as a diagnostic, then exit whack unhappily
+ */
+static void diag(const char *mess)
{
- if (ugh != NULL)
- {
- if (this == NULL)
+ if (mess != NULL)
{
- diag(ugh);
+ fprintf(stderr, "whack error: ");
+ if (label != NULL)
+ {
+ fprintf(stderr, "%s ", label);
+ }
+ if (name != NULL)
+ {
+ fprintf(stderr, "\"%s\" ", name);
+ }
+ fprintf(stderr, "%s\n", mess);
}
- else
+ whack_exit(RC_WHACK_PROBLEM);
+}
+
+/* conditially calls diag; prints second arg, if non-NULL, as quoted string */
+static void diagq(err_t ugh, const char *this)
+{
+ if (ugh != NULL)
{
- char buf[120]; /* arbitrary limit */
+ if (this == NULL)
+ {
+ diag(ugh);
+ }
+ else
+ {
+ char buf[120]; /* arbitrary limit */
- snprintf(buf, sizeof(buf), "%s \"%s\"", ugh, this);
- diag(buf);
+ snprintf(buf, sizeof(buf), "%s \"%s\"", ugh, this);
+ diag(buf);
+ }
}
- }
}
/* complex combined operands return one of these enumerated values
@@ -287,181 +300,181 @@ diagq(err_t ugh, const char *this)
* - CA_* options (CA description options)
*/
enum {
-# define OPT_FIRST OPT_CTLBASE
- OPT_CTLBASE,
- OPT_NAME,
+# define OPT_FIRST OPT_CTLBASE
+ OPT_CTLBASE,
+ OPT_NAME,
- OPT_CD,
+ OPT_CD,
- OPT_KEYID,
- OPT_ADDKEY,
- OPT_PUBKEYRSA,
+ OPT_KEYID,
+ OPT_ADDKEY,
+ OPT_PUBKEYRSA,
- OPT_MYID,
+ OPT_MYID,
- OPT_ROUTE,
- OPT_UNROUTE,
+ OPT_ROUTE,
+ OPT_UNROUTE,
- OPT_INITIATE,
- OPT_TERMINATE,
- OPT_DELETE,
- OPT_DELETESTATE,
- OPT_LISTEN,
- OPT_UNLISTEN,
+ OPT_INITIATE,
+ OPT_TERMINATE,
+ OPT_DELETE,
+ OPT_DELETESTATE,
+ OPT_LISTEN,
+ OPT_UNLISTEN,
- OPT_PURGEOCSP,
+ OPT_PURGEOCSP,
- OPT_REREADSECRETS,
- OPT_REREADCACERTS,
- OPT_REREADAACERTS,
- OPT_REREADOCSPCERTS,
- OPT_REREADACERTS,
- OPT_REREADCRLS,
- OPT_REREADALL,
+ OPT_REREADSECRETS,
+ OPT_REREADCACERTS,
+ OPT_REREADAACERTS,
+ OPT_REREADOCSPCERTS,
+ OPT_REREADACERTS,
+ OPT_REREADCRLS,
+ OPT_REREADALL,
- OPT_STATUS,
- OPT_STATUSALL,
- OPT_SHUTDOWN,
+ OPT_STATUS,
+ OPT_STATUSALL,
+ OPT_SHUTDOWN,
- OPT_OPPO_HERE,
- OPT_OPPO_THERE,
+ OPT_OPPO_HERE,
+ OPT_OPPO_THERE,
- OPT_ASYNC,
- OPT_DELETECRASH,
+ OPT_ASYNC,
+ OPT_DELETECRASH,
-# define OPT_LAST OPT_ASYNC /* last "normal" option */
+# define OPT_LAST OPT_ASYNC /* last "normal" option */
/* Smartcard options */
-# define SC_FIRST SC_ENCRYPT /* first smartcard option */
+# define SC_FIRST SC_ENCRYPT /* first smartcard option */
- SC_ENCRYPT,
- SC_DECRYPT,
- SC_INBASE,
- SC_OUTBASE,
+ SC_ENCRYPT,
+ SC_DECRYPT,
+ SC_INBASE,
+ SC_OUTBASE,
-# define SC_LAST SC_OUTBASE /* last "smartcard" option */
+# define SC_LAST SC_OUTBASE /* last "smartcard" option */
/* List options */
-# define LST_FIRST LST_UTC /* first list option */
- LST_UTC,
- LST_ALGS,
- LST_PUBKEYS,
- LST_CERTS,
- LST_CACERTS,
- LST_ACERTS,
- LST_AACERTS,
- LST_OCSPCERTS,
- LST_GROUPS,
- LST_CAINFOS,
- LST_CRLS,
- LST_OCSP,
- LST_CARDS,
- LST_ALL,
-
-# define LST_LAST LST_ALL /* last list option */
+# define LST_FIRST LST_UTC /* first list option */
+ LST_UTC,
+ LST_ALGS,
+ LST_PUBKEYS,
+ LST_CERTS,
+ LST_CACERTS,
+ LST_ACERTS,
+ LST_AACERTS,
+ LST_OCSPCERTS,
+ LST_GROUPS,
+ LST_CAINFOS,
+ LST_CRLS,
+ LST_OCSP,
+ LST_CARDS,
+ LST_ALL,
+
+# define LST_LAST LST_ALL /* last list option */
/* Connection End Description options */
-# define END_FIRST END_HOST /* first end description */
- END_HOST,
- END_ID,
- END_CERT,
- END_CA,
- END_SENDCERT,
- END_GROUPS,
- END_IKEPORT,
- END_NEXTHOP,
- END_CLIENT,
- END_CLIENTWITHIN,
- END_CLIENTPROTOPORT,
- END_DNSKEYONDEMAND,
- END_SRCIP,
- END_HOSTACCESS,
- END_UPDOWN,
-
-#define END_LAST END_UPDOWN /* last end description*/
+# define END_FIRST END_HOST /* first end description */
+ END_HOST,
+ END_ID,
+ END_CERT,
+ END_CA,
+ END_SENDCERT,
+ END_GROUPS,
+ END_IKEPORT,
+ END_NEXTHOP,
+ END_CLIENT,
+ END_CLIENTWITHIN,
+ END_CLIENTPROTOPORT,
+ END_DNSKEYONDEMAND,
+ END_SRCIP,
+ END_HOSTACCESS,
+ END_UPDOWN,
+
+#define END_LAST END_UPDOWN /* last end description*/
/* Connection Description options -- segregated */
-# define CD_FIRST CD_TO /* first connection description */
- CD_TO,
+# define CD_FIRST CD_TO /* first connection description */
+ CD_TO,
# define CD_POLICY_FIRST CD_PSK
- CD_PSK, /* same order as POLICY_* */
- CD_RSASIG, /* same order as POLICY_* */
- CD_ENCRYPT, /* same order as POLICY_* */
- CD_AUTHENTICATE, /* same order as POLICY_* */
- CD_COMPRESS, /* same order as POLICY_* */
- CD_TUNNEL, /* same order as POLICY_* */
- CD_PFS, /* same order as POLICY_* */
- CD_DISABLEARRIVALCHECK, /* same order as POLICY_* */
- CD_SHUNT0, /* same order as POLICY_* */
- CD_SHUNT1, /* same order as POLICY_* */
- CD_FAIL0, /* same order as POLICY_* */
- CD_FAIL1, /* same order as POLICY_* */
- CD_DONT_REKEY, /* same order as POLICY_* */
-
- CD_TUNNELIPV4,
- CD_TUNNELIPV6,
- CD_CONNIPV4,
- CD_CONNIPV6,
-
- CD_IKELIFETIME,
- CD_IPSECLIFETIME,
- CD_RKMARGIN,
- CD_RKFUZZ,
- CD_KTRIES,
- CD_DPDACTION,
- CD_DPDDELAY,
- CD_DPDTIMEOUT,
- CD_IKE,
- CD_PFSGROUP,
- CD_ESP,
-
-# define CD_LAST CD_ESP /* last connection description */
+ CD_PSK, /* same order as POLICY_* */
+ CD_RSASIG, /* same order as POLICY_* */
+ CD_ENCRYPT, /* same order as POLICY_* */
+ CD_AUTHENTICATE, /* same order as POLICY_* */
+ CD_COMPRESS, /* same order as POLICY_* */
+ CD_TUNNEL, /* same order as POLICY_* */
+ CD_PFS, /* same order as POLICY_* */
+ CD_DISABLEARRIVALCHECK, /* same order as POLICY_* */
+ CD_SHUNT0, /* same order as POLICY_* */
+ CD_SHUNT1, /* same order as POLICY_* */
+ CD_FAIL0, /* same order as POLICY_* */
+ CD_FAIL1, /* same order as POLICY_* */
+ CD_DONT_REKEY, /* same order as POLICY_* */
+
+ CD_TUNNELIPV4,
+ CD_TUNNELIPV6,
+ CD_CONNIPV4,
+ CD_CONNIPV6,
+
+ CD_IKELIFETIME,
+ CD_IPSECLIFETIME,
+ CD_RKMARGIN,
+ CD_RKFUZZ,
+ CD_KTRIES,
+ CD_DPDACTION,
+ CD_DPDDELAY,
+ CD_DPDTIMEOUT,
+ CD_IKE,
+ CD_PFSGROUP,
+ CD_ESP,
+
+# define CD_LAST CD_ESP /* last connection description */
/* Certificate Authority (CA) description options */
-# define CA_FIRST CA_NAME /* first ca description */
+# define CA_FIRST CA_NAME /* first ca description */
- CA_NAME,
- CA_CERT,
- CA_LDAPHOST,
- CA_LDAPBASE,
- CA_CRLURI,
- CA_CRLURI2,
- CA_OCSPURI,
- CA_STRICT
+ CA_NAME,
+ CA_CERT,
+ CA_LDAPHOST,
+ CA_LDAPBASE,
+ CA_CRLURI,
+ CA_CRLURI2,
+ CA_OCSPURI,
+ CA_STRICT
-# define CA_LAST CA_STRICT /* last ca description */
+# define CA_LAST CA_STRICT /* last ca description */
-#ifdef DEBUG /* must be last so others are less than 32 to fit in lset_t */
+#ifdef DEBUG /* must be last so others are less than 32 to fit in lset_t */
# define DBGOPT_FIRST DBGOPT_NONE
- ,
- /* NOTE: these definitions must match DBG_* and IMPAIR_* in constants.h */
- DBGOPT_NONE,
- DBGOPT_ALL,
-
- DBGOPT_RAW, /* same order as DBG_* */
- DBGOPT_CRYPT, /* same order as DBG_* */
- DBGOPT_PARSING, /* same order as DBG_* */
- DBGOPT_EMITTING, /* same order as DBG_* */
- DBGOPT_CONTROL, /* same order as DBG_* */
- DBGOPT_LIFECYCLE, /* same order as DBG_* */
- DBGOPT_KLIPS, /* same order as DBG_* */
- DBGOPT_DNS, /* same order as DBG_* */
- DBGOPT_NATT, /* same order as DBG_* */
- DBGOPT_OPPO, /* same order as DBG_* */
- DBGOPT_CONTROLMORE, /* same order as DBG_* */
-
- DBGOPT_PRIVATE, /* same order as DBG_* */
-
- DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_BUST_MI2, /* same order as IMPAIR_* */
- DBGOPT_IMPAIR_BUST_MR2 /* same order as IMPAIR_* */
+ ,
+ /* NOTE: these definitions must match DBG_* and IMPAIR_* in constants.h */
+ DBGOPT_NONE,
+ DBGOPT_ALL,
+
+ DBGOPT_RAW, /* same order as DBG_* */
+ DBGOPT_CRYPT, /* same order as DBG_* */
+ DBGOPT_PARSING, /* same order as DBG_* */
+ DBGOPT_EMITTING, /* same order as DBG_* */
+ DBGOPT_CONTROL, /* same order as DBG_* */
+ DBGOPT_LIFECYCLE, /* same order as DBG_* */
+ DBGOPT_KLIPS, /* same order as DBG_* */
+ DBGOPT_DNS, /* same order as DBG_* */
+ DBGOPT_NATT, /* same order as DBG_* */
+ DBGOPT_OPPO, /* same order as DBG_* */
+ DBGOPT_CONTROLMORE, /* same order as DBG_* */
+
+ DBGOPT_PRIVATE, /* same order as DBG_* */
+
+ DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER, /* same order as IMPAIR_* */
+ DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER, /* same order as IMPAIR_* */
+ DBGOPT_IMPAIR_BUST_MI2, /* same order as IMPAIR_* */
+ DBGOPT_IMPAIR_BUST_MR2 /* same order as IMPAIR_* */
# define DBGOPT_LAST DBGOPT_IMPAIR_BUST_MR2
#endif
@@ -473,1433 +486,1430 @@ enum {
* Numeric arg is bit immediately left of basic value.
*
*/
-#define OPTION_OFFSET 256 /* to get out of the way of letter options */
-#define NUMERIC_ARG (1 << 9) /* expect a numeric argument */
-#define AUX_SHIFT 10 /* amount to shift for aux information */
+#define OPTION_OFFSET 256 /* to get out of the way of letter options */
+#define NUMERIC_ARG (1 << 9) /* expect a numeric argument */
+#define AUX_SHIFT 10 /* amount to shift for aux information */
static const struct option long_opts[] = {
-# define OO OPTION_OFFSET
- /* name, has_arg, flag, val */
-
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { "optionsfrom", required_argument, NULL, '+' },
- { "label", required_argument, NULL, 'l' },
-
- { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
- { "name", required_argument, NULL, OPT_NAME + OO },
-
- { "keyid", required_argument, NULL, OPT_KEYID + OO },
- { "addkey", no_argument, NULL, OPT_ADDKEY + OO },
- { "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO },
-
- { "myid", required_argument, NULL, OPT_MYID + OO },
-
- { "route", no_argument, NULL, OPT_ROUTE + OO },
- { "unroute", no_argument, NULL, OPT_UNROUTE + OO },
-
- { "initiate", no_argument, NULL, OPT_INITIATE + OO },
- { "terminate", no_argument, NULL, OPT_TERMINATE + OO },
- { "delete", no_argument, NULL, OPT_DELETE + OO },
- { "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
- { "crash", required_argument, NULL, OPT_DELETECRASH + OO },
- { "listen", no_argument, NULL, OPT_LISTEN + OO },
- { "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
-
- { "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
-
- { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
- { "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
- { "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
- { "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
- { "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
- { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
- { "rereadall", no_argument, NULL, OPT_REREADALL + OO },
- { "status", no_argument, NULL, OPT_STATUS + OO },
- { "statusall", no_argument, NULL, OPT_STATUSALL + OO },
- { "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
-
- { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
- { "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO },
-
- { "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
-
- /* smartcard options */
-
- { "scencrypt", required_argument, NULL, SC_ENCRYPT + OO },
- { "scdecrypt", required_argument, NULL, SC_DECRYPT + OO },
- { "inbase", required_argument, NULL, SC_INBASE + OO },
- { "outbase", required_argument, NULL, SC_OUTBASE + OO },
-
- /* list options */
-
- { "utc", no_argument, NULL, LST_UTC + OO },
- { "listalgs", no_argument, NULL, LST_ALGS + OO },
- { "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
- { "listcerts", no_argument, NULL, LST_CERTS + OO },
- { "listcacerts", no_argument, NULL, LST_CACERTS + OO },
- { "listacerts", no_argument, NULL, LST_ACERTS + OO },
- { "listaacerts", no_argument, NULL, LST_AACERTS + OO },
- { "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
- { "listgroups", no_argument, NULL, LST_GROUPS + OO },
- { "listcainfos", no_argument, NULL, LST_CAINFOS + OO },
- { "listcrls", no_argument, NULL, LST_CRLS + OO },
- { "listocsp", no_argument, NULL, LST_OCSP + OO },
- { "listcards", no_argument, NULL, LST_CARDS + OO },
- { "listall", no_argument, NULL, LST_ALL + OO },
-
- /* options for an end description */
-
- { "host", required_argument, NULL, END_HOST + OO },
- { "id", required_argument, NULL, END_ID + OO },
- { "cert", required_argument, NULL, END_CERT + OO },
- { "ca", required_argument, NULL, END_CA + OO },
- { "sendcert", required_argument, NULL, END_SENDCERT + OO },
- { "groups", required_argument, NULL, END_GROUPS + OO },
- { "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
- { "nexthop", required_argument, NULL, END_NEXTHOP + OO },
- { "client", required_argument, NULL, END_CLIENT + OO },
- { "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
- { "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
- { "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
- { "srcip", required_argument, NULL, END_SRCIP + OO },
- { "hostaccess", no_argument, NULL, END_HOSTACCESS + OO },
- { "updown", required_argument, NULL, END_UPDOWN + OO },
-
- /* options for a connection description */
-
- { "to", no_argument, NULL, CD_TO + OO },
-
- { "psk", no_argument, NULL, CD_PSK + OO },
- { "rsasig", no_argument, NULL, CD_RSASIG + OO },
-
- { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
- { "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
- { "compress", no_argument, NULL, CD_COMPRESS + OO },
- { "tunnel", no_argument, NULL, CD_TUNNEL + OO },
- { "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
- { "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
- { "pfs", no_argument, NULL, CD_PFS + OO },
- { "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
- { "initiateontraffic", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "pass", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "drop", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "reject", no_argument, NULL
- , CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
- { "failnone", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "failpass", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "faildrop", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "failreject", no_argument, NULL
- , CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
- { "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
- { "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
- { "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
-
- { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
- { "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
- { "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
- { "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
- { "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
- { "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
- { "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
- { "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
- { "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
- { "ike", required_argument, NULL, CD_IKE + OO },
- { "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
- { "esp", required_argument, NULL, CD_ESP + OO },
-
- /* options for a ca description */
-
- { "caname", required_argument, NULL, CA_NAME + OO },
- { "cacert", required_argument, NULL, CA_CERT + OO },
- { "ldaphost", required_argument, NULL, CA_LDAPHOST + OO },
- { "ldapbase", required_argument, NULL, CA_LDAPBASE + OO },
- { "crluri", required_argument, NULL, CA_CRLURI + OO },
- { "crluri2", required_argument, NULL, CA_CRLURI2 + OO },
- { "ocspuri", required_argument, NULL, CA_OCSPURI + OO },
- { "strictcrlpolicy", no_argument, NULL, CA_STRICT + OO },
+# define OO OPTION_OFFSET
+ /* name, has_arg, flag, val */
+
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "optionsfrom", required_argument, NULL, '+' },
+ { "label", required_argument, NULL, 'l' },
+
+ { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
+ { "name", required_argument, NULL, OPT_NAME + OO },
+
+ { "keyid", required_argument, NULL, OPT_KEYID + OO },
+ { "addkey", no_argument, NULL, OPT_ADDKEY + OO },
+ { "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO },
+
+ { "myid", required_argument, NULL, OPT_MYID + OO },
+
+ { "route", no_argument, NULL, OPT_ROUTE + OO },
+ { "unroute", no_argument, NULL, OPT_UNROUTE + OO },
+
+ { "initiate", no_argument, NULL, OPT_INITIATE + OO },
+ { "terminate", no_argument, NULL, OPT_TERMINATE + OO },
+ { "delete", no_argument, NULL, OPT_DELETE + OO },
+ { "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
+ { "crash", required_argument, NULL, OPT_DELETECRASH + OO },
+ { "listen", no_argument, NULL, OPT_LISTEN + OO },
+ { "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
+
+ { "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
+
+ { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
+ { "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
+ { "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
+ { "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
+ { "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
+ { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
+ { "rereadall", no_argument, NULL, OPT_REREADALL + OO },
+ { "status", no_argument, NULL, OPT_STATUS + OO },
+ { "statusall", no_argument, NULL, OPT_STATUSALL + OO },
+ { "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
+
+ { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
+ { "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO },
+
+ { "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
+
+ /* smartcard options */
+
+ { "scencrypt", required_argument, NULL, SC_ENCRYPT + OO },
+ { "scdecrypt", required_argument, NULL, SC_DECRYPT + OO },
+ { "inbase", required_argument, NULL, SC_INBASE + OO },
+ { "outbase", required_argument, NULL, SC_OUTBASE + OO },
+
+ /* list options */
+
+ { "utc", no_argument, NULL, LST_UTC + OO },
+ { "listalgs", no_argument, NULL, LST_ALGS + OO },
+ { "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
+ { "listcerts", no_argument, NULL, LST_CERTS + OO },
+ { "listcacerts", no_argument, NULL, LST_CACERTS + OO },
+ { "listacerts", no_argument, NULL, LST_ACERTS + OO },
+ { "listaacerts", no_argument, NULL, LST_AACERTS + OO },
+ { "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
+ { "listgroups", no_argument, NULL, LST_GROUPS + OO },
+ { "listcainfos", no_argument, NULL, LST_CAINFOS + OO },
+ { "listcrls", no_argument, NULL, LST_CRLS + OO },
+ { "listocsp", no_argument, NULL, LST_OCSP + OO },
+ { "listcards", no_argument, NULL, LST_CARDS + OO },
+ { "listall", no_argument, NULL, LST_ALL + OO },
+
+ /* options for an end description */
+
+ { "host", required_argument, NULL, END_HOST + OO },
+ { "id", required_argument, NULL, END_ID + OO },
+ { "cert", required_argument, NULL, END_CERT + OO },
+ { "ca", required_argument, NULL, END_CA + OO },
+ { "sendcert", required_argument, NULL, END_SENDCERT + OO },
+ { "groups", required_argument, NULL, END_GROUPS + OO },
+ { "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
+ { "nexthop", required_argument, NULL, END_NEXTHOP + OO },
+ { "client", required_argument, NULL, END_CLIENT + OO },
+ { "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
+ { "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
+ { "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
+ { "srcip", required_argument, NULL, END_SRCIP + OO },
+ { "hostaccess", no_argument, NULL, END_HOSTACCESS + OO },
+ { "updown", required_argument, NULL, END_UPDOWN + OO },
+
+ /* options for a connection description */
+
+ { "to", no_argument, NULL, CD_TO + OO },
+
+ { "psk", no_argument, NULL, CD_PSK + OO },
+ { "rsasig", no_argument, NULL, CD_RSASIG + OO },
+
+ { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
+ { "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
+ { "compress", no_argument, NULL, CD_COMPRESS + OO },
+ { "tunnel", no_argument, NULL, CD_TUNNEL + OO },
+ { "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
+ { "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
+ { "pfs", no_argument, NULL, CD_PFS + OO },
+ { "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
+ { "initiateontraffic", no_argument, NULL
+ , CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
+ { "pass", no_argument, NULL
+ , CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
+ { "drop", no_argument, NULL
+ , CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
+ { "reject", no_argument, NULL
+ , CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
+ { "failnone", no_argument, NULL
+ , CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
+ { "failpass", no_argument, NULL
+ , CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
+ { "faildrop", no_argument, NULL
+ , CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
+ { "failreject", no_argument, NULL
+ , CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
+ { "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
+ { "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
+ { "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
+
+ { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
+ { "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
+ { "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
+ { "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
+ { "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
+ { "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
+ { "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
+ { "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
+ { "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
+ { "ike", required_argument, NULL, CD_IKE + OO },
+ { "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
+ { "esp", required_argument, NULL, CD_ESP + OO },
+
+ /* options for a ca description */
+
+ { "caname", required_argument, NULL, CA_NAME + OO },
+ { "cacert", required_argument, NULL, CA_CERT + OO },
+ { "ldaphost", required_argument, NULL, CA_LDAPHOST + OO },
+ { "ldapbase", required_argument, NULL, CA_LDAPBASE + OO },
+ { "crluri", required_argument, NULL, CA_CRLURI + OO },
+ { "crluri2", required_argument, NULL, CA_CRLURI2 + OO },
+ { "ocspuri", required_argument, NULL, CA_OCSPURI + OO },
+ { "strictcrlpolicy", no_argument, NULL, CA_STRICT + OO },
#ifdef DEBUG
- { "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
- { "debug-all]", no_argument, NULL, DBGOPT_ALL + OO },
- { "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
- { "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
- { "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
- { "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
- { "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
- { "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
- { "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
- { "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
- { "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
- { "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
- { "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
- { "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
-
- { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
- { "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
- { "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
- { "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
+ { "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
+ { "debug-all]", no_argument, NULL, DBGOPT_ALL + OO },
+ { "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
+ { "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
+ { "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
+ { "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
+ { "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
+ { "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
+ { "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
+ { "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
+ { "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
+ { "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
+ { "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
+ { "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
+
+ { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
+ { "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
+ { "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
+ { "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
#endif
# undef OO
- { 0,0,0,0 }
+ { 0,0,0,0 }
};
struct sockaddr_un ctl_addr = { AF_UNIX, DEFAULT_CTLBASE CTL_SUFFIX };
/* helper variables and function to encode strings from whack message */
-static char
- *next_str,
- *str_roof;
+static char *next_str,*str_roof;
-static bool
-pack_str(char **p)
+static bool pack_str(char **p)
{
- const char *s = *p == NULL? "" : *p; /* note: NULL becomes ""! */
- size_t len = strlen(s) + 1;
-
- if (str_roof - next_str < (ptrdiff_t)len)
- {
- return FALSE; /* fishy: no end found */
- }
- else
- {
- strcpy(next_str, s);
- next_str += len;
- *p = NULL; /* don't send pointers on the wire! */
- return TRUE;
- }
+ const char *s = *p == NULL? "" : *p; /* note: NULL becomes ""! */
+ size_t len = strlen(s) + 1;
+
+ if (str_roof - next_str < (ptrdiff_t)len)
+ {
+ return FALSE; /* fishy: no end found */
+ }
+ else
+ {
+ strcpy(next_str, s);
+ next_str += len;
+ *p = NULL; /* don't send pointers on the wire! */
+ return TRUE;
+ }
}
-static void
-check_life_time(time_t life, time_t limit, const char *which
-, const whack_message_t *msg)
+static void check_life_time(time_t life, time_t limit, const char *which,
+ const whack_message_t *msg)
{
- time_t mint = msg->sa_rekey_margin * (100 + msg->sa_rekey_fuzz) / 100;
-
- if (life > limit)
- {
- char buf[200]; /* arbitrary limit */
-
- snprintf(buf, sizeof(buf)
- , "%s [%lu seconds] must be less than %lu seconds"
- , which, (unsigned long)life, (unsigned long)limit);
- diag(buf);
- }
- if ((msg->policy & POLICY_DONT_REKEY) == LEMPTY && life <= mint)
- {
- char buf[200]; /* arbitrary limit */
-
- snprintf(buf, sizeof(buf)
- , "%s [%lu] must be greater than"
- " rekeymargin*(100+rekeyfuzz)/100 [%lu*(100+%lu)/100 = %lu]"
- , which
- , (unsigned long)life
- , (unsigned long)msg->sa_rekey_margin
- , (unsigned long)msg->sa_rekey_fuzz
- , (unsigned long)mint);
- diag(buf);
- }
+ time_t mint = msg->sa_rekey_margin * (100 + msg->sa_rekey_fuzz) / 100;
+
+ if (life > limit)
+ {
+ char buf[200]; /* arbitrary limit */
+
+ snprintf(buf, sizeof(buf)
+ , "%s [%lu seconds] must be less than %lu seconds"
+ , which, (unsigned long)life, (unsigned long)limit);
+ diag(buf);
+ }
+ if ((msg->policy & POLICY_DONT_REKEY) == LEMPTY && life <= mint)
+ {
+ char buf[200]; /* arbitrary limit */
+
+ snprintf(buf, sizeof(buf)
+ , "%s [%lu] must be greater than"
+ " rekeymargin*(100+rekeyfuzz)/100 [%lu*(100+%lu)/100 = %lu]"
+ , which
+ , (unsigned long)life
+ , (unsigned long)msg->sa_rekey_margin
+ , (unsigned long)msg->sa_rekey_fuzz
+ , (unsigned long)mint);
+ diag(buf);
+ }
}
-static void
-clear_end(whack_end_t *e)
+static void clear_end(whack_end_t *e)
{
- zero(e);
- e->id = NULL;
- e->cert = NULL;
- e->ca = NULL;
- e->updown = NULL;
- e->host_port = IKE_UDP_PORT;
+ zero(e);
+ e->id = NULL;
+ e->cert = NULL;
+ e->ca = NULL;
+ e->updown = NULL;
+ e->host_port = IKE_UDP_PORT;
}
-static void
-update_ports(whack_message_t *m)
+static void update_ports(whack_message_t *m)
{
- int port;
-
- if (m->left.port != 0) {
- port = htons(m->left.port);
- setportof(port, &m->left.host_addr);
- setportof(port, &m->left.client.addr);
- }
- if (m->right.port != 0) {
- port = htons(m->right.port);
- setportof(port, &m->right.host_addr);
- setportof(port, &m->right.client.addr);
- }
+ int port;
+
+ if (m->left.port != 0) {
+ port = htons(m->left.port);
+ setportof(port, &m->left.host_addr);
+ setportof(port, &m->left.client.addr);
+ }
+ if (m->right.port != 0) {
+ port = htons(m->right.port);
+ setportof(port, &m->right.host_addr);
+ setportof(port, &m->right.client.addr);
+ }
}
-static void
-check_end(whack_end_t *this, whack_end_t *that
-, bool default_nexthop, sa_family_t caf, sa_family_t taf)
+static void check_end(whack_end_t *this, whack_end_t *that,
+ bool default_nexthop, sa_family_t caf, sa_family_t taf)
{
- if (caf != addrtypeof(&this->host_addr))
- diag("address family of host inconsistent");
-
- if (default_nexthop)
- {
- if (isanyaddr(&that->host_addr))
- diag("our nexthop must be specified when other host is a %any or %opportunistic");
- this->host_nexthop = that->host_addr;
- }
-
- if (caf != addrtypeof(&this->host_nexthop))
- diag("address family of nexthop inconsistent");
-
- if (this->has_client)
- {
- if (taf != subnettypeof(&this->client))
- diag("address family of client subnet inconsistent");
- }
- else
- {
- /* fill in anyaddr-anyaddr as (missing) client subnet */
- ip_address cn;
-
- diagq(anyaddr(caf, &cn), NULL);
- diagq(rangetosubnet(&cn, &cn, &this->client), NULL);
- }
-
- /* fill in anyaddr if source IP is not defined */
- if (!this->has_srcip)
- diagq(anyaddr(caf, &this->host_srcip), optarg);
+ if (caf != addrtypeof(&this->host_addr))
+ diag("address family of host inconsistent");
+
+ if (default_nexthop)
+ {
+ if (isanyaddr(&that->host_addr))
+ diag("our nexthop must be specified when other host is a %any or %opportunistic");
+ this->host_nexthop = that->host_addr;
+ }
+
+ if (caf != addrtypeof(&this->host_nexthop))
+ diag("address family of nexthop inconsistent");
+
+ if (this->has_client)
+ {
+ if (taf != subnettypeof(&this->client))
+ diag("address family of client subnet inconsistent");
+ }
+ else
+ {
+ /* fill in anyaddr-anyaddr as (missing) client subnet */
+ ip_address cn;
+
+ diagq(anyaddr(caf, &cn), NULL);
+ diagq(rangetosubnet(&cn, &cn, &this->client), NULL);
+ }
+
+ /* fill in anyaddr if source IP is not defined */
+ if (!this->has_srcip)
+ diagq(anyaddr(caf, &this->host_srcip), optarg);
/* check protocol */
- if (this->protocol != that->protocol)
- diag("the protocol for leftprotoport and rightprotoport must be the same");
+ if (this->protocol != that->protocol)
+ diag("the protocol for leftprotoport and rightprotoport must be the same");
}
-static void
-get_secret(int sock)
+static void get_secret(int sock)
{
- const char *buf, *secret;
- int len;
-
- fflush(stdout);
- usleep(20000); /* give fflush time for flushing */
- buf = getpass("Enter: ");
- secret = (buf == NULL)? "" : buf;
-
- /* send the secret to pluto */
- len = strlen(secret) + 1;
- if (write(sock, secret, len) != len)
- {
- int e = errno;
-
- fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
- }
+ const char *buf, *secret;
+ int len;
+
+ fflush(stdout);
+ usleep(20000); /* give fflush time for flushing */
+ buf = getpass("Enter: ");
+ secret = (buf == NULL)? "" : buf;
+
+ /* send the secret to pluto */
+ len = strlen(secret) + 1;
+ if (write(sock, secret, len) != len)
+ {
+ int e = errno;
+
+ fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
+ exit(RC_WHACK_PROBLEM);
+ }
}
/* This is a hack for initiating ISAKMP exchanges. */
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
- whack_message_t msg;
- char esp_buf[256]; /* uses snprintf */
- lset_t
- opts_seen = LEMPTY,
- sc_seen = LEMPTY,
- lst_seen = LEMPTY,
- cd_seen = LEMPTY,
- ca_seen = LEMPTY,
- end_seen = LEMPTY,
- end_seen_before_to = LEMPTY;
- const char
- *af_used_by = NULL,
- *tunnel_af_used_by = NULL;
-
- /* check division of numbering space */
+ whack_message_t msg;
+ char esp_buf[256]; /* uses snprintf */
+ lset_t
+ opts_seen = LEMPTY,
+ sc_seen = LEMPTY,
+ lst_seen = LEMPTY,
+ cd_seen = LEMPTY,
+ ca_seen = LEMPTY,
+ end_seen = LEMPTY,
+ end_seen_before_to = LEMPTY;
+ const char
+ *af_used_by = NULL,
+ *tunnel_af_used_by = NULL;
+
+ /* check division of numbering space */
#ifdef DEBUG
- assert(OPTION_OFFSET + DBGOPT_LAST < NUMERIC_ARG);
+ assert(OPTION_OFFSET + DBGOPT_LAST < NUMERIC_ARG);
#else
- assert(OPTION_OFFSET + CA_LAST < NUMERIC_ARG);
+ assert(OPTION_OFFSET + CA_LAST < NUMERIC_ARG);
#endif
- assert(OPT_LAST - OPT_FIRST < (sizeof opts_seen * BITS_PER_BYTE));
- assert(SC_LAST - SC_FIRST < (sizeof sc_seen * BITS_PER_BYTE));
- assert(LST_LAST - LST_FIRST < (sizeof lst_seen * BITS_PER_BYTE));
- assert(END_LAST - END_FIRST < (sizeof end_seen * BITS_PER_BYTE));
- assert(CD_LAST - CD_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
- assert(CA_LAST - CA_FIRST < (sizeof ca_seen * BITS_PER_BYTE));
-#ifdef DEBUG /* must be last so others are less than (sizeof cd_seen * BITS_PER_BYTE) to fit in lset_t */
- assert(DBGOPT_LAST - DBGOPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
+ assert(OPT_LAST - OPT_FIRST < (sizeof opts_seen * BITS_PER_BYTE));
+ assert(SC_LAST - SC_FIRST < (sizeof sc_seen * BITS_PER_BYTE));
+ assert(LST_LAST - LST_FIRST < (sizeof lst_seen * BITS_PER_BYTE));
+ assert(END_LAST - END_FIRST < (sizeof end_seen * BITS_PER_BYTE));
+ assert(CD_LAST - CD_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
+ assert(CA_LAST - CA_FIRST < (sizeof ca_seen * BITS_PER_BYTE));
+#ifdef DEBUG /* must be last so others are less than (sizeof cd_seen * BITS_PER_BYTE) to fit in lset_t */
+ assert(DBGOPT_LAST - DBGOPT_FIRST < (sizeof cd_seen * BITS_PER_BYTE));
#endif
- /* check that POLICY bit assignment matches with CD_ */
- assert(LELEM(CD_DONT_REKEY - CD_POLICY_FIRST) == POLICY_DONT_REKEY);
+ /* check that POLICY bit assignment matches with CD_ */
+ assert(LELEM(CD_DONT_REKEY - CD_POLICY_FIRST) == POLICY_DONT_REKEY);
- zero(&msg);
+ zero(&msg);
- clear_end(&msg.right); /* left set from this after --to */
+ clear_end(&msg.right); /* left set from this after --to */
- msg.name = NULL;
- msg.keyid = NULL;
- msg.keyval.ptr = NULL;
- msg.esp = NULL;
- msg.ike = NULL;
- msg.pfsgroup = NULL;
+ msg.name = NULL;
+ msg.keyid = NULL;
+ msg.keyval.ptr = NULL;
+ msg.esp = NULL;
+ msg.ike = NULL;
+ msg.pfsgroup = NULL;
/* if a connection is added via whack then we assume IKEv1 */
- msg.ikev1 = TRUE;
-
- msg.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
- msg.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
- msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
- msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
- msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
-
- msg.addr_family = AF_INET;
- msg.tunnel_addr_family = AF_INET;
-
- msg.cacert = NULL;
- msg.ldaphost = NULL;
- msg.ldapbase = NULL;
- msg.crluri = NULL;
- msg.crluri2 = NULL;
- msg.ocspuri = NULL;
-
- for (;;)
- {
- int long_index;
- unsigned long opt_whole = 0; /* numeric argument for some flags */
-
- /* Note: we don't like the way short options get parsed
- * by getopt_long, so we simply pass an empty string as
- * the list. It could be "hp:d:c:o:eatfs" "NARXPECK".
- */
- int c = getopt_long(argc, argv, "", long_opts, &long_index) - OPTION_OFFSET;
- int aux = 0;
+ msg.ikev1 = TRUE;
- /* decode a numeric argument, if expected */
- if (0 <= c)
- {
- if (c & NUMERIC_ARG)
- {
- char *endptr;
-
- c -= NUMERIC_ARG;
- opt_whole = strtoul(optarg, &endptr, 0);
-
- if (*endptr != '\0' || endptr == optarg)
- diagq("badly formed numeric argument", optarg);
- }
- if (c >= (1 << AUX_SHIFT))
- {
- aux = c >> AUX_SHIFT;
- c -= aux << AUX_SHIFT;
- }
- }
+ msg.sa_ike_life_seconds = OAKLEY_ISAKMP_SA_LIFETIME_DEFAULT;
+ msg.sa_ipsec_life_seconds = PLUTO_SA_LIFE_DURATION_DEFAULT;
+ msg.sa_rekey_margin = SA_REPLACEMENT_MARGIN_DEFAULT;
+ msg.sa_rekey_fuzz = SA_REPLACEMENT_FUZZ_DEFAULT;
+ msg.sa_keying_tries = SA_REPLACEMENT_RETRIES_DEFAULT;
- /* per-class option processing */
- if (0 <= c && c <= OPT_LAST)
- {
- /* OPT_* options get added to opts_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c);
-
- if (opts_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- opts_seen |= f;
- }
- else if (SC_FIRST <= c && c <= SC_LAST)
- {
- /* SC_* options get added to sc_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - SC_FIRST);
-
- if (sc_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- sc_seen |= f;
- }
- else if (LST_FIRST <= c && c <= LST_LAST)
+ msg.addr_family = AF_INET;
+ msg.tunnel_addr_family = AF_INET;
+
+ msg.cacert = NULL;
+ msg.ldaphost = NULL;
+ msg.ldapbase = NULL;
+ msg.crluri = NULL;
+ msg.crluri2 = NULL;
+ msg.ocspuri = NULL;
+
+ options = options_create();
+
+ for (;;)
{
- /* LST_* options get added to lst_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - LST_FIRST);
-
- if (lst_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- lst_seen |= f;
- }
+ int long_index;
+ unsigned long opt_whole = 0; /* numeric argument for some flags */
+
+ /* Note: we don't like the way short options get parsed
+ * by getopt_long, so we simply pass an empty string as
+ * the list. It could be "hp:d:c:o:eatfs" "NARXPECK".
+ */
+ int c = getopt_long(argc, argv, "", long_opts, &long_index) - OPTION_OFFSET;
+ int aux = 0;
+
+ /* decode a numeric argument, if expected */
+ if (0 <= c)
+ {
+ if (c & NUMERIC_ARG)
+ {
+ char *endptr;
+
+ c -= NUMERIC_ARG;
+ opt_whole = strtoul(optarg, &endptr, 0);
+
+ if (*endptr != '\0' || endptr == optarg)
+ diagq("badly formed numeric argument", optarg);
+ }
+ if (c >= (1 << AUX_SHIFT))
+ {
+ aux = c >> AUX_SHIFT;
+ c -= aux << AUX_SHIFT;
+ }
+ }
+
+ /* per-class option processing */
+ if (0 <= c && c <= OPT_LAST)
+ {
+ /* OPT_* options get added to opts_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c);
+
+ if (opts_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ opts_seen |= f;
+ }
+ else if (SC_FIRST <= c && c <= SC_LAST)
+ {
+ /* SC_* options get added to sc_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c - SC_FIRST);
+
+ if (sc_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ sc_seen |= f;
+ }
+ else if (LST_FIRST <= c && c <= LST_LAST)
+ {
+ /* LST_* options get added to lst_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c - LST_FIRST);
+
+ if (lst_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ lst_seen |= f;
+ }
#ifdef DEBUG
- else if (DBGOPT_FIRST <= c && c <= DBGOPT_LAST)
- {
- msg.whack_options = TRUE;
- }
+ else if (DBGOPT_FIRST <= c && c <= DBGOPT_LAST)
+ {
+ msg.whack_options = TRUE;
+ }
#endif
- else if (END_FIRST <= c && c <= END_LAST)
- {
- /* END_* options are added to end_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - END_FIRST);
-
- if (end_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- end_seen |= f;
- opts_seen |= LELEM(OPT_CD);
- }
- else if (CD_FIRST <= c && c <= CD_LAST)
- {
- /* CD_* options are added to cd_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - CD_FIRST);
-
- if (cd_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- cd_seen |= f;
- opts_seen |= LELEM(OPT_CD);
- }
- else if (CA_FIRST <= c && c <= CA_LAST)
- {
- /* CA_* options are added to ca_seen.
- * Reject repeated options (unless later code intervenes).
- */
- lset_t f = LELEM(c - CA_FIRST);
-
- if (ca_seen & f)
- diagq("duplicated flag", long_opts[long_index].name);
- ca_seen |= f;
- }
+ else if (END_FIRST <= c && c <= END_LAST)
+ {
+ /* END_* options are added to end_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c - END_FIRST);
+
+ if (end_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ end_seen |= f;
+ opts_seen |= LELEM(OPT_CD);
+ }
+ else if (CD_FIRST <= c && c <= CD_LAST)
+ {
+ /* CD_* options are added to cd_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c - CD_FIRST);
+
+ if (cd_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ cd_seen |= f;
+ opts_seen |= LELEM(OPT_CD);
+ }
+ else if (CA_FIRST <= c && c <= CA_LAST)
+ {
+ /* CA_* options are added to ca_seen.
+ * Reject repeated options (unless later code intervenes).
+ */
+ lset_t f = LELEM(c - CA_FIRST);
+
+ if (ca_seen & f)
+ diagq("duplicated flag", long_opts[long_index].name);
+ ca_seen |= f;
+ }
- /* Note: "break"ing from switch terminates loop.
- * most cases should end with "continue".
- */
- switch (c)
- {
- case EOF - OPTION_OFFSET: /* end of flags */
- break;
-
- case 0 - OPTION_OFFSET: /* long option already handled */
- continue;
-
- case ':' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
- case '?' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
- diag(NULL); /* print no additional diagnostic, but exit sadly */
- break; /* not actually reached */
-
- case 'h' - OPTION_OFFSET: /* --help */
- help();
- return 0; /* GNU coding standards say to stop here */
-
- case 'v' - OPTION_OFFSET: /* --version */
- {
- const char **sp = ipsec_copyright_notice();
-
- printf("%s\n", ipsec_version_string());
- for (; *sp != NULL; sp++)
- puts(*sp);
- }
- return 0; /* GNU coding standards say to stop here */
-
- case 'l' - OPTION_OFFSET: /* --label <string> */
- label = optarg; /* remember for diagnostics */
- continue;
-
- case '+' - OPTION_OFFSET: /* --optionsfrom <filename> */
- optionsfrom(optarg, &argc, &argv, optind, stderr);
- /* does not return on error */
- continue;
-
- /* the rest of the options combine in complex ways */
-
- case OPT_CTLBASE: /* --port <ctlbase> */
- if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
- , "%s%s", optarg, CTL_SUFFIX) == -1)
- diag("<ctlbase>" CTL_SUFFIX " must be fit in a sun_addr");
- continue;
-
- case OPT_NAME: /* --name <connection-name> */
- name = optarg;
- msg.name = optarg;
- continue;
-
- case OPT_KEYID: /* --keyid <identity> */
- msg.whack_key = !msg.whack_sc_op;
- msg.keyid = optarg; /* decoded by Pluto */
- continue;
-
- case OPT_MYID: /* --myid <identity> */
- msg.whack_myid = TRUE;
- msg.myid = optarg; /* decoded by Pluto */
- continue;
-
- case OPT_ADDKEY: /* --addkey */
- msg.whack_addkey = TRUE;
- continue;
-
- case OPT_PUBKEYRSA: /* --pubkeyrsa <key> */
- {
- static char keyspace[RSA_MAX_ENCODING_BYTES]; /* room for 8K bit key */
- char diag_space[TTODATAV_BUF];
- const char *ugh = ttodatav(optarg, 0, 0
- , keyspace, sizeof(keyspace)
- , &msg.keyval.len, diag_space, sizeof(diag_space)
- , TTODATAV_SPACECOUNTS);
-
- if (ugh != NULL)
+ /* Note: "break"ing from switch terminates loop.
+ * most cases should end with "continue".
+ */
+ switch (c)
{
- char ugh_space[80]; /* perhaps enough space */
+ case EOF - OPTION_OFFSET: /* end of flags */
+ break;
- snprintf(ugh_space, sizeof(ugh_space)
- , "RSA public-key data malformed (%s)", ugh);
- diagq(ugh_space, optarg);
- }
- msg.pubkey_alg = PUBKEY_ALG_RSA;
- msg.keyval.ptr = keyspace;
- }
- continue;
-
- case OPT_ROUTE: /* --route */
- msg.whack_route = TRUE;
- continue;
-
- case OPT_UNROUTE: /* --unroute */
- msg.whack_unroute = TRUE;
- continue;
-
- case OPT_INITIATE: /* --initiate */
- msg.whack_initiate = TRUE;
- continue;
-
- case OPT_TERMINATE: /* --terminate */
- msg.whack_terminate = TRUE;
- continue;
-
- case OPT_DELETE: /* --delete */
- msg.whack_delete = TRUE;
- continue;
-
- case OPT_DELETESTATE: /* --deletestate <state_object_number> */
- msg.whack_deletestate = TRUE;
- msg.whack_deletestateno = opt_whole;
- continue;
-
- case OPT_DELETECRASH: /* --crash <ip-address> */
- msg.whack_crash = TRUE;
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.whack_crash_peer), optarg);
- if (isanyaddr(&msg.whack_crash_peer))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_LISTEN: /* --listen */
- msg.whack_listen = TRUE;
- continue;
-
- case OPT_UNLISTEN: /* --unlisten */
- msg.whack_unlisten = TRUE;
- continue;
-
- case OPT_PURGEOCSP: /* --purgeocsp */
- msg.whack_purgeocsp = TRUE;
- continue;
-
- case OPT_REREADSECRETS: /* --rereadsecrets */
- case OPT_REREADCACERTS: /* --rereadcacerts */
- case OPT_REREADAACERTS: /* --rereadaacerts */
- case OPT_REREADOCSPCERTS: /* --rereadocspcerts */
- case OPT_REREADACERTS: /* --rereadacerts */
- case OPT_REREADCRLS: /* --rereadcrls */
- msg.whack_reread |= LELEM(c-OPT_REREADSECRETS);
- continue;
-
- case OPT_REREADALL: /* --rereadall */
- msg.whack_reread = REREAD_ALL;
- continue;
-
- case OPT_STATUSALL: /* --statusall */
- msg.whack_statusall = TRUE;
-
- case OPT_STATUS: /* --status */
- msg.whack_status = TRUE;
- continue;
-
- case OPT_SHUTDOWN: /* --shutdown */
- msg.whack_shutdown = TRUE;
- continue;
-
- case OPT_OPPO_HERE: /* --oppohere <ip-address> */
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_my_client), optarg);
- if (isanyaddr(&msg.oppo_my_client))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_OPPO_THERE: /* --oppohere <ip-address> */
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_peer_client), optarg);
- if (isanyaddr(&msg.oppo_peer_client))
- diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
- continue;
-
- case OPT_ASYNC:
- msg.whack_async = TRUE;
- continue;
-
- /* Smartcard options */
-
- case SC_ENCRYPT: /* --scencrypt <plaintext data> */
- case SC_DECRYPT: /* --scdecrypt <encrypted data> */
- msg.whack_sc_op = 1 + c - SC_ENCRYPT;
- msg.whack_key = FALSE;
- msg.sc_data = optarg;
- continue;
-
- case SC_INBASE: /* --inform <format> */
- case SC_OUTBASE: /* --outform <format> */
- {
- int base = 0;
-
- if (streq(optarg, "16") || strcaseeq(optarg, "hex"))
- base = 16;
- else if (streq(optarg, "64") || strcaseeq(optarg, "base64"))
- base = 64;
- else if (streq(optarg, "256") || strcaseeq(optarg, "text")
- || strcaseeq(optarg, "ascii"))
- base = 256;
- else
- diagq("not a valid base", optarg);
+ case 0 - OPTION_OFFSET: /* long option already handled */
+ continue;
+
+ case ':' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
+ case '?' - OPTION_OFFSET: /* diagnostic already printed by getopt_long */
+ diag(NULL); /* print no additional diagnostic, but exit sadly */
+ break; /* not actually reached */
+
+ case 'h' - OPTION_OFFSET: /* --help */
+ help();
+ whack_exit(0); /* GNU coding standards say to stop here */
+
+ case 'v' - OPTION_OFFSET: /* --version */
+ {
+ const char **sp = ipsec_copyright_notice();
+
+ printf("strongSwan "VERSION"\n");
+ for (; *sp != NULL; sp++)
+ puts(*sp);
+ }
+ whack_exit(0); /* GNU coding standards say to stop here */
+
+ case 'l' - OPTION_OFFSET: /* --label <string> */
+ label = optarg; /* remember for diagnostics */
+ continue;
+
+ case '+' - OPTION_OFFSET: /* --optionsfrom <filename> */
+ if (!options->from(options, optarg, &argc, &argv, optind))
+ {
+ fprintf(stderr, "optionsfrom failed");
+ whack_exit(RC_WHACK_PROBLEM);
+ }
+ continue;
+
+ /* the rest of the options combine in complex ways */
+
+ case OPT_CTLBASE: /* --port <ctlbase> */
+ if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path)
+ , "%s%s", optarg, CTL_SUFFIX) == -1)
+ diag("<ctlbase>" CTL_SUFFIX " must be fit in a sun_addr");
+ continue;
+
+ case OPT_NAME: /* --name <connection-name> */
+ name = optarg;
+ msg.name = optarg;
+ continue;
+
+ case OPT_KEYID: /* --keyid <identity> */
+ msg.whack_key = !msg.whack_sc_op;
+ msg.keyid = optarg; /* decoded by Pluto */
+ continue;
+
+ case OPT_MYID: /* --myid <identity> */
+ msg.whack_myid = TRUE;
+ msg.myid = optarg; /* decoded by Pluto */
+ continue;
+
+ case OPT_ADDKEY: /* --addkey */
+ msg.whack_addkey = TRUE;
+ continue;
+
+ case OPT_PUBKEYRSA: /* --pubkeyrsa <key> */
+ {
+ static char keyspace[RSA_MAX_ENCODING_BYTES]; /* room for 8K bit key */
+ char diag_space[TTODATAV_BUF];
+ const char *ugh = ttodatav(optarg, 0, 0
+ , keyspace, sizeof(keyspace)
+ , &msg.keyval.len, diag_space, sizeof(diag_space)
+ , TTODATAV_SPACECOUNTS);
+
+ if (ugh != NULL)
+ {
+ char ugh_space[80]; /* perhaps enough space */
+
+ snprintf(ugh_space, sizeof(ugh_space)
+ , "RSA public-key data malformed (%s)", ugh);
+ diagq(ugh_space, optarg);
+ }
+ msg.pubkey_alg = PUBKEY_ALG_RSA;
+ msg.keyval.ptr = keyspace;
+ }
+ continue;
+
+ case OPT_ROUTE: /* --route */
+ msg.whack_route = TRUE;
+ continue;
+
+ case OPT_UNROUTE: /* --unroute */
+ msg.whack_unroute = TRUE;
+ continue;
+
+ case OPT_INITIATE: /* --initiate */
+ msg.whack_initiate = TRUE;
+ continue;
+
+ case OPT_TERMINATE: /* --terminate */
+ msg.whack_terminate = TRUE;
+ continue;
+
+ case OPT_DELETE: /* --delete */
+ msg.whack_delete = TRUE;
+ continue;
+
+ case OPT_DELETESTATE: /* --deletestate <state_object_number> */
+ msg.whack_deletestate = TRUE;
+ msg.whack_deletestateno = opt_whole;
+ continue;
+
+ case OPT_DELETECRASH: /* --crash <ip-address> */
+ msg.whack_crash = TRUE;
+ tunnel_af_used_by = long_opts[long_index].name;
+ diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.whack_crash_peer), optarg);
+ if (isanyaddr(&msg.whack_crash_peer))
+ diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
+ continue;
+
+ case OPT_LISTEN: /* --listen */
+ msg.whack_listen = TRUE;
+ continue;
+
+ case OPT_UNLISTEN: /* --unlisten */
+ msg.whack_unlisten = TRUE;
+ continue;
+
+ case OPT_PURGEOCSP: /* --purgeocsp */
+ msg.whack_purgeocsp = TRUE;
+ continue;
+
+ case OPT_REREADSECRETS: /* --rereadsecrets */
+ case OPT_REREADCACERTS: /* --rereadcacerts */
+ case OPT_REREADAACERTS: /* --rereadaacerts */
+ case OPT_REREADOCSPCERTS: /* --rereadocspcerts */
+ case OPT_REREADACERTS: /* --rereadacerts */
+ case OPT_REREADCRLS: /* --rereadcrls */
+ msg.whack_reread |= LELEM(c-OPT_REREADSECRETS);
+ continue;
+
+ case OPT_REREADALL: /* --rereadall */
+ msg.whack_reread = REREAD_ALL;
+ continue;
+
+ case OPT_STATUSALL: /* --statusall */
+ msg.whack_statusall = TRUE;
+
+ case OPT_STATUS: /* --status */
+ msg.whack_status = TRUE;
+ continue;
- if (c == SC_INBASE)
- msg.inbase = base;
- else
- msg.outbase = base;
- }
- continue;
-
- /* List options */
-
- case LST_UTC: /* --utc */
- msg.whack_utc = TRUE;
- continue;
-
- case LST_ALGS: /* --listalgs */
- case LST_PUBKEYS: /* --listpubkeys */
- case LST_CERTS: /* --listcerts */
- case LST_CACERTS: /* --listcacerts */
- case LST_ACERTS: /* --listacerts */
- case LST_AACERTS: /* --listaacerts */
- case LST_OCSPCERTS: /* --listocspcerts */
- case LST_GROUPS: /* --listgroups */
- case LST_CAINFOS: /* --listcainfos */
- case LST_CRLS: /* --listcrls */
- case LST_OCSP: /* --listocsp */
- case LST_CARDS: /* --listcards */
- msg.whack_list |= LELEM(c - LST_ALGS);
- continue;
-
- case LST_ALL: /* --listall */
- msg.whack_list = LIST_ALL;
- continue;
-
- /* Connection Description options */
-
- case END_HOST: /* --host <ip-address> */
- {
- lset_t new_policy = LEMPTY;
-
- af_used_by = long_opts[long_index].name;
- diagq(anyaddr(msg.addr_family, &msg.right.host_addr), optarg);
- if (streq(optarg, "%any"))
- {
- }
- else if (streq(optarg, "%opportunistic"))
- {
- /* always use tunnel mode; mark as opportunistic */
- new_policy |= POLICY_TUNNEL | POLICY_OPPO;
- }
- else if (streq(optarg, "%group"))
- {
- /* always use tunnel mode; mark as group */
- new_policy |= POLICY_TUNNEL | POLICY_GROUP;
- }
- else if (streq(optarg, "%opportunisticgroup"))
- {
- /* always use tunnel mode; mark as opportunistic */
- new_policy |= POLICY_TUNNEL | POLICY_OPPO | POLICY_GROUP;
- }
- else
- {
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_addr), optarg);
- }
-
- msg.policy |= new_policy;
-
- if (new_policy & (POLICY_OPPO | POLICY_GROUP))
- {
- if (!LHAS(end_seen, END_CLIENT - END_FIRST))
+ case OPT_SHUTDOWN: /* --shutdown */
+ msg.whack_shutdown = TRUE;
+ continue;
+
+ case OPT_OPPO_HERE: /* --oppohere <ip-address> */
+ tunnel_af_used_by = long_opts[long_index].name;
+ diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_my_client), optarg);
+ if (isanyaddr(&msg.oppo_my_client))
+ diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
+ continue;
+
+ case OPT_OPPO_THERE: /* --oppohere <ip-address> */
+ tunnel_af_used_by = long_opts[long_index].name;
+ diagq(ttoaddr(optarg, 0, msg.tunnel_addr_family, &msg.oppo_peer_client), optarg);
+ if (isanyaddr(&msg.oppo_peer_client))
+ diagq("0.0.0.0 or 0::0 isn't a valid client address", optarg);
+ continue;
+
+ case OPT_ASYNC:
+ msg.whack_async = TRUE;
+ continue;
+
+ /* Smartcard options */
+
+ case SC_ENCRYPT: /* --scencrypt <plaintext data> */
+ case SC_DECRYPT: /* --scdecrypt <encrypted data> */
+ msg.whack_sc_op = 1 + c - SC_ENCRYPT;
+ msg.whack_key = FALSE;
+ msg.sc_data = optarg;
+ continue;
+
+ case SC_INBASE: /* --inform <format> */
+ case SC_OUTBASE: /* --outform <format> */
+ {
+ int base = 0;
+
+ if (streq(optarg, "16") || strcaseeq(optarg, "hex"))
+ base = 16;
+ else if (streq(optarg, "64") || strcaseeq(optarg, "base64"))
+ base = 64;
+ else if (streq(optarg, "256") || strcaseeq(optarg, "text")
+ || strcaseeq(optarg, "ascii"))
+ base = 256;
+ else
+ diagq("not a valid base", optarg);
+
+ if (c == SC_INBASE)
+ msg.inbase = base;
+ else
+ msg.outbase = base;
+ }
+ continue;
+
+ /* List options */
+
+ case LST_UTC: /* --utc */
+ msg.whack_utc = TRUE;
+ continue;
+
+ case LST_ALGS: /* --listalgs */
+ case LST_PUBKEYS: /* --listpubkeys */
+ case LST_CERTS: /* --listcerts */
+ case LST_CACERTS: /* --listcacerts */
+ case LST_ACERTS: /* --listacerts */
+ case LST_AACERTS: /* --listaacerts */
+ case LST_OCSPCERTS: /* --listocspcerts */
+ case LST_GROUPS: /* --listgroups */
+ case LST_CAINFOS: /* --listcainfos */
+ case LST_CRLS: /* --listcrls */
+ case LST_OCSP: /* --listocsp */
+ case LST_CARDS: /* --listcards */
+ msg.whack_list |= LELEM(c - LST_ALGS);
+ continue;
+
+ case LST_ALL: /* --listall */
+ msg.whack_list = LIST_ALL;
+ continue;
+
+ /* Connection Description options */
+
+ case END_HOST: /* --host <ip-address> */
{
- /* set host to 0.0.0 and --client to 0.0.0.0/0
- * or IPV6 equivalent
- */
- ip_address any;
-
- tunnel_af_used_by = optarg;
- diagq(anyaddr(msg.tunnel_addr_family, &any), optarg);
- diagq(initsubnet(&any, 0, '0', &msg.right.client), optarg);
+ lset_t new_policy = LEMPTY;
+
+ af_used_by = long_opts[long_index].name;
+ diagq(anyaddr(msg.addr_family, &msg.right.host_addr), optarg);
+ if (streq(optarg, "%any"))
+ {
+ }
+ else if (streq(optarg, "%opportunistic"))
+ {
+ /* always use tunnel mode; mark as opportunistic */
+ new_policy |= POLICY_TUNNEL | POLICY_OPPO;
+ }
+ else if (streq(optarg, "%group"))
+ {
+ /* always use tunnel mode; mark as group */
+ new_policy |= POLICY_TUNNEL | POLICY_GROUP;
+ }
+ else if (streq(optarg, "%opportunisticgroup"))
+ {
+ /* always use tunnel mode; mark as opportunistic */
+ new_policy |= POLICY_TUNNEL | POLICY_OPPO | POLICY_GROUP;
+ }
+ else
+ {
+ diagq(ttoaddr(optarg, 0, msg.addr_family
+ , &msg.right.host_addr), optarg);
+ }
+
+ msg.policy |= new_policy;
+
+ if (new_policy & (POLICY_OPPO | POLICY_GROUP))
+ {
+ if (!LHAS(end_seen, END_CLIENT - END_FIRST))
+ {
+ /* set host to 0.0.0 and --client to 0.0.0.0/0
+ * or IPV6 equivalent
+ */
+ ip_address any;
+
+ tunnel_af_used_by = optarg;
+ diagq(anyaddr(msg.tunnel_addr_family, &any), optarg);
+ diagq(initsubnet(&any, 0, '0', &msg.right.client), optarg);
+ }
+ msg.right.has_client = TRUE;
+ }
+ if (new_policy & POLICY_GROUP)
+ {
+ /* client subnet must not be specified by user:
+ * it will come from the group's file.
+ */
+ if (LHAS(end_seen, END_CLIENT - END_FIRST))
+ diag("--host %group clashes with --client");
+
+ end_seen |= LELEM(END_CLIENT - END_FIRST);
+ }
+ if (new_policy & POLICY_OPPO)
+ msg.right.key_from_DNS_on_demand = TRUE;
+ continue;
}
- msg.right.has_client = TRUE;
- }
- if (new_policy & POLICY_GROUP)
- {
- /* client subnet must not be specified by user:
- * it will come from the group's file.
+ case END_ID: /* --id <identity> */
+ msg.right.id = optarg; /* decoded by Pluto */
+ continue;
+
+ case END_CERT: /* --cert <path> */
+ msg.right.cert = optarg; /* decoded by Pluto */
+ continue;
+
+ case END_CA: /* --ca <distinguished name> */
+ msg.right.ca = optarg; /* decoded by Pluto */
+ continue;
+
+ case END_SENDCERT:
+ if (streq(optarg, "yes") || streq(optarg, "always"))
+ {
+ msg.right.sendcert = CERT_ALWAYS_SEND;
+ }
+ else if (streq(optarg, "no") || streq(optarg, "never"))
+ {
+ msg.right.sendcert = CERT_NEVER_SEND;
+ }
+ else if (streq(optarg, "ifasked"))
+ {
+ msg.right.sendcert = CERT_SEND_IF_ASKED;
+ }
+ else
+ {
+ diagq("whack sendcert value is not legal", optarg);
+ }
+ continue;
+
+ case END_GROUPS:/* --groups <access control groups> */
+ msg.right.groups = optarg; /* decoded by Pluto */
+ continue;
+
+ case END_IKEPORT: /* --ikeport <port-number> */
+ if (opt_whole<=0 || opt_whole >= 0x10000)
+ diagq("<port-number> must be a number between 1 and 65535", optarg);
+ msg.right.host_port = opt_whole;
+ continue;
+
+ case END_NEXTHOP: /* --nexthop <ip-address> */
+ af_used_by = long_opts[long_index].name;
+ if (streq(optarg, "%direct"))
+ diagq(anyaddr(msg.addr_family
+ , &msg.right.host_nexthop), optarg);
+ else
+ diagq(ttoaddr(optarg, 0, msg.addr_family
+ , &msg.right.host_nexthop), optarg);
+ continue;
+
+ case END_SRCIP: /* --srcip <ip-address> */
+ af_used_by = long_opts[long_index].name;
+ if (streq(optarg, "%modeconfig") || streq(optarg, "%modecfg"))
+ {
+ msg.right.modecfg = TRUE;
+ }
+ else
+ {
+ diagq(ttoaddr(optarg, 0, msg.addr_family
+ , &msg.right.host_srcip), optarg);
+ msg.right.has_srcip = TRUE;
+ }
+ msg.policy |= POLICY_TUNNEL; /* srcip => tunnel */
+ continue;
+
+ case END_CLIENT: /* --client <subnet> */
+ if (end_seen & LELEM(END_CLIENTWITHIN - END_FIRST))
+ diag("--client conflicts with --clientwithin");
+ tunnel_af_used_by = long_opts[long_index].name;
+ if ((strlen(optarg) >= 6 && strncmp(optarg,"vhost:",6) == 0)
+ || (strlen(optarg) >= 5 && strncmp(optarg,"vnet:",5) == 0))
+ {
+ msg.right.virt = optarg;
+ }
+ else
+ {
+ diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
+ msg.right.has_client = TRUE;
+ }
+ msg.policy |= POLICY_TUNNEL; /* client => tunnel */
+ continue;
+
+ case END_CLIENTWITHIN: /* --clienwithin <address range> */
+ if (end_seen & LELEM(END_CLIENT - END_FIRST))
+ diag("--clientwithin conflicts with --client");
+ tunnel_af_used_by = long_opts[long_index].name;
+ diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
+ msg.right.has_client = TRUE;
+ msg.policy |= POLICY_TUNNEL; /* client => tunnel */
+ msg.right.has_client_wildcard = TRUE;
+ continue;
+
+ case END_CLIENTPROTOPORT: /* --clientprotoport <protocol>/<port> */
+ diagq(ttoprotoport(optarg, 0, &msg.right.protocol, &msg.right.port
+ , &msg.right.has_port_wildcard), optarg);
+ continue;
+
+ case END_DNSKEYONDEMAND: /* --dnskeyondemand */
+ msg.right.key_from_DNS_on_demand = TRUE;
+ continue;
+
+ case END_HOSTACCESS: /* --hostaccess */
+ msg.right.hostaccess = TRUE;
+ continue;
+
+ case END_UPDOWN: /* --updown <updown> */
+ msg.right.updown = optarg;
+ continue;
+
+ case CD_TO: /* --to */
+ /* process right end, move it to left, reset it */
+ if (!LHAS(end_seen, END_HOST - END_FIRST))
+ diag("connection missing --host before --to");
+ msg.left = msg.right;
+ clear_end(&msg.right);
+ end_seen_before_to = end_seen;
+ end_seen = LEMPTY;
+ continue;
+
+ case CD_PSK: /* --psk */
+ case CD_RSASIG: /* --rsasig */
+ case CD_ENCRYPT: /* --encrypt */
+ case CD_AUTHENTICATE: /* --authenticate */
+ case CD_COMPRESS: /* --compress */
+ case CD_TUNNEL: /* --tunnel */
+ case CD_PFS: /* --pfs */
+ case CD_DISABLEARRIVALCHECK: /* --disablearrivalcheck */
+ case CD_DONT_REKEY: /* --donotrekey */
+ msg.policy |= LELEM(c - CD_POLICY_FIRST);
+ continue;
+
+ /* --initiateontraffic
+ * --pass
+ * --drop
+ * --reject
*/
- if (LHAS(end_seen, END_CLIENT - END_FIRST))
- diag("--host %group clashes with --client");
-
- end_seen |= LELEM(END_CLIENT - END_FIRST);
- }
- if (new_policy & POLICY_OPPO)
- msg.right.key_from_DNS_on_demand = TRUE;
- continue;
- }
- case END_ID: /* --id <identity> */
- msg.right.id = optarg; /* decoded by Pluto */
- continue;
-
- case END_CERT: /* --cert <path> */
- msg.right.cert = optarg; /* decoded by Pluto */
- continue;
-
- case END_CA: /* --ca <distinguished name> */
- msg.right.ca = optarg; /* decoded by Pluto */
- continue;
-
- case END_SENDCERT:
- if (streq(optarg, "yes") || streq(optarg, "always"))
- {
- msg.right.sendcert = CERT_ALWAYS_SEND;
- }
- else if (streq(optarg, "no") || streq(optarg, "never"))
- {
- msg.right.sendcert = CERT_NEVER_SEND;
- }
- else if (streq(optarg, "ifasked"))
- {
- msg.right.sendcert = CERT_SEND_IF_ASKED;
- }
- else
- {
- diagq("whack sendcert value is not legal", optarg);
- }
- continue;
-
- case END_GROUPS:/* --groups <access control groups> */
- msg.right.groups = optarg; /* decoded by Pluto */
- continue;
-
- case END_IKEPORT: /* --ikeport <port-number> */
- if (opt_whole<=0 || opt_whole >= 0x10000)
- diagq("<port-number> must be a number between 1 and 65535", optarg);
- msg.right.host_port = opt_whole;
- continue;
-
- case END_NEXTHOP: /* --nexthop <ip-address> */
- af_used_by = long_opts[long_index].name;
- if (streq(optarg, "%direct"))
- diagq(anyaddr(msg.addr_family
- , &msg.right.host_nexthop), optarg);
- else
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_nexthop), optarg);
- continue;
-
- case END_SRCIP: /* --srcip <ip-address> */
- af_used_by = long_opts[long_index].name;
- if (streq(optarg, "%modeconfig") || streq(optarg, "%modecfg"))
- {
- msg.right.modecfg = TRUE;
- }
- else
- {
- diagq(ttoaddr(optarg, 0, msg.addr_family
- , &msg.right.host_srcip), optarg);
- msg.right.has_srcip = TRUE;
- }
- msg.policy |= POLICY_TUNNEL; /* srcip => tunnel */
- continue;
-
- case END_CLIENT: /* --client <subnet> */
- if (end_seen & LELEM(END_CLIENTWITHIN - END_FIRST))
- diag("--client conflicts with --clientwithin");
- tunnel_af_used_by = long_opts[long_index].name;
- if ((strlen(optarg) >= 6 && strncmp(optarg,"vhost:",6) == 0)
- || (strlen(optarg) >= 5 && strncmp(optarg,"vnet:",5) == 0))
- {
- msg.right.virt = optarg;
- }
- else
- {
- diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
- msg.right.has_client = TRUE;
- }
- msg.policy |= POLICY_TUNNEL; /* client => tunnel */
- continue;
-
- case END_CLIENTWITHIN: /* --clienwithin <address range> */
- if (end_seen & LELEM(END_CLIENT - END_FIRST))
- diag("--clientwithin conflicts with --client");
- tunnel_af_used_by = long_opts[long_index].name;
- diagq(ttosubnet(optarg, 0, msg.tunnel_addr_family, &msg.right.client), optarg);
- msg.right.has_client = TRUE;
- msg.policy |= POLICY_TUNNEL; /* client => tunnel */
- msg.right.has_client_wildcard = TRUE;
- continue;
-
- case END_CLIENTPROTOPORT: /* --clientprotoport <protocol>/<port> */
- diagq(ttoprotoport(optarg, 0, &msg.right.protocol, &msg.right.port
- , &msg.right.has_port_wildcard), optarg);
- continue;
-
- case END_DNSKEYONDEMAND: /* --dnskeyondemand */
- msg.right.key_from_DNS_on_demand = TRUE;
- continue;
-
- case END_HOSTACCESS: /* --hostaccess */
- msg.right.hostaccess = TRUE;
- continue;
-
- case END_UPDOWN: /* --updown <updown> */
- msg.right.updown = optarg;
- continue;
-
- case CD_TO: /* --to */
- /* process right end, move it to left, reset it */
- if (!LHAS(end_seen, END_HOST - END_FIRST))
- diag("connection missing --host before --to");
- msg.left = msg.right;
- clear_end(&msg.right);
- end_seen_before_to = end_seen;
- end_seen = LEMPTY;
- continue;
-
- case CD_PSK: /* --psk */
- case CD_RSASIG: /* --rsasig */
- case CD_ENCRYPT: /* --encrypt */
- case CD_AUTHENTICATE: /* --authenticate */
- case CD_COMPRESS: /* --compress */
- case CD_TUNNEL: /* --tunnel */
- case CD_PFS: /* --pfs */
- case CD_DISABLEARRIVALCHECK: /* --disablearrivalcheck */
- case CD_DONT_REKEY: /* --donotrekey */
- msg.policy |= LELEM(c - CD_POLICY_FIRST);
- continue;
-
- /* --initiateontraffic
- * --pass
- * --drop
- * --reject
- */
- case CD_SHUNT0:
- msg.policy = (msg.policy & ~POLICY_SHUNT_MASK)
- | ((lset_t)aux << POLICY_SHUNT_SHIFT);
- continue;
-
- /* --failnone
- * --failpass
- * --faildrop
- * --failreject
- */
- case CD_FAIL0:
- msg.policy = (msg.policy & ~POLICY_FAIL_MASK)
- | ((lset_t)aux << POLICY_FAIL_SHIFT);
- continue;
-
- case CD_IKELIFETIME: /* --ikelifetime <seconds> */
- msg.sa_ike_life_seconds = opt_whole;
- continue;
-
- case CD_IPSECLIFETIME: /* --ipseclifetime <seconds> */
- msg.sa_ipsec_life_seconds = opt_whole;
- continue;
-
- case CD_RKMARGIN: /* --rekeymargin <seconds> */
- msg.sa_rekey_margin = opt_whole;
- continue;
-
- case CD_RKFUZZ: /* --rekeyfuzz <percentage> */
- msg.sa_rekey_fuzz = opt_whole;
- continue;
-
- case CD_KTRIES: /* --keyingtries <count> */
- msg.sa_keying_tries = opt_whole;
- continue;
-
- case CD_DPDACTION:
- if (streq(optarg, "none"))
- msg.dpd_action = DPD_ACTION_NONE;
- else if (streq(optarg, "clear"))
- msg.dpd_action = DPD_ACTION_CLEAR;
- else if (streq(optarg, "hold"))
- msg.dpd_action = DPD_ACTION_HOLD;
- else if (streq(optarg, "restart"))
- msg.dpd_action = DPD_ACTION_RESTART;
- else
- msg.dpd_action = DPD_ACTION_UNKNOWN;
- continue;
-
- case CD_DPDDELAY:
- msg.dpd_delay = opt_whole;
- continue;
-
- case CD_DPDTIMEOUT:
- msg.dpd_timeout = opt_whole;
- continue;
-
- case CD_IKE: /* --ike <ike_alg1,ike_alg2,...> */
- msg.ike = optarg;
- continue;
-
- case CD_PFSGROUP: /* --pfsgroup modpXXXX */
- msg.pfsgroup = optarg;
- continue;
-
- case CD_ESP: /* --esp <esp_alg1,esp_alg2,...> */
- msg.esp = optarg;
- continue;
-
- case CD_CONNIPV4:
- if (LHAS(cd_seen, CD_CONNIPV6 - CD_FIRST))
- diag("--ipv4 conflicts with --ipv6");
-
- /* Since this is the default, the flag is redundant.
- * So we don't need to set msg.addr_family
- * and we don't need to check af_used_by
- * and we don't have to consider defaulting tunnel_addr_family.
- */
- continue;
-
- case CD_CONNIPV6:
- if (LHAS(cd_seen, CD_CONNIPV4 - CD_FIRST))
- diag("--ipv6 conflicts with --ipv4");
-
- if (af_used_by != NULL)
- diagq("--ipv6 must precede", af_used_by);
-
- af_used_by = long_opts[long_index].name;
- msg.addr_family = AF_INET6;
-
- /* Consider defaulting tunnel_addr_family to AF_INET6.
- * Do so only if it hasn't yet been specified or used.
- */
- if (LDISJOINT(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST))
- && tunnel_af_used_by == NULL)
- msg.tunnel_addr_family = AF_INET6;
- continue;
-
- case CD_TUNNELIPV4:
- if (LHAS(cd_seen, CD_TUNNELIPV6 - CD_FIRST))
- diag("--tunnelipv4 conflicts with --tunnelipv6");
-
- if (tunnel_af_used_by != NULL)
- diagq("--tunnelipv4 must precede", af_used_by);
-
- msg.tunnel_addr_family = AF_INET;
- continue;
-
- case CD_TUNNELIPV6:
- if (LHAS(cd_seen, CD_TUNNELIPV4 - CD_FIRST))
- diag("--tunnelipv6 conflicts with --tunnelipv4");
-
- if (tunnel_af_used_by != NULL)
- diagq("--tunnelipv6 must precede", af_used_by);
-
- msg.tunnel_addr_family = AF_INET6;
- continue;
-
- case CA_NAME: /* --caname <name> */
- msg.name = optarg;
- msg.whack_ca = TRUE;
- continue;
- case CA_CERT: /* --cacert <path> */
- msg.cacert = optarg;
- continue;
- case CA_LDAPHOST: /* --ldaphost <hostname> */
- msg.ldaphost = optarg;
- continue;
- case CA_LDAPBASE: /* --ldapbase <base> */
- msg.ldapbase = optarg;
- continue;
- case CA_CRLURI: /* --crluri <uri> */
- msg.crluri = optarg;
- continue;
- case CA_CRLURI2: /* --crluri2 <uri> */
- msg.crluri2 = optarg;
- continue;
- case CA_OCSPURI: /* --ocspuri <uri> */
- msg.ocspuri = optarg;
- continue;
- case CA_STRICT: /* --strictcrlpolicy */
- msg.whack_strict = TRUE;
- continue;
+ case CD_SHUNT0:
+ msg.policy = (msg.policy & ~POLICY_SHUNT_MASK)
+ | ((lset_t)aux << POLICY_SHUNT_SHIFT);
+ continue;
+
+ /* --failnone
+ * --failpass
+ * --faildrop
+ * --failreject
+ */
+ case CD_FAIL0:
+ msg.policy = (msg.policy & ~POLICY_FAIL_MASK)
+ | ((lset_t)aux << POLICY_FAIL_SHIFT);
+ continue;
+
+ case CD_IKELIFETIME: /* --ikelifetime <seconds> */
+ msg.sa_ike_life_seconds = opt_whole;
+ continue;
+
+ case CD_IPSECLIFETIME: /* --ipseclifetime <seconds> */
+ msg.sa_ipsec_life_seconds = opt_whole;
+ continue;
+
+ case CD_RKMARGIN: /* --rekeymargin <seconds> */
+ msg.sa_rekey_margin = opt_whole;
+ continue;
+
+ case CD_RKFUZZ: /* --rekeyfuzz <percentage> */
+ msg.sa_rekey_fuzz = opt_whole;
+ continue;
+
+ case CD_KTRIES: /* --keyingtries <count> */
+ msg.sa_keying_tries = opt_whole;
+ continue;
+
+ case CD_DPDACTION:
+ if (streq(optarg, "none"))
+ msg.dpd_action = DPD_ACTION_NONE;
+ else if (streq(optarg, "clear"))
+ msg.dpd_action = DPD_ACTION_CLEAR;
+ else if (streq(optarg, "hold"))
+ msg.dpd_action = DPD_ACTION_HOLD;
+ else if (streq(optarg, "restart"))
+ msg.dpd_action = DPD_ACTION_RESTART;
+ else
+ msg.dpd_action = DPD_ACTION_UNKNOWN;
+ continue;
+
+ case CD_DPDDELAY:
+ msg.dpd_delay = opt_whole;
+ continue;
+
+ case CD_DPDTIMEOUT:
+ msg.dpd_timeout = opt_whole;
+ continue;
+
+ case CD_IKE: /* --ike <ike_alg1,ike_alg2,...> */
+ msg.ike = optarg;
+ continue;
+
+ case CD_PFSGROUP: /* --pfsgroup modpXXXX */
+ msg.pfsgroup = optarg;
+ continue;
+
+ case CD_ESP: /* --esp <esp_alg1,esp_alg2,...> */
+ msg.esp = optarg;
+ continue;
+
+ case CD_CONNIPV4:
+ if (LHAS(cd_seen, CD_CONNIPV6 - CD_FIRST))
+ diag("--ipv4 conflicts with --ipv6");
+
+ /* Since this is the default, the flag is redundant.
+ * So we don't need to set msg.addr_family
+ * and we don't need to check af_used_by
+ * and we don't have to consider defaulting tunnel_addr_family.
+ */
+ continue;
+
+ case CD_CONNIPV6:
+ if (LHAS(cd_seen, CD_CONNIPV4 - CD_FIRST))
+ diag("--ipv6 conflicts with --ipv4");
+
+ if (af_used_by != NULL)
+ diagq("--ipv6 must precede", af_used_by);
+
+ af_used_by = long_opts[long_index].name;
+ msg.addr_family = AF_INET6;
+
+ /* Consider defaulting tunnel_addr_family to AF_INET6.
+ * Do so only if it hasn't yet been specified or used.
+ */
+ if (LDISJOINT(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST))
+ && tunnel_af_used_by == NULL)
+ msg.tunnel_addr_family = AF_INET6;
+ continue;
+
+ case CD_TUNNELIPV4:
+ if (LHAS(cd_seen, CD_TUNNELIPV6 - CD_FIRST))
+ diag("--tunnelipv4 conflicts with --tunnelipv6");
+
+ if (tunnel_af_used_by != NULL)
+ diagq("--tunnelipv4 must precede", af_used_by);
+
+ msg.tunnel_addr_family = AF_INET;
+ continue;
+
+ case CD_TUNNELIPV6:
+ if (LHAS(cd_seen, CD_TUNNELIPV4 - CD_FIRST))
+ diag("--tunnelipv6 conflicts with --tunnelipv4");
+
+ if (tunnel_af_used_by != NULL)
+ diagq("--tunnelipv6 must precede", af_used_by);
+
+ msg.tunnel_addr_family = AF_INET6;
+ continue;
+
+ case CA_NAME: /* --caname <name> */
+ msg.name = optarg;
+ msg.whack_ca = TRUE;
+ continue;
+ case CA_CERT: /* --cacert <path> */
+ msg.cacert = optarg;
+ continue;
+ case CA_LDAPHOST: /* --ldaphost <hostname> */
+ msg.ldaphost = optarg;
+ continue;
+ case CA_LDAPBASE: /* --ldapbase <base> */
+ msg.ldapbase = optarg;
+ continue;
+ case CA_CRLURI: /* --crluri <uri> */
+ msg.crluri = optarg;
+ continue;
+ case CA_CRLURI2: /* --crluri2 <uri> */
+ msg.crluri2 = optarg;
+ continue;
+ case CA_OCSPURI: /* --ocspuri <uri> */
+ msg.ocspuri = optarg;
+ continue;
+ case CA_STRICT: /* --strictcrlpolicy */
+ msg.whack_strict = TRUE;
+ continue;
#ifdef DEBUG
- case DBGOPT_NONE: /* --debug-none */
- msg.debugging = DBG_NONE;
- continue;
-
- case DBGOPT_ALL: /* --debug-all */
- msg.debugging |= DBG_ALL; /* note: does not include PRIVATE */
- continue;
-
- case DBGOPT_RAW: /* --debug-raw */
- case DBGOPT_CRYPT: /* --debug-crypt */
- case DBGOPT_PARSING: /* --debug-parsing */
- case DBGOPT_EMITTING: /* --debug-emitting */
- case DBGOPT_CONTROL: /* --debug-control */
- case DBGOPT_LIFECYCLE: /* --debug-lifecycle */
- case DBGOPT_KLIPS: /* --debug-klips */
- case DBGOPT_DNS: /* --debug-dns */
- case DBGOPT_NATT: /* --debug-natt */
- case DBGOPT_OPPO: /* --debug-oppo */
- case DBGOPT_CONTROLMORE: /* --debug-controlmore */
- case DBGOPT_PRIVATE: /* --debug-private */
- case DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER: /* --impair-delay-adns-key-answer */
- case DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER: /* --impair-delay-adns-txt-answer */
- case DBGOPT_IMPAIR_BUST_MI2: /* --impair_bust_mi2 */
- case DBGOPT_IMPAIR_BUST_MR2: /* --impair_bust_mr2 */
- msg.debugging |= LELEM(c-DBGOPT_RAW);
- continue;
+ case DBGOPT_NONE: /* --debug-none */
+ msg.debugging = DBG_NONE;
+ continue;
+
+ case DBGOPT_ALL: /* --debug-all */
+ msg.debugging |= DBG_ALL; /* note: does not include PRIVATE */
+ continue;
+
+ case DBGOPT_RAW: /* --debug-raw */
+ case DBGOPT_CRYPT: /* --debug-crypt */
+ case DBGOPT_PARSING: /* --debug-parsing */
+ case DBGOPT_EMITTING: /* --debug-emitting */
+ case DBGOPT_CONTROL: /* --debug-control */
+ case DBGOPT_LIFECYCLE: /* --debug-lifecycle */
+ case DBGOPT_KLIPS: /* --debug-klips */
+ case DBGOPT_DNS: /* --debug-dns */
+ case DBGOPT_NATT: /* --debug-natt */
+ case DBGOPT_OPPO: /* --debug-oppo */
+ case DBGOPT_CONTROLMORE: /* --debug-controlmore */
+ case DBGOPT_PRIVATE: /* --debug-private */
+ case DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER: /* --impair-delay-adns-key-answer */
+ case DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER: /* --impair-delay-adns-txt-answer */
+ case DBGOPT_IMPAIR_BUST_MI2: /* --impair_bust_mi2 */
+ case DBGOPT_IMPAIR_BUST_MR2: /* --impair_bust_mr2 */
+ msg.debugging |= LELEM(c-DBGOPT_RAW);
+ continue;
#endif
- default:
- assert(FALSE); /* unknown return value */
+ default:
+ assert(FALSE); /* unknown return value */
+ }
+ break;
}
- break;
- }
-
- if (optind != argc)
- {
- /* If you see this message unexpectedly, perhaps the
- * case for the previous option ended with "break"
- * instead of "continue"
- */
- diagq("unexpected argument", argv[optind]);
- }
-
- /* For each possible form of the command, figure out if an argument
- * suggests whether that form was intended, and if so, whether all
- * required information was supplied.
- */
-
- /* check opportunistic initiation simulation request */
- switch (opts_seen & (LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE)))
- {
- case LELEM(OPT_OPPO_HERE):
- case LELEM(OPT_OPPO_THERE):
- diag("--oppohere and --oppothere must be used together");
- /*NOTREACHED*/
- case LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE):
- msg.whack_oppo_initiate = TRUE;
- if (LIN(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST)))
- opts_seen &= ~LELEM(OPT_CD);
- break;
- }
-
- /* check connection description */
- if (LHAS(opts_seen, OPT_CD))
- {
- if (!LHAS(cd_seen, CD_TO-CD_FIRST))
- diag("connection description option, but no --to");
-
- if (!LHAS(end_seen, END_HOST-END_FIRST))
- diag("connection missing --host after --to");
-
- if (isanyaddr(&msg.left.host_addr)
- && isanyaddr(&msg.right.host_addr))
- diag("hosts cannot both be 0.0.0.0 or 0::0");
-
- if (msg.policy & POLICY_OPPO)
+
+ if (optind != argc)
{
- if ((msg.policy & (POLICY_PSK | POLICY_RSASIG)) != POLICY_RSASIG)
- diag("only RSASIG is supported for opportunism");
- if ((msg.policy & POLICY_PFS) == 0)
- diag("PFS required for opportunism");
- if ((msg.policy & POLICY_ENCRYPT) == 0)
- diag("encryption required for opportunism");
+ /* If you see this message unexpectedly, perhaps the
+ * case for the previous option ended with "break"
+ * instead of "continue"
+ */
+ diagq("unexpected argument", argv[optind]);
}
- check_end(&msg.left, &msg.right, !LHAS(end_seen_before_to, END_NEXTHOP-END_FIRST)
- , msg.addr_family, msg.tunnel_addr_family);
-
- check_end(&msg.right, &msg.left, !LHAS(end_seen, END_NEXTHOP-END_FIRST)
- , msg.addr_family, msg.tunnel_addr_family);
-
- if (subnettypeof(&msg.left.client) != subnettypeof(&msg.right.client))
- diag("endpoints clash: one is IPv4 and the other is IPv6");
+ /* For each possible form of the command, figure out if an argument
+ * suggests whether that form was intended, and if so, whether all
+ * required information was supplied.
+ */
- if (NEVER_NEGOTIATE(msg.policy))
+ /* check opportunistic initiation simulation request */
+ switch (opts_seen & (LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE)))
{
- /* we think this is just a shunt (because he didn't specify
- * a host authentication method). If he didn't specify a
- * shunt type, he's probably gotten it wrong.
- */
- if ((msg.policy & POLICY_SHUNT_MASK) == POLICY_SHUNT_TRAP)
- diag("non-shunt connection must have --psk or --rsasig or both");
+ case LELEM(OPT_OPPO_HERE):
+ case LELEM(OPT_OPPO_THERE):
+ diag("--oppohere and --oppothere must be used together");
+ /*NOTREACHED*/
+ case LELEM(OPT_OPPO_HERE) | LELEM(OPT_OPPO_THERE):
+ msg.whack_oppo_initiate = TRUE;
+ if (LIN(cd_seen, LELEM(CD_TUNNELIPV4 - CD_FIRST) | LELEM(CD_TUNNELIPV6 - CD_FIRST)))
+ opts_seen &= ~LELEM(OPT_CD);
+ break;
}
- else
+
+ /* check connection description */
+ if (LHAS(opts_seen, OPT_CD))
{
- /* not just a shunt: a real ipsec connection */
- if ((msg.policy & POLICY_ID_AUTH_MASK) == LEMPTY)
- diag("must specify --rsasig or --psk for a connection");
+ if (!LHAS(cd_seen, CD_TO-CD_FIRST))
+ diag("connection description option, but no --to");
+
+ if (!LHAS(end_seen, END_HOST-END_FIRST))
+ diag("connection missing --host after --to");
+
+ if (isanyaddr(&msg.left.host_addr)
+ && isanyaddr(&msg.right.host_addr))
+ diag("hosts cannot both be 0.0.0.0 or 0::0");
- if (!HAS_IPSEC_POLICY(msg.policy)
- && (msg.left.has_client || msg.right.has_client))
- diag("must not specify clients for ISAKMP-only connection");
+ if (msg.policy & POLICY_OPPO)
+ {
+ if ((msg.policy & (POLICY_PSK | POLICY_PUBKEY)) != POLICY_PUBKEY)
+ diag("only PUBKEY is supported for opportunism");
+ if ((msg.policy & POLICY_PFS) == 0)
+ diag("PFS required for opportunism");
+ if ((msg.policy & POLICY_ENCRYPT) == 0)
+ diag("encryption required for opportunism");
+ }
+
+ check_end(&msg.left, &msg.right, !LHAS(end_seen_before_to, END_NEXTHOP-END_FIRST)
+ , msg.addr_family, msg.tunnel_addr_family);
+
+ check_end(&msg.right, &msg.left, !LHAS(end_seen, END_NEXTHOP-END_FIRST)
+ , msg.addr_family, msg.tunnel_addr_family);
+
+ if (subnettypeof(&msg.left.client) != subnettypeof(&msg.right.client))
+ diag("endpoints clash: one is IPv4 and the other is IPv6");
+
+ if (NEVER_NEGOTIATE(msg.policy))
+ {
+ /* we think this is just a shunt (because he didn't specify
+ * a host authentication method). If he didn't specify a
+ * shunt type, he's probably gotten it wrong.
+ */
+ if ((msg.policy & POLICY_SHUNT_MASK) == POLICY_SHUNT_TRAP)
+ diag("non-shunt connection must have --psk or --rsasig or both");
+ }
+ else
+ {
+ /* not just a shunt: a real ipsec connection */
+ if ((msg.policy & POLICY_ID_AUTH_MASK) == LEMPTY)
+ diag("must specify --rsasig or --psk for a connection");
+
+ if (!HAS_IPSEC_POLICY(msg.policy)
+ && (msg.left.has_client || msg.right.has_client))
+ diag("must not specify clients for ISAKMP-only connection");
+ }
+
+ msg.whack_connection = TRUE;
}
- msg.whack_connection = TRUE;
- }
-
- /* decide whether --name is mandatory or forbidden */
- if (!LDISJOINT(opts_seen
- , LELEM(OPT_ROUTE) | LELEM(OPT_UNROUTE)
- | LELEM(OPT_INITIATE) | LELEM(OPT_TERMINATE)
- | LELEM(OPT_DELETE) | LELEM(OPT_CD)))
- {
- if (!LHAS(opts_seen, OPT_NAME) && !msg.whack_ca)
- diag("missing --name <connection_name>");
- }
- else if (!msg.whack_options && !msg.whack_status)
- {
- if (LHAS(opts_seen, OPT_NAME))
- diag("no reason for --name");
- }
-
- if (!LDISJOINT(opts_seen, LELEM(OPT_PUBKEYRSA) | LELEM(OPT_ADDKEY)))
- {
- if (!LHAS(opts_seen, OPT_KEYID))
- diag("--addkey and --pubkeyrsa require --keyid");
- }
-
- if (!(msg.whack_connection || msg.whack_key || msg.whack_myid
- || msg.whack_delete || msg.whack_deletestate
- || msg.whack_initiate || msg.whack_oppo_initiate || msg.whack_terminate
- || msg.whack_route || msg.whack_unroute || msg.whack_listen
- || msg.whack_unlisten || msg.whack_list || msg.whack_purgeocsp || msg.whack_reread
- || msg.whack_ca || msg.whack_status || msg.whack_options || msg.whack_shutdown
- || msg.whack_sc_op))
- {
- diag("no action specified; try --help for hints");
- }
-
- update_ports(&msg);
-
- /* tricky quick and dirty check for wild values */
- if (msg.sa_rekey_margin != 0
- && msg.sa_rekey_fuzz * msg.sa_rekey_margin * 4 / msg.sa_rekey_margin / 4
- != msg.sa_rekey_fuzz)
- diag("rekeymargin or rekeyfuzz values are so large that they cause oveflow");
-
- check_life_time (msg.sa_ike_life_seconds, OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM
- , "ikelifetime", &msg);
-
- check_life_time(msg.sa_ipsec_life_seconds, SA_LIFE_DURATION_MAXIMUM
- , "ipseclifetime", &msg);
-
- if (msg.dpd_action == DPD_ACTION_UNKNOWN)
- diag("dpdaction must be \"none\", \"clear\", \"hold\" or \"restart\"");
-
- if (msg.dpd_action != DPD_ACTION_NONE)
- {
- if (msg.dpd_delay <= 0)
- diag("dpddelay must be larger than zero");
-
- if (msg.dpd_timeout <= 0)
- diag("dpdtimeout must be larger than zero");
-
- if (msg.dpd_timeout <= msg.dpd_delay)
- diag("dpdtimeout must be larger than dpddelay");
- }
-
- /* pack strings for inclusion in message */
- next_str = msg.string;
- str_roof = &msg.string[sizeof(msg.string)];
-
- /* build esp message as esp="<esp>;<pfsgroup>" */
- if (msg.pfsgroup) {
- snprintf(esp_buf, sizeof (esp_buf), "%s;%s",
- msg.esp ? msg.esp : "",
- msg.pfsgroup ? msg.pfsgroup : "");
- msg.esp=esp_buf;
- }
- if (!pack_str(&msg.name) /* string 1 */
- || !pack_str(&msg.left.id) /* string 2 */
- || !pack_str(&msg.left.cert) /* string 3 */
- || !pack_str(&msg.left.ca) /* string 4 */
- || !pack_str(&msg.left.groups) /* string 5 */
- || !pack_str(&msg.left.updown) /* string 6 */
- || !pack_str(&msg.left.virt) /* string 7 */
- || !pack_str(&msg.right.id) /* string 8 */
- || !pack_str(&msg.right.cert) /* string 9 */
- || !pack_str(&msg.right.ca) /* string 10 */
- || !pack_str(&msg.right.groups) /* string 11 */
- || !pack_str(&msg.right.updown) /* string 12 */
- || !pack_str(&msg.right.virt) /* string 13 */
- || !pack_str(&msg.keyid) /* string 14 */
- || !pack_str(&msg.myid) /* string 15 */
- || !pack_str(&msg.cacert) /* string 16 */
- || !pack_str(&msg.ldaphost) /* string 17 */
- || !pack_str(&msg.ldapbase) /* string 18 */
- || !pack_str(&msg.crluri) /* string 19 */
- || !pack_str(&msg.crluri2) /* string 20 */
- || !pack_str(&msg.ocspuri) /* string 21 */
- || !pack_str(&msg.ike) /* string 22 */
- || !pack_str(&msg.esp) /* string 23 */
- || !pack_str(&msg.sc_data) /* string 24 */
- || str_roof - next_str < (ptrdiff_t)msg.keyval.len) /* chunk (sort of string 5) */
- diag("too many bytes of strings to fit in message to pluto");
-
- memcpy(next_str, msg.keyval.ptr, msg.keyval.len);
- msg.keyval.ptr = NULL;
- next_str += msg.keyval.len;
-
- msg.magic = ((opts_seen & ~LELEM(OPT_SHUTDOWN))
- | sc_seen | lst_seen | cd_seen | ca_seen) != LEMPTY
- || msg.whack_options
- ? WHACK_MAGIC : WHACK_BASIC_MAGIC;
-
- /* send message to Pluto */
- if (access(ctl_addr.sun_path, R_OK | W_OK) < 0)
- {
- int e = errno;
-
- switch (e)
+ /* decide whether --name is mandatory or forbidden */
+ if (!LDISJOINT(opts_seen
+ , LELEM(OPT_ROUTE) | LELEM(OPT_UNROUTE)
+ | LELEM(OPT_INITIATE) | LELEM(OPT_TERMINATE)
+ | LELEM(OPT_DELETE) | LELEM(OPT_CD)))
{
- case EACCES:
- fprintf(stderr, "whack: no right to communicate with pluto (access(\"%s\"))\n"
- , ctl_addr.sun_path);
- break;
- case ENOENT:
- fprintf(stderr, "whack: Pluto is not running (no \"%s\")\n"
- , ctl_addr.sun_path);
- break;
- default:
- fprintf(stderr, "whack: access(\"%s\") failed with %d %s\n"
- , ctl_addr.sun_path, errno, strerror(e));
- break;
+ if (!LHAS(opts_seen, OPT_NAME) && !msg.whack_ca)
+ diag("missing --name <connection_name>");
}
- exit(RC_WHACK_PROBLEM);
- }
- else
- {
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
- int exit_status = 0;
- ssize_t len = next_str - (char *)&msg;
-
- if (sock == -1)
+ else if (!msg.whack_options && !msg.whack_status)
{
- int e = errno;
-
- fprintf(stderr, "whack: socket() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
+ if (LHAS(opts_seen, OPT_NAME))
+ diag("no reason for --name");
}
- if (connect(sock, (struct sockaddr *)&ctl_addr
- , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
+ if (!LDISJOINT(opts_seen, LELEM(OPT_PUBKEYRSA) | LELEM(OPT_ADDKEY)))
{
- int e = errno;
-
- fprintf(stderr, "whack:%s connect() for \"%s\" failed (%d %s)\n"
- , e == ECONNREFUSED? " is Pluto running? " : ""
- , ctl_addr.sun_path, e, strerror(e));
- exit(RC_WHACK_PROBLEM);
+ if (!LHAS(opts_seen, OPT_KEYID))
+ diag("--addkey and --pubkeyrsa require --keyid");
}
- if (write(sock, &msg, len) != len)
+ if (!(msg.whack_connection || msg.whack_key || msg.whack_myid
+ || msg.whack_delete || msg.whack_deletestate
+ || msg.whack_initiate || msg.whack_oppo_initiate || msg.whack_terminate
+ || msg.whack_route || msg.whack_unroute || msg.whack_listen
+ || msg.whack_unlisten || msg.whack_list || msg.whack_purgeocsp || msg.whack_reread
+ || msg.whack_ca || msg.whack_status || msg.whack_options || msg.whack_shutdown
+ || msg.whack_sc_op))
{
- int e = errno;
+ diag("no action specified; try --help for hints");
+ }
+
+ update_ports(&msg);
+
+ /* tricky quick and dirty check for wild values */
+ if (msg.sa_rekey_margin != 0
+ && msg.sa_rekey_fuzz * msg.sa_rekey_margin * 4 / msg.sa_rekey_margin / 4
+ != msg.sa_rekey_fuzz)
+ diag("rekeymargin or rekeyfuzz values are so large that they cause oveflow");
+
+ check_life_time (msg.sa_ike_life_seconds, OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM
+ , "ikelifetime", &msg);
- fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
+ check_life_time(msg.sa_ipsec_life_seconds, SA_LIFE_DURATION_MAXIMUM
+ , "ipseclifetime", &msg);
+
+ if (msg.dpd_action == DPD_ACTION_UNKNOWN)
+ diag("dpdaction must be \"none\", \"clear\", \"hold\" or \"restart\"");
+
+ if (msg.dpd_action != DPD_ACTION_NONE)
+ {
+ if (msg.dpd_delay <= 0)
+ diag("dpddelay must be larger than zero");
+
+ if (msg.dpd_timeout <= 0)
+ diag("dpdtimeout must be larger than zero");
+
+ if (msg.dpd_timeout <= msg.dpd_delay)
+ diag("dpdtimeout must be larger than dpddelay");
}
- /* for now, just copy reply back to stdout */
+ /* pack strings for inclusion in message */
+ next_str = msg.string;
+ str_roof = &msg.string[sizeof(msg.string)];
+ /* build esp message as esp="<esp>;<pfsgroup>" */
+ if (msg.pfsgroup) {
+ snprintf(esp_buf, sizeof (esp_buf), "%s;%s",
+ msg.esp ? msg.esp : "",
+ msg.pfsgroup ? msg.pfsgroup : "");
+ msg.esp=esp_buf;
+ }
+ if (!pack_str(&msg.name) /* string 1 */
+ || !pack_str(&msg.left.id) /* string 2 */
+ || !pack_str(&msg.left.cert) /* string 3 */
+ || !pack_str(&msg.left.ca) /* string 4 */
+ || !pack_str(&msg.left.groups) /* string 5 */
+ || !pack_str(&msg.left.updown) /* string 6 */
+ || !pack_str(&msg.left.virt) /* string 7 */
+ || !pack_str(&msg.right.id) /* string 8 */
+ || !pack_str(&msg.right.cert) /* string 9 */
+ || !pack_str(&msg.right.ca) /* string 10 */
+ || !pack_str(&msg.right.groups) /* string 11 */
+ || !pack_str(&msg.right.updown) /* string 12 */
+ || !pack_str(&msg.right.virt) /* string 13 */
+ || !pack_str(&msg.keyid) /* string 14 */
+ || !pack_str(&msg.myid) /* string 15 */
+ || !pack_str(&msg.cacert) /* string 16 */
+ || !pack_str(&msg.ldaphost) /* string 17 */
+ || !pack_str(&msg.ldapbase) /* string 18 */
+ || !pack_str(&msg.crluri) /* string 19 */
+ || !pack_str(&msg.crluri2) /* string 20 */
+ || !pack_str(&msg.ocspuri) /* string 21 */
+ || !pack_str(&msg.ike) /* string 22 */
+ || !pack_str(&msg.esp) /* string 23 */
+ || !pack_str(&msg.sc_data) /* string 24 */
+ || str_roof - next_str < (ptrdiff_t)msg.keyval.len) /* chunk (sort of string 5) */
+ diag("too many bytes of strings to fit in message to pluto");
+
+ memcpy(next_str, msg.keyval.ptr, msg.keyval.len);
+ msg.keyval.ptr = NULL;
+ next_str += msg.keyval.len;
+
+ msg.magic = ((opts_seen & ~LELEM(OPT_SHUTDOWN))
+ | sc_seen | lst_seen | cd_seen | ca_seen) != LEMPTY
+ || msg.whack_options
+ ? WHACK_MAGIC : WHACK_BASIC_MAGIC;
+
+ /* send message to Pluto */
+ if (access(ctl_addr.sun_path, R_OK | W_OK) < 0)
{
- char buf[4097]; /* arbitrary limit on log line length */
- char *be = buf;
+ int e = errno;
- for (;;)
- {
- char *ls = buf;
- ssize_t rl = read(sock, be, (buf + sizeof(buf)-1) - be);
+ switch (e)
+ {
+ case EACCES:
+ fprintf(stderr, "whack: no right to communicate with pluto (access(\"%s\"))\n"
+ , ctl_addr.sun_path);
+ break;
+ case ENOENT:
+ fprintf(stderr, "whack: Pluto is not running (no \"%s\")\n"
+ , ctl_addr.sun_path);
+ break;
+ default:
+ fprintf(stderr, "whack: access(\"%s\") failed with %d %s\n"
+ , ctl_addr.sun_path, errno, strerror(e));
+ break;
+ }
+ whack_exit(RC_WHACK_PROBLEM);
+ }
+ else
+ {
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ int exit_status = 0;
+ ssize_t len = next_str - (char *)&msg;
- if (rl < 0)
+ if (sock == -1)
{
- int e = errno;
+ int e = errno;
- fprintf(stderr, "whack: read() failed (%d %s)\n", e, strerror(e));
- exit(RC_WHACK_PROBLEM);
+ fprintf(stderr, "whack: socket() failed (%d %s)\n", e, strerror(e));
+ whack_exit(RC_WHACK_PROBLEM);
}
- if (rl == 0)
+
+ if (connect(sock, (struct sockaddr *)&ctl_addr
+ , offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
{
- if (be != buf)
- fprintf(stderr, "whack: last line from pluto too long or unterminated\n");
- break;
- }
+ int e = errno;
- be += rl;
- *be = '\0';
+ fprintf(stderr, "whack:%s connect() for \"%s\" failed (%d %s)\n"
+ , e == ECONNREFUSED? " is Pluto running? " : ""
+ , ctl_addr.sun_path, e, strerror(e));
+ whack_exit(RC_WHACK_PROBLEM);
+ }
- for (;;)
+ if (write(sock, &msg, len) != len)
{
- char *le = strchr(ls, '\n');
+ int e = errno;
- if (le == NULL)
- {
- /* move last, partial line to start of buffer */
- memmove(buf, ls, be-ls);
- be -= ls - buf;
- break;
- }
+ fprintf(stderr, "whack: write() failed (%d %s)\n", e, strerror(e));
+ whack_exit(RC_WHACK_PROBLEM);
+ }
- le++; /* include NL in line */
- ignore_result(write(1, ls, le - ls));
+ /* for now, just copy reply back to stdout */
- /* figure out prefix number
- * and how it should affect our exit status
- */
- {
- unsigned long s = strtoul(ls, NULL, 10);
+ {
+ char buf[4097]; /* arbitrary limit on log line length */
+ char *be = buf;
- switch (s)
+ for (;;)
{
- case RC_COMMENT:
- case RC_LOG:
- /* ignore */
- break;
- case RC_SUCCESS:
- /* be happy */
- exit_status = 0;
- break;
- case RC_ENTERSECRET:
- get_secret(sock);
- break;
- /* case RC_LOG_SERIOUS: */
- default:
- /* pass through */
- exit_status = s;
- break;
+ char *ls = buf;
+ ssize_t rl = read(sock, be, (buf + sizeof(buf)-1) - be);
+
+ if (rl < 0)
+ {
+ int e = errno;
+
+ fprintf(stderr, "whack: read() failed (%d %s)\n", e, strerror(e));
+ whack_exit(RC_WHACK_PROBLEM);
+ }
+ if (rl == 0)
+ {
+ if (be != buf)
+ fprintf(stderr, "whack: last line from pluto too long or unterminated\n");
+ break;
+ }
+
+ be += rl;
+ *be = '\0';
+
+ for (;;)
+ {
+ char *le = strchr(ls, '\n');
+
+ if (le == NULL)
+ {
+ /* move last, partial line to start of buffer */
+ memmove(buf, ls, be-ls);
+ be -= ls - buf;
+ break;
+ }
+
+ le++; /* include NL in line */
+ ignore_result(write(1, ls, le - ls));
+
+ /* figure out prefix number
+ * and how it should affect our exit status
+ */
+ {
+ unsigned long s = strtoul(ls, NULL, 10);
+
+ switch (s)
+ {
+ case RC_COMMENT:
+ case RC_LOG:
+ /* ignore */
+ break;
+ case RC_SUCCESS:
+ /* be happy */
+ exit_status = 0;
+ break;
+ case RC_ENTERSECRET:
+ get_secret(sock);
+ break;
+ /* case RC_LOG_SERIOUS: */
+ default:
+ /* pass through */
+ exit_status = s;
+ break;
+ }
+ }
+ ls = le;
+ }
}
- }
- ls = le;
}
- }
+ whack_exit(exit_status);
}
- return exit_status;
- }
+ return -1; /* should never be reached */
}
diff --git a/src/whack/whack.h b/src/whack/whack.h
index 8e0e7c3af..79d115262 100644
--- a/src/whack/whack.h
+++ b/src/whack/whack.h
@@ -10,8 +10,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * RCSID $Id: whack.h 4709 2008-11-27 10:20:25Z martin $
*/
#ifndef _WHACK_H
@@ -23,10 +21,10 @@
#ifndef SC_OP_T
#define SC_OP_T
typedef enum {
- SC_OP_NONE = 0,
- SC_OP_ENCRYPT = 1,
- SC_OP_DECRYPT = 2,
- SC_OP_SIGN = 3,
+ SC_OP_NONE = 0,
+ SC_OP_ENCRYPT = 1,
+ SC_OP_DECRYPT = 2,
+ SC_OP_SIGN = 3,
} sc_op_t;
#endif /* SC_OP_T */
@@ -56,187 +54,187 @@ typedef struct whack_end whack_end_t;
* and because whack is a separate program from pluto.
*/
struct whack_end {
- char *id; /* id string (if any) -- decoded by pluto */
- char *cert; /* path string (if any) -- loaded by pluto */
- char *ca; /* distinguished name string (if any) -- parsed by pluto */
- char *groups; /* access control groups (if any) -- parsed by pluto */
- ip_address
- host_addr,
- host_nexthop,
- host_srcip;
- ip_subnet client;
-
- bool key_from_DNS_on_demand;
- bool has_client;
- bool has_client_wildcard;
- bool has_port_wildcard;
- bool has_srcip;
- bool has_natip;
- bool modecfg;
- bool hostaccess;
- bool allow_any;
- certpolicy_t sendcert;
- char *updown; /* string */
- u_int16_t host_port; /* host order */
- u_int16_t port; /* host order */
- u_int8_t protocol;
- char *virt;
+ char *id; /* id string (if any) -- decoded by pluto */
+ char *cert; /* path string (if any) -- loaded by pluto */
+ char *ca; /* distinguished name string (if any) -- parsed by pluto */
+ char *groups; /* access control groups (if any) -- parsed by pluto */
+ ip_address
+ host_addr,
+ host_nexthop,
+ host_srcip;
+ ip_subnet client;
+
+ bool key_from_DNS_on_demand;
+ bool has_client;
+ bool has_client_wildcard;
+ bool has_port_wildcard;
+ bool has_srcip;
+ bool has_natip;
+ bool modecfg;
+ bool hostaccess;
+ bool allow_any;
+ certpolicy_t sendcert;
+ char *updown; /* string */
+ u_int16_t host_port; /* host order */
+ u_int16_t port; /* host order */
+ u_int8_t protocol;
+ char *virt;
};
typedef struct whack_message whack_message_t;
struct whack_message {
- unsigned int magic;
+ unsigned int magic;
- /* for WHACK_STATUS: */
- bool whack_status;
- bool whack_statusall;
+ /* for WHACK_STATUS: */
+ bool whack_status;
+ bool whack_statusall;
- /* for WHACK_SHUTDOWN */
- bool whack_shutdown;
+ /* for WHACK_SHUTDOWN */
+ bool whack_shutdown;
- /* END OF BASIC COMMANDS
- * If you change anything earlier in this struct, update WHACK_BASIC_MAGIC.
- */
+ /* END OF BASIC COMMANDS
+ * If you change anything earlier in this struct, update WHACK_BASIC_MAGIC.
+ */
- /* name is used in connection, ca and initiate */
- size_t name_len; /* string 1 */
- char *name;
+ /* name is used in connection, ca and initiate */
+ size_t name_len; /* string 1 */
+ char *name;
- /* for WHACK_OPTIONS: */
+ /* for WHACK_OPTIONS: */
- bool whack_options;
+ bool whack_options;
- lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
+ lset_t debugging; /* only used #ifdef DEBUG, but don't want layout to change */
- /* for WHACK_CONNECTION */
+ /* for WHACK_CONNECTION */
- bool whack_connection;
- bool whack_async;
- bool ikev1;
+ bool whack_connection;
+ bool whack_async;
+ bool ikev1;
- lset_t policy;
- time_t sa_ike_life_seconds;
- time_t sa_ipsec_life_seconds;
- time_t sa_rekey_margin;
- unsigned long sa_rekey_fuzz;
- unsigned long sa_keying_tries;
-
- /* For DPD 3706 - Dead Peer Detection */
- time_t dpd_delay;
- time_t dpd_timeout;
- dpd_action_t dpd_action;
-
- /* note that each end contains string 2/5.id, string 3/6 cert,
- * and string 4/7 updown
- */
- whack_end_t left;
- whack_end_t right;
-
- /* note: if the client is the gateway, the following must be equal */
- sa_family_t addr_family; /* between gateways */
- sa_family_t tunnel_addr_family; /* between clients */
-
- char *ike; /* ike algo string (separated by commas) */
- char *pfsgroup; /* pfsgroup will be "encapsulated" in esp string for pluto */
- char *esp; /* esp algo string (separated by commas) */
-
- /* for WHACK_KEY: */
- bool whack_key;
- bool whack_addkey;
- char *keyid; /* string 8 */
- enum pubkey_alg pubkey_alg;
- chunk_t keyval; /* chunk */
-
- /* for WHACK_MYID: */
- bool whack_myid;
- char *myid; /* string 7 */
-
- /* for WHACK_ROUTE: */
- bool whack_route;
-
- /* for WHACK_UNROUTE: */
- bool whack_unroute;
-
- /* for WHACK_INITIATE: */
- bool whack_initiate;
-
- /* for WHACK_OPINITIATE */
- bool whack_oppo_initiate;
- ip_address oppo_my_client, oppo_peer_client;
-
- /* for WHACK_TERMINATE: */
- bool whack_terminate;
-
- /* for WHACK_DELETE: */
- bool whack_delete;
-
- /* for WHACK_DELETESTATE: */
- bool whack_deletestate;
- so_serial_t whack_deletestateno;
-
- /* for WHACK_LISTEN: */
- bool whack_listen, whack_unlisten;
-
- /* for WHACK_CRASH - note if a remote peer is known to have rebooted */
- bool whack_crash;
- ip_address whack_crash_peer;
-
- /* for WHACK_LIST */
- bool whack_utc;
- lset_t whack_list;
-
- /* for WHACK_PURGEOCSP */
- bool whack_purgeocsp;
-
- /* for WHACK_REREAD */
- u_char whack_reread;
-
- /* for WHACK_CA */
- bool whack_ca;
- bool whack_strict;
-
- char *cacert;
- char *ldaphost;
- char *ldapbase;
- char *crluri;
- char *crluri2;
- char *ocspuri;
-
- /* for WHACK_SC_OP */
- sc_op_t whack_sc_op;
- int inbase, outbase;
- char *sc_data;
-
- /* space for strings (hope there is enough room):
- * Note that pointers don't travel on wire.
- * 1 connection name [name_len]
- * 2 left's name [left.host.name.len]
- * 3 left's cert
- * 4 left's ca
- * 5 left's groups
- * 6 left's updown
- * 7 right's name [left.host.name.len]
- * 8 right's cert
- * 9 right's ca
- * 10 right's groups
- * 11 right's updown
- * 12 keyid
- * 13 myid
- * 14 cacert
- * 15 ldaphost
- * 16 ldapbase
- * 17 crluri
- * 18 crluri2
- * 19 ocspuri
- * 20 ike
- " 21 esp
- * 22 rsa_data
- * plus keyval (limit: 8K bits + overhead), a chunk.
- */
- size_t str_size;
- char string[2048];
+ lset_t policy;
+ time_t sa_ike_life_seconds;
+ time_t sa_ipsec_life_seconds;
+ time_t sa_rekey_margin;
+ unsigned long sa_rekey_fuzz;
+ unsigned long sa_keying_tries;
+
+ /* For DPD 3706 - Dead Peer Detection */
+ time_t dpd_delay;
+ time_t dpd_timeout;
+ dpd_action_t dpd_action;
+
+ /* note that each end contains string 2/5.id, string 3/6 cert,
+ * and string 4/7 updown
+ */
+ whack_end_t left;
+ whack_end_t right;
+
+ /* note: if the client is the gateway, the following must be equal */
+ sa_family_t addr_family; /* between gateways */
+ sa_family_t tunnel_addr_family; /* between clients */
+
+ char *ike; /* ike algo string (separated by commas) */
+ char *pfsgroup; /* pfsgroup will be "encapsulated" in esp string for pluto */
+ char *esp; /* esp algo string (separated by commas) */
+
+ /* for WHACK_KEY: */
+ bool whack_key;
+ bool whack_addkey;
+ char *keyid; /* string 8 */
+ enum pubkey_alg pubkey_alg;
+ chunk_t keyval; /* chunk */
+
+ /* for WHACK_MYID: */
+ bool whack_myid;
+ char *myid; /* string 7 */
+
+ /* for WHACK_ROUTE: */
+ bool whack_route;
+
+ /* for WHACK_UNROUTE: */
+ bool whack_unroute;
+
+ /* for WHACK_INITIATE: */
+ bool whack_initiate;
+
+ /* for WHACK_OPINITIATE */
+ bool whack_oppo_initiate;
+ ip_address oppo_my_client, oppo_peer_client;
+
+ /* for WHACK_TERMINATE: */
+ bool whack_terminate;
+
+ /* for WHACK_DELETE: */
+ bool whack_delete;
+
+ /* for WHACK_DELETESTATE: */
+ bool whack_deletestate;
+ so_serial_t whack_deletestateno;
+
+ /* for WHACK_LISTEN: */
+ bool whack_listen, whack_unlisten;
+
+ /* for WHACK_CRASH - note if a remote peer is known to have rebooted */
+ bool whack_crash;
+ ip_address whack_crash_peer;
+
+ /* for WHACK_LIST */
+ bool whack_utc;
+ lset_t whack_list;
+
+ /* for WHACK_PURGEOCSP */
+ bool whack_purgeocsp;
+
+ /* for WHACK_REREAD */
+ u_char whack_reread;
+
+ /* for WHACK_CA */
+ bool whack_ca;
+ bool whack_strict;
+
+ char *cacert;
+ char *ldaphost;
+ char *ldapbase;
+ char *crluri;
+ char *crluri2;
+ char *ocspuri;
+
+ /* for WHACK_SC_OP */
+ sc_op_t whack_sc_op;
+ int inbase, outbase;
+ char *sc_data;
+
+ /* space for strings (hope there is enough room):
+ * Note that pointers don't travel on wire.
+ * 1 connection name [name_len]
+ * 2 left's name [left.host.name.len]
+ * 3 left's cert
+ * 4 left's ca
+ * 5 left's groups
+ * 6 left's updown
+ * 7 right's name [left.host.name.len]
+ * 8 right's cert
+ * 9 right's ca
+ * 10 right's groups
+ * 11 right's updown
+ * 12 keyid
+ * 13 myid
+ * 14 cacert
+ * 15 ldaphost
+ * 16 ldapbase
+ * 17 crluri
+ * 18 crluri2
+ * 19 ocspuri
+ * 20 ike
+ " 21 esp
+ * 22 rsa_data
+ * plus keyval (limit: 8K bits + overhead), a chunk.
+ */
+ size_t str_size;
+ char string[2048];
};
/* Codes for status messages returned to whack.
@@ -247,82 +245,82 @@ struct whack_message {
* NOTE: ipsec_auto(8) knows about some of these numbers -- change carefully.
*/
enum rc_type {
- RC_COMMENT, /* non-commital utterance (does not affect exit status) */
- RC_WHACK_PROBLEM, /* whack-detected problem */
- RC_LOG, /* message aimed at log (does not affect exit status) */
- RC_LOG_SERIOUS, /* serious message aimed at log (does not affect exit status) */
- RC_SUCCESS, /* success (exit status 0) */
-
- /* failure, but not definitive */
-
- RC_RETRANSMISSION = 10,
-
- /* improper request */
-
- RC_DUPNAME = 20, /* attempt to reuse a connection name */
- RC_UNKNOWN_NAME, /* connection name unknown or state number */
- RC_ORIENT, /* cannot orient connection: neither end is us */
- RC_CLASH, /* clash between two Road Warrior connections OVERLOADED */
- RC_DEAF, /* need --listen before --initiate */
- RC_ROUTE, /* cannot route */
- RC_RTBUSY, /* cannot unroute: route busy */
- RC_BADID, /* malformed --id */
- RC_NOKEY, /* no key found through DNS */
- RC_NOPEERIP, /* cannot initiate when peer IP is unknown */
- RC_INITSHUNT, /* cannot initiate a shunt-oly connection */
- RC_WILDCARD, /* cannot initiate when ID has wildcards */
- RC_NOVALIDPIN, /* cannot initiate without valid PIN */
-
- /* permanent failure */
-
- RC_BADWHACKMESSAGE = 30,
- RC_NORETRANSMISSION,
- RC_INTERNALERR,
- RC_OPPOFAILURE, /* Opportunism failed */
-
- /* entry of secrets */
- RC_ENTERSECRET = 40,
-
- /* progress: start of range for successful state transition.
- * Actual value is RC_NEW_STATE plus the new state code.
- */
- RC_NEW_STATE = 100,
-
- /* start of range for notification.
- * Actual value is RC_NOTIFICATION plus code for notification
- * that should be generated by this Pluto.
- */
- RC_NOTIFICATION = 200 /* as per IKE notification messages */
+ RC_COMMENT, /* non-commital utterance (does not affect exit status) */
+ RC_WHACK_PROBLEM, /* whack-detected problem */
+ RC_LOG, /* message aimed at log (does not affect exit status) */
+ RC_LOG_SERIOUS, /* serious message aimed at log (does not affect exit status) */
+ RC_SUCCESS, /* success (exit status 0) */
+
+ /* failure, but not definitive */
+
+ RC_RETRANSMISSION = 10,
+
+ /* improper request */
+
+ RC_DUPNAME = 20, /* attempt to reuse a connection name */
+ RC_UNKNOWN_NAME, /* connection name unknown or state number */
+ RC_ORIENT, /* cannot orient connection: neither end is us */
+ RC_CLASH, /* clash between two Road Warrior connections OVERLOADED */
+ RC_DEAF, /* need --listen before --initiate */
+ RC_ROUTE, /* cannot route */
+ RC_RTBUSY, /* cannot unroute: route busy */
+ RC_BADID, /* malformed --id */
+ RC_NOKEY, /* no key found through DNS */
+ RC_NOPEERIP, /* cannot initiate when peer IP is unknown */
+ RC_INITSHUNT, /* cannot initiate a shunt-oly connection */
+ RC_WILDCARD, /* cannot initiate when ID has wildcards */
+ RC_NOVALIDPIN, /* cannot initiate without valid PIN */
+
+ /* permanent failure */
+
+ RC_BADWHACKMESSAGE = 30,
+ RC_NORETRANSMISSION,
+ RC_INTERNALERR,
+ RC_OPPOFAILURE, /* Opportunism failed */
+
+ /* entry of secrets */
+ RC_ENTERSECRET = 40,
+
+ /* progress: start of range for successful state transition.
+ * Actual value is RC_NEW_STATE plus the new state code.
+ */
+ RC_NEW_STATE = 100,
+
+ /* start of range for notification.
+ * Actual value is RC_NOTIFICATION plus code for notification
+ * that should be generated by this Pluto.
+ */
+ RC_NOTIFICATION = 200 /* as per IKE notification messages */
};
/* options of whack --list*** command */
-#define LIST_NONE 0x0000 /* don't list anything */
-#define LIST_ALGS 0x0001 /* list all registered IKE algorithms */
-#define LIST_PUBKEYS 0x0002 /* list all public keys */
-#define LIST_CERTS 0x0004 /* list all host/user certs */
-#define LIST_CACERTS 0x0008 /* list all ca certs */
-#define LIST_ACERTS 0x0010 /* list all attribute certs */
-#define LIST_AACERTS 0x0020 /* list all aa certs */
-#define LIST_OCSPCERTS 0x0040 /* list all ocsp certs */
-#define LIST_GROUPS 0x0080 /* list all access control groups */
-#define LIST_CAINFOS 0x0100 /* list all ca information records */
-#define LIST_CRLS 0x0200 /* list all crls */
-#define LIST_OCSP 0x0400 /* list all ocsp cache entries */
-#define LIST_CARDS 0x0800 /* list all smartcard records */
-
-#define LIST_ALL LRANGES(LIST_ALGS, LIST_CARDS) /* all list options */
+#define LIST_NONE 0x0000 /* don't list anything */
+#define LIST_ALGS 0x0001 /* list all registered IKE algorithms */
+#define LIST_PUBKEYS 0x0002 /* list all public keys */
+#define LIST_CERTS 0x0004 /* list all host/user certs */
+#define LIST_CACERTS 0x0008 /* list all ca certs */
+#define LIST_ACERTS 0x0010 /* list all attribute certs */
+#define LIST_AACERTS 0x0020 /* list all aa certs */
+#define LIST_OCSPCERTS 0x0040 /* list all ocsp certs */
+#define LIST_GROUPS 0x0080 /* list all access control groups */
+#define LIST_CAINFOS 0x0100 /* list all ca information records */
+#define LIST_CRLS 0x0200 /* list all crls */
+#define LIST_OCSP 0x0400 /* list all ocsp cache entries */
+#define LIST_CARDS 0x0800 /* list all smartcard records */
+
+#define LIST_ALL LRANGES(LIST_ALGS, LIST_CARDS) /* all list options */
/* options of whack --reread*** command */
-#define REREAD_NONE 0x00 /* don't reread anything */
-#define REREAD_SECRETS 0x01 /* reread /etc/ipsec.secrets */
-#define REREAD_CACERTS 0x02 /* reread certs in /etc/ipsec.d/cacerts */
-#define REREAD_AACERTS 0x04 /* reread certs in /etc/ipsec.d/aacerts */
-#define REREAD_OCSPCERTS 0x08 /* reread certs in /etc/ipsec.d/ocspcerts */
-#define REREAD_ACERTS 0x10 /* reread certs in /etc/ipsec.d/acerts */
-#define REREAD_CRLS 0x20 /* reread crls in /etc/ipsec.d/crls */
+#define REREAD_NONE 0x00 /* don't reread anything */
+#define REREAD_SECRETS 0x01 /* reread /etc/ipsec.secrets */
+#define REREAD_CACERTS 0x02 /* reread certs in /etc/ipsec.d/cacerts */
+#define REREAD_AACERTS 0x04 /* reread certs in /etc/ipsec.d/aacerts */
+#define REREAD_OCSPCERTS 0x08 /* reread certs in /etc/ipsec.d/ocspcerts */
+#define REREAD_ACERTS 0x10 /* reread certs in /etc/ipsec.d/acerts */
+#define REREAD_CRLS 0x20 /* reread crls in /etc/ipsec.d/crls */
-#define REREAD_ALL LRANGES(REREAD_SECRETS, REREAD_CRLS) /* all reread options */
+#define REREAD_ALL LRANGES(REREAD_SECRETS, REREAD_CRLS) /* all reread options */
#endif /* _WHACK_H */